Responsive design: сохранение формы элементов разметки
Одним из приемов адаптивного веб-дизайна является установка размеров элементов разметки
в процентах относительно размеров контейнера их содержащего. Тем самым достигается пропорциональное изменение размеров всех элементов при изменении размеров окна браузера. Если задаются только горизонтальные размеры, как, например, при верстке страницы, когда важно правильно разместить элементы по горизонтали, мы можем очевидным образом предсказать, каковы будут действительные горизонтальные размеры элементов. При этом однако, наверное, мы ничего заранее не можем сказать об их вертикальных размерах (конечно, если высоты не заданы явно). Отсюда вытекает следующая задача — как сохранять пропорции элементов?
Простой пример из практики. Страница состоит из трех колонок: левое вертикальное меню, картинка, правое вертикальное меню.
При изменении размеров окна картинка должна растягиваться (сжиматься), оставаясь в пространстве между левым и правым меню. В свою очередь пункты меню должны быть представлены квадратными областями, которые при изменении размеров окна должны оставаться квадратными:
Мы можем представить нашу страницу двумя неупорядоченными списками и изображением посредине:
- menu 1
- menu 2
- menu 3
- menu 1
- menu 2
- menu 3
установив ширину списков по 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
В результате страница будет выглядеть таким образом:
Изображение и меню будут изменять свои размеры при изменении размеров окна, однако
видно, что пункты меню не квадратные. Это естественно, потому что все, что мы сделали, — установили ширину меню в процентах, оставив установку высоты пунктов на откуп алгоритму отрисовки.
Можно, конечно, установить размеры пункта меню явным образом в абсолютных единицах. Они приобретут желаемую квадратную форму, однако верстка утратит адаптивные свойства. Просто указать высоту в процентах:
тоже не является решением, потому что ширина и высота родительского элемента (а в нашем случае это body), как правило, не одинаковы.
Решение подобной задачи основывается на том отчасти парадоксальном факте, что отступы (paddings) внутри элемента разметки, если они выражены в процентах, рассчитываются относительно ширины этого элемента. Парадокс заключается в том, что данное утверждение справедливо не только в отношении горизонтальных отступов:
, но также и вертикальных отступов:
Следующее, что нам понадобится, — псевдоселектор ::after. Он добавит внутрь нашего растягиваемого по ширине элемента псевдоэлемент нулевой высоты. Если же мы зададим для этого псевдоэлемента padding-top или padding-bottom равным 100%, то значение отступа установится равным ширине родителя (растягиваемого элемента, — li в нашем случае).
.left-navigation li:after, .right-navigation li:after
В результате высота растягиваемого элемента станет равной его ширине и пункты меню станут квадратными:
Чтобы добавить содержимое внутрь пункта меню, используем абсолютное позиционирование:
.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
В результате страница примет желаемый вид:
И самое главное — пункты меню останутся квадратными при изменении размеров окна.
Как менять размер текста при изменении размера окна?
Для изменения размера текста веб-страницы совместно с окном браузера есть несколько методов. Рассмотрим наиболее популярные.
Использование единиц vw
Размер текста задаётся с помощью свойства font-size, в качестве значения можно указывать разные единицы — пиксели, пункты, миллиметры и др. Единица vw (от англ. viewport width — ширина области просмотра) соответствует 1% от ширины окна браузера, таким образом, при изменении этой ширины будет меняться и размер текста (пример 1).
Пример 1. Использование vw
Для педагогов
Результат данного примера показан на рис. 1.
Рис. 1. а — текст на широком окне; б — текст на узком окне
У единицы vw есть несколько недостатков — главное, что текст уменьшается пропорционально вместе с окном и в какой-то момент становится нечитаемым. Это будет особенно заметно на смартфонах, где ширина экрана меньше ширины мониторов. Чтобы установить минимальный размер текста можно воспользоваться функцией calc(), как показано в примере 2.
Пример 2. Использование calc()
Здесь мы смешиваем разные единицы — для заголовка rem и vw, для основного текста пиксели и vw. Использование calc() гарантирует, что текст не станет меньше указанного значения (для заголовка, к примеру, это 1rem).
Использование медиа-запросов
Поскольку единицы vw завязаны на ширину области просмотра, то при увеличении размера окна увеличивается и размер текста. Иногда требуется сделать наоборот — на маленьких экранах показывать большой текст, а на больших экранах, соответственно, маленький текст. Для этого применяются медиа-запросы, они меняют стиль элементов при определённой ширине окна браузера.
Сперва определяем стиль для больших экранов, затем с помощью конструкции @media screen and (max-width: 1024px) задаём стиль для экранов с шириной до 1024 пикселей. Внутри @media пишется размер текста под этот размер. При желании ниже добавляем ещё несколько @media с разными значениями max-width (пример 3).
Пример 3. Использование @media
Для педагогов
Размер текста в данном случае будет меняться не плавно, а ступенчато — при достижении указанной ширины окна размер текста уменьшается или увеличивается.
См. также
Как менять размер объектов при изменении размеров окна браузера?
Нужно сделать так, чтобы размер картинок изменялся при уменьшении размера окна браузера. Запутал сам себя.
max-width: 100%;
Картинки будут уменьшатся если не будут влезать в родительский элемент (размеры которого могут быть в процентах)
Гуглите так же responsive images
Картинки закрыты паролем, это раз.
h_ttp://jquery.page2page.ru/index.php5/Обработчик_или_источник_события_resize, это два.
Спасибо. Картики перезалил. Дело в том что хотелось бы решить проблему в CSS а не привязывать скрипты типа jquery.
а цель какая? если для того, чтобы не текла верстка, то можно сделать ступенчатое изменение, используя только css. Если нужно плавное изменение, то в голову только js приходит.
Почитайте про meta name=»viewport» или посмотрите, как этим пользуются в twitter bootstrap. Вот, например: bootstrap-ru.com/204/scaffolding.php — см. заголовок — динамический дизайн.
Как вариант, использовать в макете не сами изображения, а блочные элементы с нужными изображениями в фоне.
Есть замечательное CSS3 — волшебство background-size: contain , которое «масштабирует изображение с сохранением пропорций таким образом, чтобы картинка целиком поместилась внутрь блока».
Один нюанс — в блоке, естественно, должны быть заданы ширина и высота, причем, в процентах, что логично (нам же нужна резина, ведь так?).
Надеюсь, помог. 🙂