CSS Layouty

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.

<!DOCTYPE html>
<html lang="cs">
<head>
    <title>Vlastnost float</title>
    <style>
        img {
            width150px;
            floatright
        }
    </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>

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.

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.

header
side bar
content
float: left;
Jiří Satora
profil

odhlásit se

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.

<!DOCTYPE html>
<html lang="cs">
<head>
    <title>Vlastnost clear</title>
    <style>
        .float-left-element {
            background-colororangeredcolorwhitefont-size16px;

            height100px;

            floatleft/* nastavení elementu na plovoucí */
        }
        .element-1 background-colorgreencolorwhitefont-size16px; }
        .element-2 background-colorbluecolorwhitefont-size16px}
        .element-3 {
            background-colororangecolorwhitefont-size16px;
            
            clearleft/* zrušení obtékání kolem plovoucího elementu */
        }
        .element-4 background-colorpurplecolorwhitefont-size16px}
    </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>
element s float: left;
1
2
3
4

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.

.row {
    max-width700px/* nastavení maximální šířky gridu */
    marginauto/* vycentrování gridu na střed */
    font-size16px/* pro testování */
}

.col-1-of-2 /* sloupec pro jednu polovinu řádku */
    floatleft/* nastavení elementu na plovoucí */
    width50%/* sloupec bude zabírat jednu polovinu řádku */
    background-colororangered/* nějaké pozadí pro testování */
}
@grid-width700px// šířka gridu

.row {
    max-width@grid-width// nastavení maximální šířky gridu
    marginauto// vycentrování gridu na střed
    font-size16px// pro testování

    .col-1-of-2 // sloupec pro jednu polovinu řádku
        floatleft// nastavení elementu na plovoucí
        width50%// sloupec bude zabírat jednu polovinu řádku
        background-colororangered// nějaké pozadí pro testování
    }
}
<!DOCTYPE html>
<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>
1
2
3
4

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.

1
2
3

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.

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.

.row {
    max-width700px;
    marginauto;
    font-size16px;
}

/* clearfix */
.row::after /* nastylování ::after pseudo elementu */
    content""/* řekneme že se má za řádkem pseudo element zobrazit */
    displaytable/* nějak element zobrazíme */
    clearboth/* zrušíme obtékání */
}

.col-1-of-2 {
    floatleft;
    width50%;
    background-colororangered;
}
@grid-width700px;

#clearfix() { // mixin pro clearfix
    &::after // nastylování pseudo elementu
        content""// řekneme že se má za řádkem pseudo element zobrazit
        displaytable// nějak element zobrazíme
        clearboth// zrušíme obtékání
    }
}

.row {
    max-width@grid-width;
    marginauto;
    font-size16px;

    #clearfix()// použití cleafixu

    .col-1-of-2 {
        floatleft;
        width50%;
        background-colororangered;
    }
}
<!DOCTYPE html>
<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>
1
2
3

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.

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.

.row {
    max-width700px;
    marginauto;
    font-size16px;
}

.row:not(:last-child) { /* všechny řádky kromě posledního budou mít pod sebou mezeru */
    margin-bottom20px;
}

/* clearfix */
.row::after {
    content"";
    displaytable;
    clearboth;
}

.col-1-of-2 {
    floatleft;
    widthcalc((100% - 20px) / 2)/* protože teď řádek obsahuje také mezery, tak musíme nastavovat šířku trochu složitěji */
    background-colororangered;
}

.col-1-of-2:not(:last-child) /* všechny sloupce v řádku kromě posledního budou mít napravo mezeru */
    margin-right20px;
}
@grid-width700px;
@gutter-vertical20px// velikost mezery mezi řádky
@gutter-horizontal20px// velikost mezery mezi sloupci

#clearfix() {
    &::after {
        content"";
        displaytable;
        clearboth;
    }
}

