Layout

Александр Белёв

Layout (раскладка) –

взаимное расположение крупных блоков страницы.

Делаем колонки

Таблицы

колонка раз колонка два колонка три
колонка раз колонка два колонка три
раз два три
Раскладка на таблицах:
  • колонки выравниваются по высоте
  • адекватна при переполнении
  • куча лишней разметки
  • не семантично

Float




.float-left
{
    width: 33%;
    float: left;
}
float: left
float: left
float: left
float: left
float: left
float: left
clear: both
Раскладка на float:
  • размеры не зависят от контента
  • колонки переносятся
  • колонки не выравниваются по высоте
  • спецэффекты (схлопывание родителя)
    и хаки (clearfix)
  • перекрытие контента при переполнении

Inline-block

display: inline-block
display: inline-block
display: inline-block
Раскладка на inline-block:
  • реагируют на выравнивание
    (text-align и vertical-align)
  • можно задавать размеры
  • переносятся
  • лишние пробелы
  • колонки не выравниваются по высоте
  • при неаккуратной верстке всё может развалиться
Чем раскладывать-то тогда?
  • table — для табличных данных
  • float — для обтекания текстом
  • inline-block — вы не хотите так делать
  • obi
Чем раскладывать-то тогда?
  • table — для табличных данных
  • float — для обтекания текстом
  • inline-block — вы не хотите так делать
  • flexbox 👍
  • grid 👍

Flexbox

Гибкие раскладки:

  • управление распределением места
  • мощные возможности для выравнивания

display: flex

Термины

флекс-контейнер (flex-container)

флекс-элемент (flex-item)

главная ось (main axis)

поперечная ось (cross axis)

Флекс-элементы располагаются вдоль главной оси.


Свойство flex-direction меняет её направление.

flex-direction: row

по умолчанию


With your feet
in the air
when your head on the ground

flex-direction: row-reverse



With your feet
in the air
when your head on the ground

flex-direction: column

With your feet
in the air
when your head on the ground

flex-direction: column-reverse

With your feet
in the air
when your head on the ground

Свойство justify-content управляет выравниванием флекс-элементов вдоль главной оси.

justify-content: flex-start

по умолчанию


With your feet
in the air
when your head on the ground

justify-content: flex-end


With your feet
in the air
when your head on the ground

justify-content: center


With your feet
in the air
when your head on the ground

justify-content: space-between


With your feet
in the air
when your head on the ground

justify-content: space-around


With your feet
in the air
when your head on the ground

Поперечная ось всегда перпендикулярна главной оси.


Направление изменить нельзя.



Свойство align-items управляет выравниванием флекс-элементов вдоль поперечной оси.

align-items: stretch

по умолчанию


With your feet
in the air
when your head on the ground

align-items: flex-start


With your feet
in the air
when your head on the ground

align-items: flex-end


With your feet
in the air
when your head on the ground

align-items: center


With your feet
in the air
when your head on the ground

align-items: baseline


With your feet
in the air
when your head on the ground

align-self даёт переопределить выравнивание у флекс-элемента.

Значения те же, что и у align-items.


нам
сказали
стоять
в начале
я не с вами, ребят

Что если флекс-элементов
много?


With your feet
in the air
when your head on the ground

Будут сжиматься до предела.



With your feet
in the air
when your head on the ground
You try this trick and spin
Yeahh
Your head will collapse

Выйдут за пределы контейнера, но продолжат располагаться в один ряд.


With your feet
in the air
when your head on the ground
You try this trick and spin
Yeahh
Your head will collapse
when there is nothing in it
And you ask yourself
Where is my mind?
Where is my mind?

Переносом элементов управляет свойство flex-wrap, и по умолчанию перенос запрещён.

flex-wrap: nowrap wrap

With your feet
in the air
when your head on the ground
You try this trick and spin
Yeahh
Your head will collapse
when there is nothing in it
And you ask yourself
Where is my mind?
Where is my mind?

