CSS Posizionamento degli elementi

Transcript

CSS Posizionamento degli elementi
Laboratorio di Tecnologie Web
CSS
Posizionamento degli
elementi
Dott. Stefano Burigat
www.dimi.uniud.it/burigat
Tutti gli esempi che abbiamo visto finora sfruttavano regole
di posizionamento standard (il cosiddetto flusso normale
degli elementi). Ad esempio, elementi di tipo blocco
vengono visualizzati uno di seguito all'altro verticalmente
mentre elementi di tipo inline vengono posizionati
all'interno del flusso del testo. CSS consente di controllare
direttamente il posizionamento degli elementi tramite i
metodi di floating e positioning.
Floating
Il floating si basa sull'utilizzo della proprietà “float” che
permette di muovere un elemento all'estrema destra (valore
right) o all'estrema sinistra (valore left) dell'area di
contenuto dell'elemento padre. Il contenuto che segue
l'elemento floating all'interno dello stesso padre si disporrà
attorno all'elemento floating, nello spazio disponibile.
Questa proprietà si applica a tutti gli elementi e non viene
ereditata.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
img {
float: left;
margin: 10px;
border: 1px solid;
}
p {
padding: 15px;
background-color: #FFF799;
border: 1px solid;
}
</style>
</head>
<body>
<p>
<img src="imgs/html5.png" alt=""/>
Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.
</p>
</body>
</html>
Come si può notare dall'esempio, l'elemento <img> non ha
più il comportamento tradizionale (allineamento con il
testo) ma continua ad influenzare il contenuto circostante.
Un elemento floating può essere considerato come un'isola
attorno alla quale deve fluire il contenuto.
Si nota anche come l'elemento <img> sia posizionato
all'interno dell'area del contenuto del padre (e non si
estenda ad esempio al padding).
Infine, la proprietà “float” si applica a tutto l'elemento
inclusi padding, margini e bordi.
L'esempio seguente applica la proprietà “float” a del testo
inline.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
span {
float: right;
margin: 10px;
width: 200px;
color: #FFF;
background-color: #9D080D;
padding: 4px;
}
p {
padding: 15px;
background-color: #FFF799;
border: 1px solid;
}
</style>
</head>
<body>
<p>
<span>Lorem ipsum dolor sit amet</span>
Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.
</p>
</body>
</html>
Il comportamento sembra identico a quello dell'esempio
precedente ma ci sono alcuni aspetti da tenere in
considerazione:
• E' preferibile specificare la proprietà “width” per un
testo inline floating poiché le dimensioni del box
dell'elemento potrebbero essere diverse da browser a
browser.
• Gli elementi inline floating si comportano come
elementi di tipo blocco e quindi, ad esempio, i margini
dell'elemento <span> vengono visualizzati su tutti i lati
(e non solo a destra e sinistra).
• I margini superiore e inferiore degli elementi floating
non vengono uniti.
L'esempio seguente applica la proprietà “float” ad un
elemento di tipo blocco.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
p#floating {
float: left;
width: 200px;
margin-top: 0px;
background: #A5D3DE;
}
p {
border: 1px solid;
}
</style>
</head>
<body>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua.
</p>
<p id="floating"> Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. </p>
<p>Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. </p>
</body>
</html>
Anche in questo caso, ci sono alcuni aspetti da sottolineare:
• Se non si imposta la proprietà “width” dell'elemento,
allora questo occuperà tutto lo spazio che occupa
normalmente (in questo caso, l'intera larghezza della
finestra il che rende inutile usare la proprietà “float”).
• Un elemento floating di tipo blocco starà sempre al di
sotto degli elementi blocco che lo precedono. Quindi,
per poter posizionare ad esempio un elemento floating
nell'angolo in alto a sinistra delle finestra, è necessario
che questo elemento sia il primo nel codice html
(oppure usare il posizionamento assoluto come
vedremo in seguito).
• Per poter allineare i margini superiori dell'elemento
floating e dell'elemento seguente, è stato necessario
impostare il margine superiore dell'elemento floating a
0 (altrimenti viene impostato il default del browser).
Annullare il floating
Per poter ripristinare il normale comportamento degli
elementi che seguono un elemento floating, è necessario
utilizzare la proprietà “clear”. Tale proprietà si applica solo
agli elementi di tipo blocco e deve essere applicata
all'elemento che si vuole venga posizionato sotto
all'elemento floating, non all'elemento floating stesso.
Il valore left per la proprietà “clear” posiziona un elemento
sotto qualsiasi elemento con proprietà “float” impostata a
left. Il valore right posiziona un elemento sotto qualsiasi
elemento con proprietà “float” impostata a right. Il valore
both posiziona un elemento sotto qualsiasi elemento
floating.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
p {
border: 1px solid;
}
p#floating {
float: left;
width: 200px;
margin-top: 0px;
background: #A5D3DE;
}
p#cleared {
clear: both;
}
</style>
</head>
<body>
<p id="floating"> Lorem ipsum dolor sit amet,
consectetur adipisicing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.
</p>
<p> Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. </p>
<p id="cleared"> Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. </p>
</body>
</html>
Elementi floating multipli
E' ovviamente possibile inserire più elementi floating
all'interno di una pagina o anche all'interno di un unico
elemento. Esiste un complesso insieme di regole che
determina come posizionare tali elementi in modo che non
si sovrappongano tra loro ma in generale gli elementi
floating vengono posizionati più a destra o sinistra possibile
e più in alto possibile, compatibilmente con lo spazio a
disposizione.
Nell'esempio seguente, sono stati inseriti quattro elementi
floating a sinistra che vengono posizionati uno accanto
all'altro finché c'è spazio. Quando lo spazio disponibile non
è sufficiente, gli elementi floating riprendono da una
posizione più in basso a sinistra.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
p {
border: 1px solid;
}
p.floating {
float: left;
width: 200px;
margin-top: 0px;
background: #A5D3DE;
}
p#float1 {
height: 200px;
background: #ccc;
}
</style>
</head>
<body>
<p>P1</p>
<p class="floating" id="float1">Lorem ipsum dolor sit
amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.</p>
<p class="floating">Lorem ipsum dolor sit amet,
consectetur adipisicing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.</p>
<p class="floating">Lorem ipsum dolor sit amet,
consectetur adipisicing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.</p>
<p class="floating">Lorem ipsum dolor sit amet,
consectetur adipisicing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua.</p>
</body>
</html>
Questo comportamento può essere sfruttato per creare un
menu orizzontale come nell'esempio seguente.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
ul li {
float: left;
}
ul li a {
display: block;
text-decoration: none;
border: solid thick;
border-top-right-radius: 10px;
border-top-left-radius: 10px;
background-color: rgba(255,144,0,1);
padding: 5px;
margin: 3px;
}
p#first { clear: both;}
</style>
</head>
<body>
<ul>
<li><a href="#">Elemento1</a></li>
<li><a href="#">Elemento2</a></li>
<li><a href="#">Elemento3</a></li>
<li><a href="#">Elemento4</a></li>
<li><a href="#">Elemento5</a></li>
</ul>
<p id="first">Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua.</p>
</body>
</html>
Notate che questo esempio è diverso da quello del capitolo
precedente in cui creavamo un menu orizzontale facendo
comportare come inline gli elementi <li> del menu. Questa
soluzione è preferibile in quanto permette un controllo
migliore dello spazio tra gli elementi.
Elementi floating e contenitori
Un problema che può accadere quando si utilizzano
elementi floating è che questi si estendano al di fuori
dell'elemento che li contiene, come nell'esempio seguente.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
img { float: left; }
p { border: 1px solid; }
</style>
</head>
<body>
<p><img src="imgs/html5.png" alt=""/> Lorem ipsum dolor
sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua..</p>
</body>
</html>
Allo stesso modo, se vengono resi floating tutti gli elementi
di un certo contenitore, quel contenitore scomparirà come
nell'esempio seguente.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
div {
background: #A5D3DE;
border: 1px solid;
}
p {
float: left;
width: 200px;
border: 1px solid;
}
</style>
</head>
<body>
<div>
<p>Lorem ipsum dolor sit amet,
adipisicing elit, sed do eiusmod tempor
et dolore magna aliqua..</p>
<p>Lorem ipsum dolor sit amet,
adipisicing elit, sed do eiusmod tempor
et dolore magna aliqua..</p>
</div>
</body>
</html>
consectetur
incididunt ut labore
consectetur
incididunt ut labore
Una possibile soluzione a questo problema è rendere il
contenitore stesso floating e impostarne la larghezza a
100%. La seconda soluzione è impostare la proprietà
“overflow” dell'elemento contenitore ad auto o hidden.
Creare colonne con float
La proprietà “float” può essere sfruttata per organizzare il
layout di un sito in colonne (riparleremo di layout più
avanti). Per creare un layout a due colonne, si possono
utilizzare le seguenti soluzioni basate sull'impiego di
elementi <div>:
• Rendere floating a sinistra il primo <div> e aggiungere
un margine sinistro sufficiente al secondo <div>.
• Rendere floating a destra o a sinistra entrambi i <div>.
• Rendere floating a sinistra un div e a destra l'altro.
Nella creazione di un layout di questo tipo bisogna porre
particolare attenzione ad impostare correttamente le
dimensioni (in larghezza) degli elementi floating (inclusi
padding, bordi e margini). Se la dimensione totale degli
elementi floating è superiore allo spazio disponibile sul
browser, gli elementi floating in eccesso vengono
riposizionati più in basso (il che non è normalmente l'effetto
voluto).
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
div {
width: 41%;
margin: 2%;
padding: 2%;
background: #A5D3DE;
border: 1px solid;
}
div#col1 { float: left; }
div#col2 { float: right; }
</style>
</head>
<body>
<div id="col1">
<p>Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.</p>
</div>
<div id="col2">
<p>Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum.</p>
</div>
</body>
</html>
Positioning
Oltre al floating, CSS mette a disposizione altri metodi che
consentono di posizionare precisamente elementi su una
pagina.
Tipi di posizionamento
La proprietà “position” permette di indicare quale metodo
di posizionamento deve essere utilizzato per l'elemento che
la specifica. I possibili valori sono static (il posizionamento
di default che abbiamo visto finora), relative (il box
dell'elemento viene spostato relativamente alla sua
posizione normale nel flusso degli elementi; lo spazio
occupato dall'elemento nel flusso viene preservato),
absolute (l'elemento viene posizionato in modo assoluto
rispetto alla finestra del browser o all'elemento contenitore;
lo spazio occupato nel flusso normale non viene
mantenuto), fixed (l'elemento viene posizionato in modo
fisso rispetto alla finestra del browser; la posizione viene
mantenuta anche durante lo scrolling).
Vedremo questi metodi in più dettaglio più avanti.
Specifica della posizione
Una volta stabilito il metodo di posizionamento, è possibile
utilizzare le proprietà “top”, “right”, “bottom”, “left” per
specificare l'offset dell'elemento rispetto al corrispondente
outer edge dell'elemento contenitore o del browser (in base
al tipo di posizionamento). Ad esempio, la proprietà “top”
definisce la distanza dell'outer edge superiore del box
dell'elemento dall'outer edge superiore del box contenitore
o del browser. I valori possono essere specificati tramite
unità di misura della lunghezza o percentuali. Valori
negativi definiscono un offset nella direzione opposta
rispetto ai valori positivi.
Posizionamento relativo
Il posizionamento relativo muove un elemento rispetto al
posto che questo avrebbe normalmente nel flusso degli
elementi. Nell'esempio seguente, un elemento <em> viene
spostato 30px verso il basso e 60px verso destra rispetto
alla sua posizione iniziale.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
p {
padding: 5px;
background: #A5D3DE;
border: 1px solid;
}
em {
position: relative;
top: 30px;
left: 60px;
background: orange;
}
</style>
</head>
<body>
<p>Lorem ipsum dolor sit amet, <em>consectetur
adipisicing elit</em>, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.</p>
</body>
</html>
Come si può notare, lo spazio che l'elemento avrebbe
occupato normalmente viene comunque mantenuto. Inoltre,
l'elemento nella nuova posizione può andare a sovrapporsi
ad altri elementi della pagina.
Posizionamento assoluto
Il vantaggio del posizionamento assoluto rispetto a quello
relativo è che lo spazio nel flusso originale normalmente
occupato dall'elemento non viene mantenuto e non influisce
quindi sul posizionamento di altri elementi.
Se impostiamo la proprietà “position” ad absolute
nell'esempio precedente, possiamo notare come l'elemento
<em> venga adesso posizionato in relazione all'angolo
superiore sinistro della finestra del browser (la parte del
browser che visualizza il contenuto web).
In generale, il posizionamento assoluto viene effettuato in
relazione al più vicino “containing block”. Quest'ultimo è il
più vicino elemento antenato che utilizza la proprietà
“position” (con valore diverso da static). Se non c'è nessun
antenato di questo tipo, allora il containing block è
l'elemento radice (quello creato dall'elemento <html> e
corrispondente alla finestra del browser).
Nell'esempio seguente, la posizione dell'elemento <em>
non viene più definita in relazione alla finestra del browser
ma in relazione all'elemento <p> che contiene <em>, in
quanto <p> è stato trasformato in un containing block
attraverso l'utilizzo della proprietà “position” con valore
relative (senza peraltro spostare effettivamente l'elemento
<p>; questo è il modo più diffuso per sfruttare il
posizionamento relativo).
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
p {
position: relative;
padding: 5px;
background: #A5D3DE;
border: 1px solid;
}
em {
position: absolute;
top: 30px;
left: 60px;
background: orange;
}
</style>
</head>
<body>
<p>Lorem ipsum dolor sit amet, <em>consectetur
adipisicing elit</em>, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.</p>
</body>
</html>
Va tenuto presente che quando il containing block è un
elemento di tipo blocco, come nell'esempio sopra, il
posizionamento assoluto viene calcolato rispetto al limite
del padding dell'elemento di tipo blocco mentre quando il
containing block è un elemento di tipo inline, il
posizionamento viene effettuato rispetto all'area del
contenuto dell'elemento inline.
Inoltre, un elemento inline posizionato in modo assoluto si
comporta come un elemento di tipo blocco e quindi ad
esempio un eventuale margine viene inserito su tutti i lati
dell'elemento inline.
Nell'esempio seguente utilizziamo il posizionamento
assoluto per posizionare un elemento <div> all'interno di un
altro elemento <div>, definendone in modo implicito le
dimensioni.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
div#a {
position: relative;
height: 240px;
width: 600px;
border: 1px solid;
background-color: #CCC;
}
div#b {
position: absolute;
top: 20px;
right: 30px;
bottom: 40px;
left: 50px;
border: 1px solid;
background-color: orange;
}
</style>
</head>
<body>
<div id="a">
<div id="b">
</div>
</div>
</body>
</html>
In casi come quello appena visto bisogna fare attenzione a
non combinare la definizione esplicita delle dimensioni di
un elemento con la specifica del suo posizionamento
assoluto su tutti i lati per evitare potenziali conflitti (anche
se CSS definisce delle regole per gestire tali conflitti).
Oltre ad utilizzare unità di misura di lunghezza, la posizione
di un elemento può anche essere specificata utilizzando
valori percentuali.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
div {
position: relative;
height: 400px;
width: 600px;
border: 1px solid;
background-color: #CCC;
}
img#a {
position: absolute;
top: 50%;
left: 0%;
}
img#b {
position: absolute;
bottom: 0%;
right: 0%;
}
</style>
</head>
<body>
<div id="a">
<img id="a" src="imgs/html5.png" alt=""/>
<img id="b" src="imgs/html5.png" alt=""/>
</div>
</body>
</html>
Sovrapposizioni
Poichè gli elementi posizionati possono sovrapporsi tra di
loro, la proprietà “z-index” permette di modificare l'ordine
con cui tali elementi vengono visualizzati sullo schermo. Di
default, gli elementi appaiono nell'ordine in cui vengono
incontrati nel documento html. Il valore è un numero
(positivo o negativo) che determina l'ordine: gli elementi
vengono visualizzati a partire dai valori più bassi. Gli
specifici valori utilizzati non sono importanti (ad esempio,
non è necessario che siano sequenziali), viene considerato
solo il loro ordine relativo.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
img#a {
z-index: 10;
position: absolute;
top: 100px;
left: 200px;
}
img#b {
z-index: 5;
position: absolute;
top: 125px;
left: 225px;
}
div {
height: 400px;
width: 400px;
border: 1px solid;
background-color: #CCC;
}
</style>
</head>
<body>
<div>
<img id="a" src="imgs/css3.png" alt=""/>
<img id="b" src="imgs/html5.png" alt=""/>
</div>
</body>
</html>
Posizionamento fisso
Il posizionamento fisso, specificato tramite valore fixed
della proprietà “position”, si comporta in modo simile a
quello assoluto. La differenza sostanziale è che lo
spostamento degli elementi è sempre relativo al viewport il
che significa che gli elementi posizionati in questo modo
restano fissi nella loro posizione sullo schermo anche
quando l'utente scrolla la pagina. Questo tipo di
posizionamento può essere utilizzato ad esempio per
mantenere un menu sempre visibile sullo schermo. Il
posizionamento fisso può causare problemi su alcuni
browser mobili a causa di un'implementazione scorretta.
<!DOCTYPE html>
<html>
<head>
<title>
Tecnologie web
</title>
<style>
ul {
position: fixed;
top: 0%;
left: 0%;
list-style-type: none;
margin: 0;
padding: 0;
}
ul li { float: left; }
ul li a {
display: block;
text-decoration: none;
border: solid thick;
border-top-right-radius: 10px;
border-top-left-radius: 10px;
background-color: rgba(255,144,0,1);
padding: 5px;
margin: 3px;
}
p#first {
position: absolute;
top: 50px;
clear: both;
}
</style>
</head>
<body>
<ul>
<li><a href="#">Elemento1</a></li>
<li><a href="#">Elemento2</a></li>
<li><a href="#">Elemento3</a></li>
</ul>
<p id="first">Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua.</p>
<p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>
<p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>
<p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>
<p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>
</body>
</html>