.row {
    max-width@grid-width;
    marginauto;
    font-size16px;

    #clearfix();

    &:not(:last-child) { // všechny řádky kromě posledního budou mít pod sebou mezeru
        margin-bottom@gutter-vertical;
    }

    .col-1-of-2 {
        floatleft;
        widthcalc((100% - @gutter-horizontal) / 2)// protože teď řádek obsahuje také mezery, tak musíme nastavovat šířku trochu složitěji
        background-colororangered;
        &:not(:last-child) // všechny sloupce v řádku kromě posledního budou mít napravo mezeru
            margin-right@gutter-horizontal;
        }
    }
}
<!DOCTYPE html>
<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>
1
2
3
4

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.

.row {
    max-width700px;
    marginauto;
    font-size16px;
}

.row:not(:last-child) {
    margin-bottom20px;
}

/* clearfix */
.row::after {
    content"";
    displaytable;
    clearboth;
}

[class^="col-"]:not(:last-child) { /* selektor pro všechny sloupce */
    floatleft;
    background-colororangered;
}

[class^="col-"]:not(:last-child) { /* všechny sloupce v jednom řádku budou mít napravo mezeru, kromě posledního */
    margin-right20px;
}

.col-1-of-2 { /* sloupec - 1 ze 2 */
    /* (100% - mezera) / 2 */
    widthcalc((100% - 20px) / 2);
}
.col-1-of-3 { /* sloupec - 1 ze 3 */
    /* (100% - 2 mezery) / 3 */
    widthcalc((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) */
    widthcalc(2 * ((100% - 20px * 2) / 3) + 20px);
}
.col-1-of-4 { /* sloupec - 1 ze 4 */
    /* (100% - 3 mezery) / 4 */
    widthcalc((100% - 20px * 3) / 4);
}
.col-2-of-4 { /* sloupec - 2 ze 4 */
    /* 2 * ((100% - 3 mezery) / 4) + mezera */
    widthcalc(2 * ((100% - 20px * 3) / 4) + 20px);
}
.col-3-of-4 { /* sloupec - 3 ze 4 */
    /* 3 * ((100% - 3 mezery) / 4) + 2 mezery */
    widthcalc(3 * ((100% - 20px * 3) / 4) + 2 * 20px);
}
@grid-width700px;
@gutter-vertical20px;
@gutter-horizontal20px;

#clearfix() {
    &::after {
        content"";
        displaytable;
        clearboth;
    }
}

.row {
    max-width@grid-width;
    marginauto;
    font-size16px;

    #clearfix();

    &:not(:last-child) {
        margin-bottom@gutter-vertical;
    }

    [class^="col-"] { // selektor pro všechny sloupce
        floatleft;
        background-colororangered;
        &:not(:last-child) {
            margin-right: @gutter-horizontal;
        }
    }

    .col-1-of-2 // sloupec - 1 ze 2
        // (100% - mezera) / 2
        widthcalc((100% - @gutter-horizontal) / 2);
    }
    .col-1-of-3 // sloupec - 1 ze 3
        // (100% - 2 mezery) / 3
        widthcalc((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)
        widthcalc(2 * ((100% - @gutter-horizontal * 2) / 3) + @gutter-horizontal);
    }
    .col-1-of-4 // sloupec - 1 ze 4
        // (100% - 3 mezery) / 4
        widthcalc((100% - @gutter-horizontal * 3) / 4);
    }
    .col-2-of-4 // sloupec - 2 ze 4
        // 2 * ((100% - 3 mezery) / 4) + mezera
        widthcalc(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)
        widthcalc(3 * ((100% - @gutter-horizontal * 3) / 4) + 2 * @gutter-horizontal);
    }
}
<!DOCTYPE html>
<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>
col-1-of-2
col-1-of-2
col-1-of-3
col-1-of-3
col-1-of-3
col-1-of-3
col-2-of-3
col-1-of-4
col-1-of-4
col-1-of-4
col-1-of-4
col-1-of-4
col-2-of-4
col-1-of-4
col-1-of-4
col-3-of-4