Responsive design: сохранение формы элементов разметки

Одним из приемов адаптивного веб-дизайна является установка размеров элементов разметки
в процентах относительно размеров контейнера их содержащего. Тем самым достигается пропорциональное изменение размеров всех элементов при изменении размеров окна браузера. Если задаются только горизонтальные размеры, как, например, при верстке страницы, когда важно правильно разместить элементы по горизонтали, мы можем очевидным образом предсказать, каковы будут действительные горизонтальные размеры элементов. При этом однако, наверное, мы ничего заранее не можем сказать об их вертикальных размерах (конечно, если высоты не заданы явно). Отсюда вытекает следующая задача — как сохранять пропорции элементов?

Простой пример из практики. Страница состоит из трех колонок: левое вертикальное меню, картинка, правое вертикальное меню.

При изменении размеров окна картинка должна растягиваться (сжиматься), оставаясь в пространстве между левым и правым меню. В свою очередь пункты меню должны быть представлены квадратными областями, которые при изменении размеров окна должны оставаться квадратными:

image

Мы можем представить нашу страницу двумя неупорядоченными списками и изображением посредине:

<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%;
}

В результате страница будет выглядеть таким образом:



Изображение и меню будут изменять свои размеры при изменении размеров окна, однако
видно, что пункты меню не квадратные. Это естественно, потому что все, что мы сделали, — установили ширину меню в процентах, оставив установку высоты пунктов на откуп алгоритму отрисовки.

Можно, конечно, установить размеры пункта меню явным образом в абсолютных единицах. Они приобретут желаемую квадратную форму, однако верстка утратит адаптивные свойства. Просто указать высоту в процентах:

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%;
}

В результате высота растягиваемого элемента станет равной его ширине и пункты меню станут квадратными:



Чтобы добавить содержимое внутрь пункта меню, используем абсолютное позиционирование:

.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%);
}

В результате страница примет желаемый вид:



И самое главное — пункты меню останутся квадратными при изменении размеров окна.
  • +12
  • 4.8k
  • 3
Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 3

    +3

    И ради этого статью писать?
    Флоатами верстать в 2018 очень круто, а как вы текст по центру в % спозиционировали круто. Да и что-бы высоту динамическую сделать тоже костыль какой-то, попробуйте в гугле ввести: "css width = height", там более кратко напишут и правильно.

      +1
      Эмм… А почему не сверстать флексами задав пунктам меню размеры в пикселях?
      Ну или на крайний случай (хотя я и не понимаю зачем размеры кнопки делать резиновыми, а не адаптировать в зависимости от способа ввода) можно просто использовать единицы vw/vh.
        +1

        Зачем использовать float в 2018 году для создания колонок? Есть же flexbox, который намного более удобный, гибкий, поддерживается 99% аудитории и всеми современными браузерами.

        Only users with full accounts can post comments. Log in, please.