flex-wrap: wrap-reverse

With your feet
in the air
when your head on the ground
You try this trick and spin
Yeahh
Your head will collapse
when there is nothing in it
And you ask yourself
Where is my mind?
Where is my mind?

Можно комбинировать направление и перенос в свойстве flex-flow:

.container
{
    display: flex;
    flex-flow: row wrap;
}

Cвойство align-content управляет распределением рядов флекс-элементов вдоль поперечной оси.

align-content: stretch

по умолчанию


With your feet
in the air
when your head on the ground
You try this trick and spin
Yeahh
Your head will collapse
when there is nothing in it
And you ask yourself
Where is my mind?
Where is my mind?

align-content: flex-start


With your feet
in the air
when your head on the ground
You try this trick and spin
Yeahh
Your head will collapse
when there is nothing in it
And you ask yourself
Where is my mind?
Where is my mind?

align-content: flex-end


With your feet
in the air
when your head on the ground
You try this trick and spin
Yeahh
Your head will collapse
when there is nothing in it
And you ask yourself
Where is my mind?
Where is my mind?

align-content: center


With your feet
in the air
when your head on the ground
You try this trick and spin
Yeahh
Your head will collapse
when there is nothing in it
And you ask yourself
Where is my mind?
Where is my mind?

align-content: space-between


With your feet
in the air
when your head on the ground
You try this trick and spin
Yeahh
Your head will collapse
when there is nothing in it
And you ask yourself
Where is my mind?
Where is my mind?

align-content: space-around


With your feet
in the air
when your head on the ground
You try this trick and spin
Yeahh
Your head will collapse
when there is nothing in it
And you ask yourself
Where is my mind?
Where is my mind?

Если активно align-content,
то что с align-items?

align-content: stretch; align-items: center

With your feet
in the air
when your head on the ground
You try this trick and spin
Yeahh
Your head will collapse
when there is nothing in it
And you ask yourself
Where is my mind?
Where is my mind?

align-content: stretch; align-items: flex-start

With your feet
in the air
when your head on the ground
You try this trick and spin
Yeahh
Your head will collapse
when there is nothing in it
And you ask yourself
Where is my mind?
Where is my mind?

С помощью свойства order можно менять порядок следования флекс-элементов.

order: 0

по умолчанию


раз 0
два 0
три 0
четыре 0
пять 0

order: 1


раз 0
два 0
три 1
четыре 0
пять 0

order: -1


раз 0
два 0
три -1
четыре 0
пять 0

order


раз 1
два 2
три 3
четыре 4
пять 5

Как управлять размерами флекс-элементов?

Свободное пространство

Раз
Два
Три

positive free space

Раз
Два
Три

negative free space

Cвойство flex-basis задает базовый размер на главной оси.

    Возможные значения:

  • auto/content — размер контента
  • <length> — точное значение
  • 0 — не учитывать размер

flex-basis: 50%

50% по горизонтали
auto

50% по вертикали
auto

Почему размер базовый?

Это исходный размер.

Свободное место можно распределять в соответствии с коэффициентом жадности флекс-элемента (flex-grow).

flex-grow: 0

по умолчанию


😑 0
😐 0
😑 0

flex-grow: 1


😑 0
😜 1
😑 0

flex-grow: 2


😑 0
😒 1
😎 2

Как вычисляется итоговый размер?
  1. Посчитаем свободное место:
    free space = container width - ∑ flex-basis
  2. Посчитаем долю свободного места:
    fraction = free space / ∑ flex-grow
  3. Вычислим итоговый размер:
    final size = flex-basis + (fraction × flex-grow)
На размер свободного места могут влиять рамки и отступы
Особенности внешних отступов:
  • не схлапываются
  • отступ с auto заберет все свободное место по своему направлению
  • часть базового размера элемента

        

        .box {
            padding: 10px;
            margin: 10px;
        }

        .1 {
            flex-grow: 1;
        }

        .2 {
            flex-grow: 2;
        }
    

