Bentornati alla nostra città in costruzione. Abbiamo buttato giù la pianta e ora è il momento di tirare su degli edifici.
Hai perso la prima parte? O sei già pronto per la terza e ultima?
Edifici
La tecnica da usare per creare gli edifici è la stessa usata per la piattaforma. Avremo un div che erediterà la trasformazione 3d della base, e la coppia :after/:before per mostrare i lati visibili dell’edificio.
Cominciamo dall’html, dove apporteremo solo una piccola modifica aggiungendo un div con classe “building”:
[cce lang=”html”]
<body>
<div id=”base_platform”>
<div class=”building”></div>
</div>
</body>
[/cce]
Passiamo al css, definendo in primis tre nuove variabili che conterranno la misura del lato di un edificio, la sua profondità e la sua “altezza” intesa come spostamento sull’asse Z.
[cc lang=”css”]
$building_side: 100px;
$building_depth: 100px;
$building_heigth: 100px;
e forniamo lo stile base della classe .building:
$platform_side: 480px;
$panel_heigth: 50px;
$building_side: 100px;
$building_depth: 100px;
$building_heigth: 100px;
…
.building {
width: $building_side;
height: $building_depth;
}
[/cc]
A questo punto, dopo la compilazione del foglio di stile, tornando al browser, una faccia della piattaforma dovrebbe essersi spostata in maniera non corretta. Questo accade perché tutti gli oggetti figli di #base_platform devo essere posizionati in maniera assoluta, separati dal flow di rendering in modo da non alterare la posizione di :after e :before.
Per ovviare a questo problema e garantire un posizionamento comodo dei palazzi, dobbiamo creare una sovrastruttura in cui inserirli. Immaginiamola come un isolato che può essere riempito di edifici.
Dentro l’html:
[cce lang=”html”]
<body>
<div id=”base_platform”>
<div class=”block”>
<div class=”building”></div>
</div>
</div>
</body>
[/cce]
Lo stile css di block è molto semplice:
[cc lang=”css”]
.block {
position: absolute;
top: 0;
left: 0;
}
aggiungiamo a .building il posizionamento relativo e un background provvisorio per capire dove stiamo posizionando il nostro elemento:
.building {
width: $building_side;
height: $building_depth;
position: relative;
background-color: #d2d2d2;
}
[/cc]
A questo punto abbiamo una struttura contenitore, il div.block, spostabile a piacimento lungo la superficie della piattaforma, che al suo interno contiene uno o più elementi div.building.
Trasliamo sull’asse Z (quindi verso l’alto o verso il basso nel nostro piano tridimensionale) l’elemento .building e aggiungiamo l’opzione per preservare la prospettiva 3d dei figli; inoltre, diamo outline di 1px per compensare il lieve distacco tra le facce dei parallelepipedi, box-shadow per dare più corpo alle linee, float a sinistra e un margine di 5px per distanziare i palazzi.
[cc lang=”css”]
.building {
width: $building_side;
height: $building_depth;
position: relative;
background-color: #d2d2d2;
transform: translateZ($building_heigth);
transform-style: preserve-3d;
outline: 1px solid #b5b5b5;
float: left;
margin: 10px;
}
[/cc]
Dobbiamo creare e posizionare le facce visibili dell’edificio, esattamente come abbiamo fatto per la piattaforma:
[cc lang=”css”]
.building {
width: $building_side;
height: $building_depth;
position: relative;
background-color: white;
transform: translateZ($building_height);
transform-style: preserve-3d;
outline: 1px solid #b5b5b5;
box-shadow: inset 0 0 0 2px #b5b5b5;
float: left;
margin: 5px;
transition: all 0.5s;
&:before, &:after {
position: absolute;
background-color: inherit;
content: “”;
outline: 1px solid #b5b5b5;
box-shadow: inset 0 0 0 2px #b5b5b5;
}
&:after {
height: $building_depth;
width: $building_heigth;
transform: rotateY(90deg) translateX(0px) translateY(0px) translateZ($building_side);
transform-origin: left;
}
&:before {
height: $building_heigth;
width: $building_side;
transform: rotateX(90deg) translateX(0) translateY(-$building_heigth) translateZ(-$building_depth);
transform-origin: top;
}
}
[/cc]
L’utilizzo di sass e delle variabili ci permette di cambiare questi valori per personalizzare il nostro edificio. A questo punto, prospettando di avere edifici differenti per evitare una certa monotonia nel paesaggio, conviene spostare lo styling in un mixin e usare quest’ultimo per generare tutte le configurazioni che vogliamo.
Trasformiamo .building in un mixin:
[cc lang=”css”]
@mixin building($building_side, $building_depth, $building_heigth) {
width: $building_side;
height: $building_side;
poi ricreiamo il selettore usando il mixin per riempirlo:
.building {
@include building(50px, 50px);
}
[/cc]
Possiamo eliminare le variabili $building_side, $building_depth e $building_heigth in cima al nostro file in quanto adesso possiamo generare ogni genere di palazzo passando nel mixin i parametri relativi a lunghezza del lato e altezza dell’edificio. Il nostro edificio di default sarà un cubo di 50px.
Aggiungiamo due varianti, legandole a classi specifiche da aggiungere agli elementi .building che andremo a creare per popolare la città:
[cc lang=”css”]
.tall {
@include building(50px, 50px, 200px);
}
.medium {
@include building(50px, 50px, 100px);
}
.large {
@include building(110px, 50px, 200px);
}
[/cc]
A questo punto, aggiungendo la classe .tall ad un elemento con classe .building, dovremmo ottenere un piccolo grattacielo:
[cce lang=”html”]
<body>
<div id=”base_platform”>
<div class=”block”>
<div class=”building tall”></div>
<div class=”building medium”></div>
<div class=”building large”></div>
</div>
</div>
</body>
[/cce]
Per combattere la monotonia di un paesaggio completamente bianco, definiamo una piccola palette di colori nel foglio di stile.
[cc lang=”css”]
$colors: bisque, darkseagreen, dodgerblue, burlywood, palegoldenrod, palegreen, paleturquoise, palevioletred;
@mixin generateColors {
@each $color in $colors {
.#{$color} {
background-color: $color !important;
&:before, &:after {
background-color: $color !important;
}
}
}
}
@include generateColors;
[/cc]
Questo mixin serve a generare dei selettori ciclando il contenuto della variabile $colors, in modo da sovrascrivere e forzare il valore di background-color per gli elementi cui viene appesa la classe, e per i loro :before e :after.
I colori scelti vengono dalla palette standard Html (https://www.w3schools.com/colors/colors_names.asp).
Adesso possiamo colorare i nostri edifici appendendo la classe relativa al colore scelto:
[cce lang=”html”]
<body>
<div id=”base_platform”>
<div class=”block”>
<div class=”building tall bisque”></div>
<div class=”building medium palegoldenrod”></div>
<div class=”building palegreen”></div>
</div>
</div>
</body>
[/cce]