Float Layouty
V tomto článku se dozvíte, jak můžete vytvářet layouty pomocí vlastnosti float. Tato vlastnost, jak možná víte slouží k nastavení elementu na plovoucí. Pokud tedy tuto vlastnost nějakému elementu nastavíme, tak jej ostatní neplovoucí elementy začnou obtékat. Klasickým příkladem je obrázek u kterého chceme aby jej obtékal text.
<html lang="cs">
<head>
<title>Vlastnost float</title>
<style>
img {
width: 150px;
float: right;
}
</style>
</head>
<body>
<img src="./Desk.jpg">
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla ratione molestiae dicta facere hic modi consequatur ab voluptatibus! Distinctio doloribus, aspernatur vero, voluptas nobis molestiae aperiam possimus maxime ipsum velit totam quam tempora nisi sapiente! Expedita rerum animi non ratione quibusdam quisquam itaque temporibus minima, magni alias nostrum officiis obcaecati maiores, fugiat, provident in ab commodi aperiam omnis nulla! Dignissimos tempora dolorem distinctio ullam necessitatibus voluptate tempore, consequuntur expedita delectus.
</p>
</body>
</html>
K čemu můžeme float vlastnost použít?
Kromě obtékání obrázku textem můžeme float použít také na vytváření layoutů. Můžeme vytvářet celý layout webové stránky, nebo třeba jen nějaké její menší části, jak ukazují následující dvě ukázky. Dnes už ale na tvorbu layoutů máme mnohem lepší nástroje, Flexbox a CSS Grid.
Zrušení obtékání pomocí vlastnosti clear
Ještě než se pustíme do tvorby nějakého float layout systému, tak bychom měli vědět jak funguje zrušení obtékání kolem plovoucích elementů. Slouží k tomu vlastnost clear, kterou když nějakému elementu nastavíme, přestane obtékat kolem plovoucích elementů. Tuto vlastnost můžeme nastavit na hodnotu left, right nebo both. Pokud nastavíme hodnotu left, tak element přestane obtékat kolem elementů plovoucích vlevo, pokud right tak kolem elementů plovoucích vpravo a pokud both tak přestane obtékat kolem elementů plovoucích vlevo i vpravo. Následující ukázka použití vlastnosti clear ukazuje.
<html lang="cs">
<head>
<title>Vlastnost clear</title>
<style>
.float-left-element {
background-color: orangered; color: white; font-size: 16px;
height: 100px;
float: left; /* nastavení elementu na plovoucí */
}
.element-1 { background-color: green; color: white; font-size: 16px; }
.element-2 { background-color: blue; color: white; font-size: 16px; }
.element-3 {
background-color: orange; color: white; font-size: 16px;
clear: left; /* zrušení obtékání kolem plovoucího elementu */
}
.element-4 { background-color: purple; color: white; font-size: 16px; }
</style>
</head>
<body>
<div class="float-left-element">element s float: left;</div>
<div class="element-1">1</div>
<div class="element-2">2</div>
<div class="element-3">3</div>
<div class="element-4">4</div>
</body>
</html>
Tvorba grid systému
Pro ukázku tvorby layoutů s vlastností float si vytvoříme takový grid systém. Budeme mít jednu třídu pro řádky a nějaké třídy pro sloupce. Když budeme chtít vytvořit řádek, tak na stránku přidáme element s třídou pro řádek a když budeme chtít v řádku vytvořit sloupce, tak do něj přidáme elementy s třídami pro sloupce. Začneme vytvořením třídy pro řádek a třídy pro sloupec o šířce poloviny šířky řádku.
max-width: 700px; /* nastavení maximální šířky gridu */
margin: 0 auto; /* vycentrování gridu na střed */
font-size: 16px; /* pro testování */
}
.col-1-of-2 { /* sloupec pro jednu polovinu řádku */
float: left; /* nastavení elementu na plovoucí */
width: 50%; /* sloupec bude zabírat jednu polovinu řádku */
background-color: orangered; /* nějaké pozadí pro testování */
}
.row {
max-width: @grid-width; // nastavení maximální šířky gridu
margin: 0 auto; // vycentrování gridu na střed
font-size: 16px; // pro testování
.col-1-of-2 { // sloupec pro jednu polovinu řádku
float: left; // nastavení elementu na plovoucí
width: 50%; // sloupec bude zabírat jednu polovinu řádku
background-color: orangered; // nějaké pozadí pro testování
}
}
<html lang="cs">
<head>
<title>Float Grid Systém</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="row">
<div class="col-1-of-2">
1
</div>
<div class="col-1-of-2">
2
</div>
</div>
<div class="row">
<div class="col-1-of-2">
3
</div>
<div class="col-1-of-2">
4
</div>
</div>
</body>
</html>
Clearfix
Náš grid funguje ale obsahuje jednu nedokonalost, která na první pohled není vidět. Pokud se např. pomocí vývojářských nástrojů v prohlížeči podíváte jakou výšku má řádek, tak zjistíte že žádnou výšku nemá. Pokud div obsahuje jen plovoucí elementy, tak nebude mít žádnou výšku. Elementy, které řádek obsahuje ale přetečou ven, takže to vypadá jako by řádek nějakou výšku měl. V některých případech by to možná nevadilo, ale ve většině ano. Jeden takový případ ukazuje následující ukázka.
Jak vidíte v ukázce, pokud za náš grid chceme přidat například odstavec, tak se stane to, že text odstavce začne grid obtékat. Děje se to, protože řádky nemají žádnou výšku. Tento nedostatek můžeme vyřešit tím, že za každý řádek umístíme nějaký element, který obtékání zruší pomocí vlastnosti clear a nastaví řádkům výšku. Říká se tomu clearfix. Klidně bychom mohli za každý řádek přidávat tento element ručně, ale existuje lepší cesta. Namísto přidávání elementů ručně můžeme použít ::after pseudo element. Pokud v CSS řekneme že se má tento pseudo element zobrazit, tak se nám automaticky za každý řádek bude přidávat element a můžeme jej v CSS nastylovat. Jak clearfix vytvořit ukazuje následující ukázka.
max-width: 700px;
margin: 0 auto;
font-size: 16px;
}
/* clearfix */
.row::after { /* nastylování ::after pseudo elementu */
content: ""; /* řekneme že se má za řádkem pseudo element zobrazit */
display: table; /* nějak element zobrazíme */
clear: both; /* zrušíme obtékání */
}
.col-1-of-2 {
float: left;
width: 50%;
background-color: orangered;
}
#clearfix() { // mixin pro clearfix
&::after { // nastylování pseudo elementu
content: ""; // řekneme že se má za řádkem pseudo element zobrazit
display: table; // nějak element zobrazíme
clear: both; // zrušíme obtékání
}
}
.row {
max-width: @grid-width;
margin: 0 auto;
font-size: 16px;
#clearfix(); // použití cleafixu
.col-1-of-2 {
float: left;
width: 50%;
background-color: orangered;
}
}
<html lang="cs">
<head>
<title>Float Grid Systém</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="row">
<div class="col-1-of-2">
1
</div>
<div class="col-1-of-2">
2
</div>
</div>
<div class="row">
<div class="col-1-of-2">
3
</div>
</div>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Inventore cupiditate quos, est minus totam dignissimos quasi officiis beatae exercitationem, veritatis explicabo ea quia velit recusandae temporibus, vitae nostrum facere incidunt.</p>
</body>
</html>
Jak můžete vidět, po použití clearfixu již text odstavce náš grid neobtéká.
Mezery mezi buňkami gridu
V našem gridu nyní buňky mezi sebou nemají žádné mezery, jsou nalepeny všechny na sobě. Pokud by nám to tak vyhovovalo, mohli bychom to tak nechat. Pokud ale ne, tak bychom museli náš kód trochu předělat a definovat si mezi buňkami nějaké mezery. Následující ukázka ukazuje jak bychom to mohli udělat. A protože už nemůžeme jen tak nastavit sloupci šířku 50%, musíme použít funkci calc, která nám umožňuje v CSS provádět výpočty. V této funkci odečteme od 100% jednu mezeru a výsledek vydělíme dvěma abychom dostali šířku jednoho sloupce.
max-width: 700px;
margin: 0 auto;
font-size: 16px;
}
.row:not(:last-child) { /* všechny řádky kromě posledního budou mít pod sebou mezeru */
margin-bottom: 20px;
}
/* clearfix */
.row::after {
content: "";
display: table;
clear: both;
}
.col-1-of-2 {
float: left;
width: calc((100% - 20px) / 2); /* protože teď řádek obsahuje také mezery, tak musíme nastavovat šířku trochu složitěji */
background-color: orangered;
}
.col-1-of-2:not(:last-child) { /* všechny sloupce v řádku kromě posledního budou mít napravo mezeru */
margin-right: 20px;
}
@gutter-vertical: 20px; // velikost mezery mezi řádky
@gutter-horizontal: 20px; // velikost mezery mezi sloupci
#clearfix() {
&::after {
content: "";
display: table;
clear: both;
}
}
.row {
max-width: @grid-width;
margin: 0 auto;
font-size: 16px;
#clearfix();
&:not(:last-child) { // všechny řádky kromě posledního budou mít pod sebou mezeru
margin-bottom: @gutter-vertical;
}
.col-1-of-2 {
float: left;
width: calc((100% - @gutter-horizontal) / 2); // protože teď řádek obsahuje také mezery, tak musíme nastavovat šířku trochu složitěji
background-color: orangered;
&:not(:last-child) { // všechny sloupce v řádku kromě posledního budou mít napravo mezeru
margin-right: @gutter-horizontal;
}
}
}
<html lang="cs">
<head>
<title>Float Grid Systém</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="row">
<div class="col-1-of-2">
1
</div>
<div class="col-1-of-2">
2
</div>
</div>
<div class="row">
<div class="col-1-of-2">
3
</div>
<div class="col-1-of-2">
4
</div>
</div>
</body>
</html>
Vytvoření více velikostí sloupců
Teď když máme náš grid systém v podstatě hotový, můžeme si pro něj vytvořit další velikosti sloupců. Tyto sloupce budou mít všechny stejné vlastnosti kromě šířky, která bude u každého jiná. Pokud tedy tyto stejné vlastnosti nechceme u každého sloupce vypisovat, můžeme si vytvořit selektor na všechny sloupce najednou a nastavit je společně. Můžeme to udělat atribut selektorem, pomocí kterého si najdeme všechny elementy s třídou začínající na text "col-". Následující ukázka tento selektor spolu s třídami různých velikostí sloupců ukazuje.
max-width: 700px;
margin: 0 auto;
font-size: 16px;
}
.row:not(:last-child) {
margin-bottom: 20px;
}
/* clearfix */
.row::after {
content: "";
display: table;
clear: both;
}
[class^="col-"]:not(:last-child) { /* selektor pro všechny sloupce */
float: left;
background-color: orangered;
}
[class^="col-"]:not(:last-child) { /* všechny sloupce v jednom řádku budou mít napravo mezeru, kromě posledního */
margin-right: 20px;
}
.col-1-of-2 { /* sloupec - 1 ze 2 */
/* (100% - mezera) / 2 */
width: calc((100% - 20px) / 2);
}
.col-1-of-3 { /* sloupec - 1 ze 3 */
/* (100% - 2 mezery) / 3 */
width: calc((100% - 20px * 2) / 3);
}
.col-2-of-3 { /* sloupec - 2 ze 3 */
/* 2 * ((100% - 2 mezery) / 3) + mezera (sloupec obsahuje jednu mezeru, tak ji musíme přičíst) */
width: calc(2 * ((100% - 20px * 2) / 3) + 20px);
}
.col-1-of-4 { /* sloupec - 1 ze 4 */
/* (100% - 3 mezery) / 4 */
width: calc((100% - 20px * 3) / 4);
}
.col-2-of-4 { /* sloupec - 2 ze 4 */
/* 2 * ((100% - 3 mezery) / 4) + mezera */
width: calc(2 * ((100% - 20px * 3) / 4) + 20px);
}
.col-3-of-4 { /* sloupec - 3 ze 4 */
/* 3 * ((100% - 3 mezery) / 4) + 2 mezery */
width: calc(3 * ((100% - 20px * 3) / 4) + 2 * 20px);
}
@gutter-vertical: 20px;
@gutter-horizontal: 20px;
#clearfix() {
&::after {
content: "";
display: table;
clear: both;
}
}
.row {
max-width: @grid-width;
margin: 0 auto;
font-size: 16px;
#clearfix();
&:not(:last-child) {
margin-bottom: @gutter-vertical;
}
[class^="col-"] { // selektor pro všechny sloupce
float: left;
background-color: orangered;
&:not(:last-child) {
margin-right: @gutter-horizontal;
}
}
.col-1-of-2 { // sloupec - 1 ze 2
// (100% - mezera) / 2
width: calc((100% - @gutter-horizontal) / 2);
}
.col-1-of-3 { // sloupec - 1 ze 3
// (100% - 2 mezery) / 3
width: calc((100% - @gutter-horizontal * 2) / 3);
}
.col-2-of-3 { // sloupec - 2 ze 3
// 2 * ((100% - 2 mezery) / 3) + mezera (sloupec obsahuje jednu mezeru, tak ji musíme přičíst)
width: calc(2 * ((100% - @gutter-horizontal * 2) / 3) + @gutter-horizontal);
}
.col-1-of-4 { // sloupec - 1 ze 4
// (100% - 3 mezery) / 4
width: calc((100% - @gutter-horizontal * 3) / 4);
}
.col-2-of-4 { // sloupec - 2 ze 4
// 2 * ((100% - 3 mezery) / 4) + mezera
width: calc(2 * ((100% - @gutter-horizontal * 3) / 4) + @gutter-horizontal);
}
.col-3-of-4 { // sloupec - 3 ze 4
// 3 * ((100% - 3 mezery) / 4) + 2 mezery (sloupec obsahuje 2 mezery)
width: calc(3 * ((100% - @gutter-horizontal * 3) / 4) + 2 * @gutter-horizontal);
}
}
<html lang="cs">
<head>
<title>Float Grid Systém</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="row">
<div class="col-1-of-2">
col-1-of-2
</div>
<div class="col-1-of-2">
col-1-of-2
</div>
</div>
<div class="row">
<div class="col-1-of-3">
col-1-of-3
</div>
<div class="col-1-of-3">
col-1-of-3
</div>
<div class="col-1-of-3">
col-1-of-3
</div>
</div>
<div class="row">
<div class="col-1-of-3">
col-1-of-3
</div>
<div class="col-2-of-3">
col-2-of-3
</div>
</div>
<div class="row">
<div class="col-1-of-4">
col-1-of-4
</div>
<div class="col-1-of-4">
col-1-of-4
</div>
<div class="col-1-of-4">
col-1-of-4
</div>
<div class="col-1-of-4">
col-1-of-4
</div>
</div>
<div class="row">
<div class="col-1-of-4">
col-1-of-4
</div>
<div class="col-2-of-4">
col-2-of-4
</div>
<div class="col-1-of-4">
col-1-of-4
</div>
</div>
<div class="row">
<div class="col-1-of-4">
col-1-of-4
</div>
<div class="col-3-of-4">
col-3-of-4
</div>
</div>
</body>
</html>