😑 0
😒 1
😎 2
width = 960px
flex-basisi = 2×10px + 2×10px + 25px = 65px
  • free space = 960px - 3 × 65px = 765px
  • fraction = 765px / (0 + 1 + 2) = 255px
  • final size1 = 65px + (255px × 0) = 65px;
  • final size2 = 65px + (255px × 1) = 320px;
  • final size3 = 65px + (255px × 2) = 575px;

Что если сумма базовых размеров больше, чем свободного места?

Будем делить отрицательное значение свободного места в соответствии с коэффициентами сжатия (flex-shrink).

flex-shrink: 1

по умолчанию


😒 ? 1
😜)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 1
плак ;( 1

flex-shrink: 0


😎 ! 0
😜)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 1
плак ;( 1

flex-shrink: 0


😎 ! 0
😜)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) 1
не плак :) 0

Положительное свободное место — увеличиваем размеры в соответствии с flex- grow

Отрицательное свободное место — уменьшаем в соответствии c flex-shrink

Дока с алгоритмом

С помощью сокращённого свойства flex можно одновременно задать
флекс-элементу flex-grow, flex-shrink
и flex-basis.

flex: [flex-grow] [flex-shrink] [flex-basis]

.elem
{
    flex: initial; /* = 0 1 auto — все по умолчанию */










}

flex: [flex-grow] [flex-shrink] [flex-basis]

.elem
{
    flex: initial; /* = 0 1 auto — все по умолчанию */
    flex: auto;    /* = 1 1 auto */









}

flex: [flex-grow] [flex-shrink] [flex-basis]

.elem
{
    flex: initial; /* = 0 1 auto — все по умолчанию */
    flex: auto;    /* = 1 1 auto */
    flex: none;    /* = 0 0 auto */








}

flex: [flex-grow] [flex-shrink] [flex-basis]

.elem
{
    flex: initial; /* = 0 1 auto — все по умолчанию */
    flex: auto;    /* = 1 1 auto */
    flex: none;    /* = 0 0 auto */
    flex: 2;       /* число -> flex-grow,
                      = 2 1 auto */






}

flex: [flex-grow] [flex-shrink] [flex-basis]

.elem
{
    flex: initial; /* = 0 1 auto — все по умолчанию */
    flex: auto;    /* = 1 1 auto */
    flex: none;    /* = 0 0 auto */
    flex: 2;       /* число -> flex-grow,
                      = 2 1 auto */
    flex: 50%;     /* единица измерения длины -> flex-basis = 50%,
                      = 0 1 50% */




}

flex: [flex-grow] [flex-shrink] [flex-basis]

.elem
{
    flex: initial; /* = 0 1 auto — все по умолчанию */
    flex: auto;    /* = 1 1 auto */
    flex: none;    /* = 0 0 auto */
    flex: 2;       /* число -> flex-grow,
                      = 2 1 auto */
    flex: 50%;     /* единица измерения длины -> flex-basis = 50%,
                      = 0 1 50% */
    flex: 0px;     /* не то же самое, что flex: 0! */



}

flex: [flex-grow] [flex-shrink] [flex-basis]

.elem
{
    flex: initial; /* = 0 1 auto — все по умолчанию */
    flex: auto;    /* = 1 1 auto */
    flex: none;    /* = 0 0 auto */
    flex: 2;       /* число -> flex-grow,
                      = 2 1 auto */
    flex: 50%;     /* единица измерения длины -> flex-basis = 50%,
                      = 0 1 50% */
    flex: 0px;     /* не то же самое, что flex: 0! */
    flex: 2 50%;   /* flex-grow & flex-basis,
                      = 2 1 50% */

}

flex: [flex-grow] [flex-shrink] [flex-basis]

