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> </p><p> </p><p> </p><p> </p> <p> </p><p> </p><p> </p><p> </p> <p> </p><p> </p><p> </p><p> </p> <p> </p><p> </p><p> </p><p> </p> </body> </html>