Одним из приемов адаптивного веб-дизайна является установка размеров элементов разметки
в процентах относительно размеров контейнера их содержащего. Тем самым достигается пропорциональное изменение размеров всех элементов при изменении размеров окна браузера. Если задаются только горизонтальные размеры, как, например, при верстке страницы, когда важно правильно разместить элементы по горизонтали, мы можем очевидным образом предсказать, каковы будут действительные горизонтальные размеры элементов. При этом однако, наверное, мы ничего заранее не можем сказать об их вертикальных размерах (конечно, если высоты не заданы явно). Отсюда вытекает следующая задача — как сохранять пропорции элементов?
Простой пример из практики. Страница состоит из трех колонок: левое вертикальное меню, картинка, правое вертикальное меню.
При изменении размеров окна картинка должна растягиваться (сжиматься), оставаясь в пространстве между левым и правым меню. В свою очередь пункты меню должны быть представлены квадратными областями, которые при изменении размеров окна должны оставаться квадратными:
![image](https://habrastorage.org/r/w780q1/webt/yy/rz/gk/yyrzgkwwczb98zethyy9g8eiklq.jpeg)
Мы можем представить нашу страницу двумя неупорядоченными списками и изображением посредине:
установив ширину списков по 4%:
и картинки 92%:
В результате страница будет выглядеть таким образом:
![](https://habrastorage.org/r/w780q1/webt/eq/a2/xa/eqa2xakxoo92lbpicgww98v9wzu.jpeg)
Изображение и меню будут изменять свои размеры при изменении размеров окна, однако
видно, что пункты меню не квадратные. Это естественно, потому что все, что мы сделали, — установили ширину меню в процентах, оставив установку высоты пунктов на откуп алгоритму отрисовки.
Можно, конечно, установить размеры пункта меню явным образом в абсолютных единицах. Они приобретут желаемую квадратную форму, однако верстка утратит адаптивные свойства. Просто указать высоту в процентах:
тоже не является решением, потому что ширина и высота родительского элемента (а в нашем случае это body), как правило, не одинаковы.
Решение подобной задачи основывается на том отчасти парадоксальном факте, что отступы (paddings) внутри элемента разметки, если они выражены в процентах, рассчитываются относительно ширины этого элемента. Парадокс заключается в том, что данное утверждение справедливо не только в отношении горизонтальных отступов:
, но также и вертикальных отступов:
Следующее, что нам понадобится, — псевдоселектор ::after. Он добавит внутрь нашего растягиваемого по ширине элемента псевдоэлемент нулевой высоты. Если же мы зададим для этого псевдоэлемента padding-top или padding-bottom равным 100%, то значение отступа установится равным ширине родителя (растягиваемого элемента, — li в нашем случае).
В результате высота растягиваемого элемента станет равной его ширине и пункты меню станут квадратными:
![](https://habrastorage.org/r/w780q1/webt/n3/eg/ow/n3egowrobf5slpaaqijntvttskq.jpeg)
Чтобы добавить содержимое внутрь пункта меню, используем абсолютное позиционирование:
В результате страница примет желаемый вид:
![](https://habrastorage.org/r/w780q1/webt/pf/ka/uc/pfkauc_a-fssd9nie0xmc4bgj6q.jpeg)
И самое главное — пункты меню останутся квадратными при изменении размеров окна.
в процентах относительно размеров контейнера их содержащего. Тем самым достигается пропорциональное изменение размеров всех элементов при изменении размеров окна браузера. Если задаются только горизонтальные размеры, как, например, при верстке страницы, когда важно правильно разместить элементы по горизонтали, мы можем очевидным образом предсказать, каковы будут действительные горизонтальные размеры элементов. При этом однако, наверное, мы ничего заранее не можем сказать об их вертикальных размерах (конечно, если высоты не заданы явно). Отсюда вытекает следующая задача — как сохранять пропорции элементов?
Простой пример из практики. Страница состоит из трех колонок: левое вертикальное меню, картинка, правое вертикальное меню.
При изменении размеров окна картинка должна растягиваться (сжиматься), оставаясь в пространстве между левым и правым меню. В свою очередь пункты меню должны быть представлены квадратными областями, которые при изменении размеров окна должны оставаться квадратными:
![image](https://habrastorage.org/webt/yy/rz/gk/yyrzgkwwczb98zethyy9g8eiklq.jpeg)
Мы можем представить нашу страницу двумя неупорядоченными списками и изображением посредине:
<ul class="left-navigation">
<li>
menu 1
</li>
<li>
menu 2
</li>
<li>
menu 3
</li>
</ul>
<div class="picture">
<img src="img/fox.jpg">
</div>
<ul class="right-navigation">
<li>
menu 1
</li>
<li>
menu 2
</li>
<li>
menu 3
</li>
</ul>
установив ширину списков по 4%:
.left-navigation, .right-navigation {
width: 4%;
list-style: none;
float: left;
padding-left: 0;
margin: 0;
}
.right-navigation {
float: right;
}
.left-navigation li, .right-navigation li {
border: 1px solid black;
cursor: pointer;
}
и картинки 92%:
.picture {
box-sizing: border-box;
padding: 30px;
width: 92%;
float: left;
}
.picture img {
width: 100%;
}
В результате страница будет выглядеть таким образом:
![](https://habrastorage.org/webt/eq/a2/xa/eqa2xakxoo92lbpicgww98v9wzu.jpeg)
Изображение и меню будут изменять свои размеры при изменении размеров окна, однако
видно, что пункты меню не квадратные. Это естественно, потому что все, что мы сделали, — установили ширину меню в процентах, оставив установку высоты пунктов на откуп алгоритму отрисовки.
Можно, конечно, установить размеры пункта меню явным образом в абсолютных единицах. Они приобретут желаемую квадратную форму, однако верстка утратит адаптивные свойства. Просто указать высоту в процентах:
width: 4%;
height: 4%;
тоже не является решением, потому что ширина и высота родительского элемента (а в нашем случае это body), как правило, не одинаковы.
Решение подобной задачи основывается на том отчасти парадоксальном факте, что отступы (paddings) внутри элемента разметки, если они выражены в процентах, рассчитываются относительно ширины этого элемента. Парадокс заключается в том, что данное утверждение справедливо не только в отношении горизонтальных отступов:
padding-left, padding-right
, но также и вертикальных отступов:
padding-top, padding-bottom
Следующее, что нам понадобится, — псевдоселектор ::after. Он добавит внутрь нашего растягиваемого по ширине элемента псевдоэлемент нулевой высоты. Если же мы зададим для этого псевдоэлемента padding-top или padding-bottom равным 100%, то значение отступа установится равным ширине родителя (растягиваемого элемента, — li в нашем случае).
.left-navigation li:after, .right-navigation li:after {
content: '';
display: block;
padding-bottom: 100%;
}
В результате высота растягиваемого элемента станет равной его ширине и пункты меню станут квадратными:
![](https://habrastorage.org/webt/n3/eg/ow/n3egowrobf5slpaaqijntvttskq.jpeg)
Чтобы добавить содержимое внутрь пункта меню, используем абсолютное позиционирование:
.left-navigation li a, .right-navigation li a {
position: absolute;
margin-left: 2%;
margin-top: 2%;
}
.left-navigation li a img, .right-navigation li a img{
transform: translate(-50%, -50%);
}
В результате страница примет желаемый вид:
![](https://habrastorage.org/webt/pf/ka/uc/pfkauc_a-fssd9nie0xmc4bgj6q.jpeg)
И самое главное — пункты меню останутся квадратными при изменении размеров окна.