.elem
{
    flex: initial; /* = 0 1 auto — все по умолчанию */
    flex: auto;    /* = 1 1 auto */
    flex: none;    /* = 0 0 auto */
    flex: 2;       /* число -> flex-grow,
                      = 2 1 auto */
    flex: 50%;     /* единица измерения длины -> flex-basis = 50%,
                      = 0 1 50% */
    flex: 0px;     /* не то же самое, что flex: 0! */
    flex: 2 50%;   /* flex-grow & flex-basis,
                      = 2 1 50% */
    flex: 2 0 50%;
}

А теперь немножко магии...

Родителю — display: flex,
ребёнку — margin: auto

стою по-царски по центру и чихал на все выравнивания

caniuse.com/#feat=flexbox

Полезные ссылки


  1. Гайд по флексбоксу
  2. Flexbox Playground
  3. Игра для изучения флексбокса

Перерыв

Grid

grid = сетка

Даёт возможность располагать элементы по сетке!

display: grid

Контейнер

Линия

Ячейка

Область

Дорожка

Интервал

Чтобы наполнить сетку колонками и рядами существуют свойства
grid-template-columns и grid-template-rows.

.container
{
    display: grid;
    grid-template-columns: 100px auto 100px; /* ширины столбцов */
    grid-template-rows: 100px 100px 100px;   /* высоты рядов    */
}
1 2 3 4
1 2 3 4
.container
{
    display: grid;
    grid-template-columns: 100px auto 100px; /* ширины столбцов */
    grid-template-rows: 100px 100px 100px;   /* высоты рядов    */
}
1 2 3 4
1 2 3 4
a
.container
{
    display: grid;
    grid-template-columns: 100px auto 100px; /* ширины столбцов */
    grid-template-rows: 100px 100px 100px;   /* высоты рядов    */
}
1 2 3 4
1 2 3 4
a
b
.container
{
    display: grid;
    grid-template-columns: 100px auto 100px; /* ширины столбцов */
    grid-template-rows: 100px 100px 100px;   /* высоты рядов    */
}
1 2 3 4
1 2 3 4
a
b
c
.container
{
    display: grid;
    grid-template-columns: 100px auto 100px; /* ширины столбцов */
    grid-template-rows: 100px 100px 100px;   /* высоты рядов    */
}
1 2 3 4
1 2 3 4
a
b
c
d
.container
{
    display: grid;
    grid-template-columns: 100px auto 100px; /* ширины столбцов */
    grid-template-rows: 100px 100px 100px;   /* высоты рядов    */
}
1 2 3 4
1 2 3 4
a
b
c
d
e
.a
{
    grid-row: 1 / 2;
    grid-column: 1 / 4;
}

1 2 3 4
1 2 3 4
a
b
c
d
e
.a
{
    grid-row: 1 / 2;
    grid-column: 1 / 4;
}

.b
{
    grid-row: 2 / 4;
    grid-column: 1 / 2;
}

1 2 3 4
1 2 3 4
a
b
c
d
e
.a
{
    grid-row: 1 / 2;
    grid-column: 1 / 4;
}

.b
{
    grid-row: ➩ 1 / 4;
    grid-column: 1 / 2;
}

1 2 3 4
1 2 3 4
a
b
c
d
e
.a
{
    grid-row: 1 / 2;
    grid-column: 1 / 4;
    ➩ z-index: 1;
}
.b
{
    grid-row: 1 / 4;
    grid-column: 1 / 2;
}
1 2 3 4
1 2 3 4
a
b
c
d
e

Размер дорожки можно указывать в fr – долях свободного места.

Свободное место вычисляется после расположения всех элементов фиксированных размеров.

.container
{
    display: grid;
    grid-template-columns: 100px 1fr 1fr;
    grid-template-rows: 100px 100px 100px;
}
1 2 3 4
1 2 3 4
a
b
c
d
e
.a
{
    grid-column: span 3;
}

    
1 2 3 4
1 2 3 4
a
b
c
d
e
.a
{
    grid-column: span 3;
}

    
.b
{
    grid-row: span 2;
}
1 2 3 4
1 2 3 4
a
b
c
d
e

