Layout

Лена Рашкован

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

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

Таблицы

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

Флоаты

float: left
float: left
float: left
float: left
float: left
float: left
clear: both
Раскладка на флоатах:
  • можно задавать размеры
  • переносятся
  • колонки не выравниваются по высоте
  • спецэффекты (схлопывание родителя)
    и хаки (clearfix)
  • перекрытие контента при переполнении

Инлайн-блоки

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

Флексбокс

flex = гибкий

Гибкие раскладки:
- управление распределением места
- мощные возможности для выравнивания

display: flex

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

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

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

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

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


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

flex-direction: row

по умолчанию


целовались студенты
распускались тюльпаны
чик-чирикало там и тут

flex-direction: row-reverse



целовались студенты
распускались тюльпаны
чик-чирикало там и тут

flex-direction: column

целовались студенты
распускались тюльпаны
чик-чирикало там и тут

flex-direction: column-reverse

целовались студенты
распускались тюльпаны
чик-чирикало там и тут

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

justify-content: flex-start

по умолчанию


целовались студенты
распускались тюльпаны
чик-чирикало там и тут

justify-content: flex-end


целовались студенты
распускались тюльпаны
чик-чирикало там и тут

justify-content: center


целовались студенты
распускались тюльпаны
чик-чирикало там и тут

justify-content: space-between


целовались студенты
распускались тюльпаны
чик-чирикало там и тут

justify-content: space-around


целовались студенты
распускались тюльпаны
чик-чирикало там и тут

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


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



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

align-items: stretch

по умолчанию


целовались студенты
распускались тюльпаны
чик-чирикало там и тут

align-items: flex-start


целовались студенты
распускались тюльпаны
чик-чирикало там и тут

align-items: flex-end


целовались студенты
распускались тюльпаны
чик-чирикало там и тут

align-items: center


целовались студенты
распускались тюльпаны
чик-чирикало там и тут

align-items: baseline


целовались студенты
распускались тюльпаны
чик-чирикало там и тут

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

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


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

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


целовались студенты
распускались тюльпаны
чик-чирикало там и тут

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



целовались студенты
распускались тюльпаны
чик-чирикало там и тут
я забрала документы
поругалась с деканом
мам, я бросила институт

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


целовались студенты
распускались тюльпаны
чик-чирикало там и тут
я забрала документы
поругалась с деканом
мам, я бросила институт
это мне сказал сделать

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

flex-wrap: nowrap wrap

целовались студенты
распускались тюльпаны
чик-чирикало там и тут
я забрала документы
поругалась с деканом
мам, я бросила институт
это мне сказал сделать
Слава, мой хороший друг
чемодан, вокзал, поезд
Москва – Екатеринбург

flex-wrap: wrap-reverse

целовались студенты
распускались тюльпаны
чик-чирикало там и тут
я забрала документы
поругалась с деканом
мам, я бросила институт
это мне сказал сделать
Слава, мой хороший друг
чемодан, вокзал, поезд
Москва – Екатеринбург

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

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

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

align-content: stretch

по умолчанию


целовались студенты
распускались тюльпаны
чик-чирикало там и тут
я забрала документы
поругалась с деканом
мам, я бросила институт
это мне сказал сделать
Слава, мой хороший друг
чемодан, вокзал, поезд
Москва – Екатеринбург

align-content: flex-start


целовались студенты
распускались тюльпаны
чик-чирикало там и тут
я забрала документы
поругалась с деканом
мам, я бросила институт
это мне сказал сделать
Слава, мой хороший друг
чемодан, вокзал, поезд
Москва – Екатеринбург

align-content: flex-end


целовались студенты
распускались тюльпаны
чик-чирикало там и тут
я забрала документы
поругалась с деканом
мам, я бросила институт
это мне сказал сделать
Слава, мой хороший друг
чемодан, вокзал, поезд
Москва – Екатеринбург

align-content: center


целовались студенты
распускались тюльпаны
чик-чирикало там и тут
я забрала документы
поругалась с деканом
мам, я бросила институт
это мне сказал сделать
Слава, мой хороший друг
чемодан, вокзал, поезд
Москва – Екатеринбург

align-content: space-between


целовались студенты
распускались тюльпаны
чик-чирикало там и тут
я забрала документы
поругалась с деканом
мам, я бросила институт
это мне сказал сделать
Слава, мой хороший друг
чемодан, вокзал, поезд
Москва – Екатеринбург

align-content: space-around


целовались студенты
распускались тюльпаны
чик-чирикало там и тут
я забрала документы
поругалась с деканом
мам, я бросила институт
это мне сказал сделать
Слава, мой хороший друг
чемодан, вокзал, поезд
Москва – Екатеринбург

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

align-content: stretch; align-items: center

целовались студенты
распускались тюльпаны
чик-чирикало там и тут
я забрала документы
поругалась с деканом
мам, я бросила институт
это мне сказал сделать
Слава, мой хороший друг
чемодан, вокзал, поезд
Москва – Екатеринбург

С помощью свойства 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

Как указать размер флекс-элемента?

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

Если не указать, то базовый размер возьмётся из ширины или высоты.

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

😑 0
😒 1
😎 2
width = 980px
flex-basis = 2×10px + 2×10px + 25px = 65px
  • free space = 980px - 3 × 65px = 785px
  • fraction = 785px / (0 + 1 + 2) = ~262px
  • final size1 = 65px + (262px × 0) = 65px;
  • final size2 = 65px + (262px × 1) = ~326px;
  • final size3 = 65px + (262px × 2) = ~589px;

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

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

flex-shrink: 1

по умолчанию


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

flex-shrink: 0


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

flex-shrink: 0


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

Хардкорный алгоритм расчёта

С помощью сокращённого свойства 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: 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: 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 = сетка

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

display: grid

грид-контейнер (grid-container)

грид-элемент (grid-item)

линия (grid-line)

ячейка (grid-cell)

область (grid-area)

дорожка (grid-track)

интервал (grid-gap)

Чтобы наполнить сетку колонками и рядами существуют свойства
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.

.container {
    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
.container {
    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. Игра для изучения грида

Флексбокс или грид?

Флексбокс
.container
{
    display: flex;
}
.column-i
{
    flex: auto;
}
Грид
.container
{
    display: grid;
    grid-template-columns:
                1fr 1fr 1fr;
}
Флексбокс
  • одно измерение
    — ряд или столбец
Грид
  • два измерения
    — ряды и столбцы
Флексбокс

Грид

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


.logout
{
    margin-left: auto;
}
Грид
.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
{
    grid-column: span 12;
}
.menu
{
    grid-column: span 2;
}
.content
{
    grid-column: span 10;
}
.footer
{
    grid-column: span 12;
}

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

Две новости

Используя флексбокс и грид,
можно сверстать всё что угодно

А таблицы пригодятся для вёрстки электронных писем

Про домашку

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

условное применение 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