В контейнере можно создавать именованные области с помощью свойства grid-template-areas.

Поместить элемент в область можно свойством grid-area.

.beach {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 100px 100px 100px;
    grid-template-areas: 'sand  water'
                         'sand  water'
                         'grass grass';
}
.a {
    grid-area: grass;
}
.b {
    grid-area: sand;
}
.c {
   grid-area: water;
}
a
b
c
.beach {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 100px 100px 100px;
    grid-template-areas: 'sand  water'
                         'sand  water'
                         '.     grass';
}
.a {
    grid-area: grass;
}
.b {
    grid-area: sand;
}
.c {
   grid-area: water;
}
a
b
c

Короче!

Свойство grid-template:

.container
{
    display: grid;
    grid-template: 'header  header'  100px
                   'sidebar content' 100px
                   'footer  content'  100px
                    / 100px auto;
}

Используя свойство grid-gap, можно управлять размером интервалов между линиями.

Интервал только между рядами — grid-row-gap, только между столбцами — grid-column-gap.

.container
{
    grid-column-gap: 1%;
    grid-row-gap: 16px;
}
a
b
c
d
e

12 колонок!

Писать руками?

.container
{
    grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr...;
}

НЕТ. Есть функция repeat()

.container
{
    grid-template-columns: repeat(12, 1fr);
}
caniuse.com/#feat=css-grid

Полезные ссылки


  1. Grid Explained In 7 Minutes
  2. Гайд по гриду
  3. Grid By Example
  4. Игра для изучения грида

Flexbox или grid?

Flexbox
.container
{
    display: flex;
}
.column-i
{
    flex: auto;
}
Grid
.container
{
    display: grid;
    grid-template-columns:
                1fr 1fr 1fr;
}
Flexbox

Grid

Flexbox
  • одно измерение
    — ряд или столбец
  • content-first
Grid
  • два измерения
    — ряды и столбцы
  • layout-first
Home
Logout
Flexbox
.header
{
    display: flex;
    align-items: center;
}


.logout
{
    margin-left: auto;
}
Grid
.header
{
    display: grid;
    grid-template-columns:
                repeat(10, 1fr);
}
.logout
{
    grid-column: 10;
}

Подходы можно совмещать

Подходы можно совмещать

HEADER
CONTENT
FOOTER

Подходы можно совмещать

.container
{
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    grid-template-rows: 50px 350px 50px;
}
.header
{
    display: flex;
    align-items: center;
}
.logout
{
    margin-left: auto;
}
.header,
.footer
{
    grid-column: span 12;
}
.menu
{
    grid-column: span 2;
}
.content
{
    grid-column: span 10;
}

Адаптивный дизайн

Медиа-выражения –

условное применение CSS-правил.

Одна разметка, разные наборы стилей.

Задаются с помощью at-правила @media, за которым следует условие:
Media Type задает тип устройства

  • all – все устройства (по умолчанию)
  • print — принтеры и режим предпросмотра
  • screen — устройства с экраном
  • speech — скринридеры
Media Features задают технические характеристики устройства

  • width – ширина вьюпорта
  • height — высота вьюпорта
  • orientation — ориентация вьюпорта
  • resolution — разрешение устройства вывода
и другие
Ширина вьюпорта
/* для мобильных */
body {
    background: red;
}

/* для планшетов */
@media screen and (min-width: 768px) {
    body {
        background: yellow;
    }
}

/* для десктопов */
@media screen and (min-width: 1280px) {
    body {
        background: blue;
    }
}

Полезные ссылки


  1. @media на MDN
  2. Responsive Design Tutorial

Итоги

  • Для раскладки одномерных элементов удобно применять flex
  • Для двумерных — grid
  • Совмещая эти подходы, можно сверстать всё, что угодно
  • И сделать адаптивно с помощью media-запросов

Спасибо!