Как найти class container

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

Предыдущая статья

Пользовались ли вы Flexbox до этого? Если да, то это просто отлично. В Flexbox его контекст форматирования НЕ инициализируется до тех пор, пока не будет создан flex-container.

В принципе не важно есть ли у вас опыт использования Flexbox или нет, в Bootstrap должен быть определён элемент container для того, чтобы использовать все преимущества отзывчивого дизайна, предлагаемого Bootstrap-ом.

Итак, что же такое Bootstrap-контейнер?

Контейнер – это простой элемент, который имеет класс .container.

К примеру:

<div class="container">
</div>
Очень просто, не так ли?

В простой разметке лучше всего обернуть каждый элемент в bootstrap-контейнер. Для примера, я произведу рефакторинг «Поэмы про кроликов», используя Bootstrap-контейнер.

<div class="container">  
  <h1> Bunnie Poems </h1>
  <p class="lead"> The following is a mostly unintelligent poem about Bunnies. 
                   Don't think too hard about them. <br /> Enjoy!
  </p><h2 class="display-5"> The Bunnie Who Had No Ears </h2>
  <p> Mr Bunnie. How big the ears of your ancestors </p>
  <p> How fluffy the pride of your family </p>
  <p class="display-4"> But, wait... </p>
  <p class="text-center">How is it that you have no ears </p>
  <p> With your eyes you hear, and your nose you see? </p>
  <p class="font-weight-bold"> How sad, Mr Bunny </p>
  <p class="font-italic">See him hop, hop, hop about on legs so very strong.</p>
  <strong class="font-weight-normal"> But ears, he has none </strong>
  <p> Live long, and make your ancestors proud </p>
  <p class="text-capitalize">We believe in you</p>
  <blockquote class="blockquote">
    Men have ears. Men have Noses. Men have Mouths.We do too. We are Bunnies
    <div class="blockquote-footer">Ohans Bunny </div>
  </blockquote>
  ...
</div>

Как можно увидеть из примера кода выше, я обернул КАЖДЫЙ элемент в элемент div, содержащим класс .container.

<div class="container">
    <!—все остальные элементы размещаются здесь -->
</div>

В чем разница между классами container и container-fluid?

В примере выше, я сделал следующее:

<div class="container">
    <!—все остальные элементы размещаются здесь -->
</div>

Хоть это и верно, однако есть еще один класс контейнера, который предоставляется Bootstrap-ом, а именно .container-fluid.

Использование этого класс точно такое же:

<div class="container-fluid">
    <!—все остальные элементы размещаются здесь -->
</div>

Тогда, в чем же разница?

Давайте обратимся к визуальным примерам.

Я всегда задавался вопросом почему же я не понял разницы между этими классами, когда я начинал изучать структуру Bootstrap несколько лет назад. Вам в этом вопросе повезло, так как я во всем разобрался и готов вам все объяснить.

Для получения фидбека от визуальных примеров, я к уже привычному нам примеру добавлю красный задний фон. Также я добавлю белый задний фон для классов .container и .container-fluid. Только потому что они не наследуют красный задний фон от body.

Ниже представлен необходимый код:

body {
  background: red
}
.container,
.container-fluid {
  background: white
}

Теперь давайте посмотрим в чем заключается разница, если вы обернете всё содержание «Поэмы про кроликов» в div, который содержит класс .container.

А сейчас попробуйте изменить размер вашего окна браузера. Что вы заметили?

Bootstrap

Вы должны были заметить, что ширина .container изменяется в зависимости от размера окна. Тем самым, остаются небольшие области между самим контейнером и телом сайта (body). Этот эффект как раз и видно из гифки выше, так как вы можете наблюдать красные полосы. Вы же не забыли, что наш элемент body имеет красный задний фон.

Может показаться, что это довольно просто, однако не стоит забывать о важности подобного поведения.

И совсем наоборот ведет себя класс .container-fluid. Его использование приводит к тому, что div с данным классом заполняет все доступное пространство, в момент, когда вы изменяете размер окна. Из примера ниже можно увидеть, что красных полос больше нет, то есть отсутствует пространство между телом сайта (body) и контейнером. Контейнер занимает все доступное место.

Как можно видеть, использование класса .container-fluid оставляет вас без этого роскошного пространства по бокам. Контейнер занимает 100% доступного пространства (width 100%). По-прежнему имеется небольшой внутренний отступ, применяемы к элементу с классом .container-fluid, однако ширина не становится больше и не изменяется в зависимости от размеров окна пользователя. В этом и заключается разница между классами .container и .container-fluid.

Что такое мультимедийные запросы?

Поскольку данный раздел посвящён отзывчивому дизайну, то я думаю, что немало важным будет освежить знания о мультимедийных запросах, особенно это касается новичков. Кроме того, раздел важен для понимания того, как работают модули, отвечающие за отзывчивый дизайн в Bootstrap.

Рассмотрим блок кода ниже:
@media screen and (min-width: 768px) {
     .bg {
         background-color: blue
     }
}

Если вам знакомо написание вручную отзывчивых модулей, то блок кода выше должен быть понятен. Данный блок кода показывает то, как надо использовать мультимедийные CSS-запросы. Если у вас нет представления как это работает, то продолжайте читать.

Мультимедийные запросы – это «сердце» отзывчивого дизайна. Они позволяют вам настроить определённый размер экрана и указать код, который будет выполняться только на определённых устройствах.

Наиболее популярным способом использования мультимедийных запросов является @media-правило. Выглядит это следующим образом:

@media screen and (min-width: 300px) {
  /*создавайте свой css в этом блоке кода*/
}
Глядя на этот пример, вы можете догадываться что он делает.

«Для устройств с минимальной шириной экрана равной 300px … делай это и это»

Любые CSS-стили, определённые в данном блоке, будут применены только к тем устройствам, которые подходят под описание: «screen and (min-width: 300px).» В приведённом выше примере ширина равная 300px является контрольной точкой.

Думаю, это помогло прояснить некоторую путаницу.

Что такое решётчатая система Bootstrap?

В Bootstrap или любой другой хорошо организованной структуре, ничего просто так не располагается на странице. Каждый элемент располагается на своем определенном месте в решётчатой структуре.

Как мы можем видеть, решётчатая структура представляет собой набор пересекающих друг друга вертикальных и горизонтальных линий, которые используются для структурирования контента на веб-странице.

Никто не размещает контент как попало на странице.

Посмотрите на то, как хаотично размещен контент на примере выше. Вы когда-либо видели, чтобы контент был размещен так? Держу пари «нет».

В большинстве случаев вы сталкиваетесь с хорошо структурированным контентом. Что-то вроде такого:

Внимательно размешайте контент на странице. А чтобы вам было проще, то в Bootstrap предусмотрена своя решётчатая система, позволяющая грамотно размещать содержимое вашего будущего сайта.

Для более опытных пользователей, важно отметить, что вам не нужны горизонтальные или вертикальные линии этой системы. Благодаря CSS-сетки с небольшими вкраплениями магии CSS, вы с легкостью сможете создать альтернативную разметку.

Как мне использовать Bootstrap-сетку?

Решётчатая система Bootstrap 4 создана с помощью Flexbox, что делает еще более мощной чем когда-либо.

Предостережение: данная часть Bootstrap-а скорее всего вам будет не понятна после первого прочтения. Однако, если вы потратите время и хорошо разберетесь с устройством решётчатой системы Bootstrap, то вы найдете это знание одним из наиболее важных из всего того, что вы знаете о Bootstrap.

Позвольте мне объяснить, как это работает.

Ну что ж представим, что вам в полночь звонит ваш подруга Хлоя и говорит: «Я собираюсь выйти замуж!..хаха»

Вы оба находитесь в состоянии сильного удивления, после такой-то новости, и разговариваете дольше чем могли ожидать. Только к концу разговора вы решили действовать как крутой разработчик. «Так Хлоя, я хочу создать тебе сайт для твоей свадьбы!» И вы разговариваете еще 30 минут…

Прекрасная история.

Хорошая новость в том, что вы сделали эту ночь для Хлои. Она будет очень рада. Плохая новость (или не очень плохая новость) в том, что вам придется потратить время и свою энергию (и немного кофе) чтобы создать сайт для свадьбы.

Итак, у вас есть примерно вот такой макет:

Сразу оговорю, что я создал этот макет только для данной статьи, не судите строго. Вернемся к нашей истории.

У вас нет времени на построение такого сайта, поэтому вы решаете использовать Bootstrap. Что в первую очередь необходимо сделать? Настроить сетку Bootstrap.

Существует несколько строгих правил, которые необходимо соблюдать во время использования решётчатой системы Boostrap.

Во-первых, вернитесь к макету и мысленно разбейте его содержимое на отдельные ряды. Можете это сделать?

Я проделал тоже самое и вот что у меня получилось:

Все что я сделал – это нарисовал прямоугольники, включающие в себя разный контент страницы и являющиеся рядами. Для более сложных макетов подобное разделение на ряды или области – очень важно.

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

Это еще не конец. Внутри каждого ряда есть отдельные блоки с контентом. Посмотрите на предыдущее изображение и попробуйте выделить эти блоки.

И вновь я сделал тоже самое, что и вы. Посмотрите на результат:

Данные блоки с контентом называются колонки. Все поняли?

Колонки обозначаются классом .col.

Поскольку ряды и колонки отличные «друзья», то колонки не должны существовать вне рядов. Запомните это важное правило. Также каждый ряд должен быть помещён внутрь контейнера. Это может быть как .container, так и .container-fluid. Ряды не могут существовать вне контейнера, то есть всегда должны находиться.

На практике у вас может быть один общий контейнер, в котором будут располагаться все ряды, примерно так:

Как мы видим все ряды располагаются внутри красного контейнера. Кроме того, у вас может быть контейнера для каждого ряда в отдельности, примерно так:

Мне больше нравится последний вариант, так как я считаю его более гибким в решениях определенных задач.

Промежуточные итоги: Каждый ряд должен находиться внутри контейнера. Ряды определены классом .row, а колонки классом .col. Контейнером может быть как класс .container, так и класс .container-fluid.

Это основа того, как работает решётчатая система Bootstrap. В следующих разделах я расскажу о некоторых её практических применениях.

Что делать с колонками разного размера?

При построении веб-приложений очень вероятно, что вам понадобятся колонки разной ширины. Практически везде можно встретить колонки разной ширины внутри рядов.

Ниже приведен пример таких колонок:

Одна из колонок может занимать 60% ширины ряда, а другая 40%. Однако, как это взаимосвязано с использованием Bootstrap-сетки?

В Bootstrap-сетке предусмотрено разбиение на 12 колонок. То есть внутри каждого ряда теоретически может быть до 12 колонок включительно. Сколько каждая из 12 колонок будет занимать места в ряду, зависит только от ваших предпочтений.

Позвольте объяснить.

Давайте более внимательно рассмотрим этот пример:

Данный ряд содержит две колонки разного размера. Как уже было сказано, Bootstrap-сетка предусматривает разбиение на 12 колонок в одном ряду, выглядит это следующим образом:

То как распределять пространство между колонками, это уже дело ваше. Поскольку в нашем случае есть только две пользовательские колонки (большая и меньшая), то вам необходимо распределить между ними все пространство. Примерно так:

Как видно из примера из пространства первых 8 колонок у нас получилась наша большая колонка, а из оставшихся 4 получилась маленькая колонка. Очень просто и вы очень быстро к этому привыкните. Но обратите внимание, что сумма всех колонок должна равняться 12.

Запомните, что сумма всех колонок не должна превышать двенадцати. В примере выше, мы использовали классы col-8 и col-4. Как уже можно было догадаться, col-8 представляет собой большую колонку и эквивалентен восьми Bootstrap-колонкам. Собственно, col-4 в нашем случае это маленькая колонка, которая эквивалентна четырём Bootstrap-колонкам.

Получается, что в нашем случае будет две колонки ширина, одной из которых в два раза больше другой. Запомните, 8 / 4 = 2.

Если же вы хотите две одинаковые колонки, то используйте два раза класс col-6. Это создаст две колонки, каждая из которых будет занимать половину от 12 колонок Bootstrap-сетки.

Кроме того, вы можете создать две колонки, одна из которых будет в разы больше другой. Для этого используйте классы col-10 и col-2.

Я более чем уверен, что у вас с этим проблем не будет.

Что произойдет если у меня будет больше 12 колонок?

Если количество ваших колонок превысит 12, то они просто будут перенесены на следующий ряд. Точно также работает класс flex-wrap.

К примеру:

<section>
  <div class="container">
    <div class="row">
      <div class="col-3">
      </div>
      <div class="col-3">
      </div>
      <div class="col-3">
      </div>
      <div class="col-3">
      </div>
    </div>
  </div>
</section>
Зная то, как работает Bootstrap-сетка вы ожидаете увидеть следующий результат:

Как мы можем видеть это 4 колонки, которые и будут нашим результатом. Однако, если добавить еще 2 колонки, то что произойдет?

<section>
  <div class="container">
    <div class="row">
      <div class="col-3">
      </div>
      <div class="col-3">
      </div>
      <div class="col-3">
      </div>
      <div class="col-3">
      </div>
      <div class="col-3">
      </div>
      <div class="col-3">
      </div>
    </div>
  </div>
</section>
Результатом превышения количества колонок будет следующим:

Это хорошо, но что по поводу применения сетки в отзывчивом дизайне?

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

Например, использование col-8 и col-4 создаст две колонки внутри ряда. Это будет работать как на мобильных устройствах, так и на устройствах с более большим экраном.

Однако в рамках отзывчивого дизайна такое работает редко. Если на вашем планшете имеется сетка из двух колонок, то вы у вас может появится желание, чтобы на мобильном устройстве было также.

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

На мобильном устройстве колонки размещаются одна под другой, то есть вертикально. Как и на планшете, на мобильном устройстве колонки занимают 100% доступной ширины.

Также возможны ситуации, когда вам на десктопном устройстве понадобится 3 колонки, а на планшете нужно будет отображать только 2, и 1 на мобильном устройстве. В этом случае вам необходимо будет скрыть те колонки, которые вы не хотите, чтобы отображались на более небольших устройствах.

К счастью в Bootstrap и на такой случай есть решение!

Bootstrap-колонки могут быть модифицированы с помощью следующих модификаторов:

  • col-sm предназначен для маленьких устройств (телефонов) и выше;
  • col-md предназначен для средних устройств (планшетов) и выше;
  • col-lg предназначен для больших устройств (десктопов) и выше;
  • col-xl предназначен для очень больших устройств (широкие экраны).

Давайте вернёмся назад к примеру с двумя колонками. Нам необходимо, чтобы на планшетах (и выше) также было две колонки, но на мобильных устройствах колонки должны также оставаться горизонтально, а не вертикально.

Как нам это сделать?

Начнем с простой разметки:

<div class="row">
    <div></div>
    <div></div>
</div>

Я предположил, что этот ряд будет помещен в контейнер, так как запомните – каждый ряд должен быть помещён в контейнер.

Bootstrap ориентирован в первую очередь на мобильные устройства. Следовательно, вы сперва должны думать о построении дизайна на мобильном устройстве, а затем уже продвигаться к большим девайсам.

По этой причине сначала мы разберемся с отображением на мобильных устройствах.
<div class="row">
    <div class="col-12"></div>
    <div class="col-12"></div>
</div>

В разметке выше создается две колонки, которые занимают всю доступную ширину внутри ряда. Колонки будут размещены вертикально и займут 100% ширины.

Это не то поведение, которого мы хотим добиться от средних устройств (планшетов), поэтому мы добавим классы-модификаторы:

<div class="row">
    <div class="col-12 col-md-6"></div>
    <div class="col-12 col-md-6"></div>
</div>
Вы видите?

Обратите внимание, что для самых маленьких устройств нет необходимости в классе-модификаторе.

Теперь на средних устройствах и выше ряд будет иметь ширину равную двум колонкам. Каждая из этих колонок займет по 6 колонок Bootstrap-сетки.

Как это работает?

В Bootstrap реализованы мультимедийные запросы с определёнными контрольными точками для решения всех нужд отзывчивого дизайна. Диапазон, который охватывает Bootstrap это практически все современные устройства от совсем небольших мобильных устройств до ноутбуков и даже больших настольных компьютеров.

Как в случае с внешним и внутренним отступами, так и для определенных размеров экрана пользователя существуют свои классы.

Как видно из изображения выше, xs относится очень маленьким устройствам, sm к просто маленьким устройствам, md к средним устройствам, lg к большим устройствам, к примеру, ноутбукам, и xl относится к очень большим устройствам таким, как настольные компьютеры.

Для самых любознательных далее приведу пояснение мультимедийных запросов в Bootstrap:
// очень маленькие устройства (размер экрана меньше 576px)
// Для этого мультимедийный запрос не нужен, Bootstrap по умолчанию поддерживает // данный режим

// маленькие устройства (размер экрана от 576px и выше)
@media (min-width: 576px) { ... }

// средние устройства (размер экрана от 768px и выше)
@media (min-width: 768px) { ... }

// большие устройства (размер экрана от 992px и выше)
@media (min-width: 992px) { ... }

// очень большие устройства (размер экрана от 1200px и выше)
@media (min-width: 1200px) { ... }

Если вы считаете себя опытным пользователем, то взгляните на документации по четвертой и третьей версии. Обратите внимание на различие между контрольными точками в решётчатой системе. Я потратил некоторое количество времени на это. Так что, не поленитесь и сделайте тоже самое.

Что из себя представляет min-width?

Вы, наверное, заметили, что в мультимедийных запросах Bootstrap-а используется min-width. Также могли заметить, что я в своих примерах использовал фразу «средние устройства и выше».

Например, col-md предназначен для средних устройств (планшетов) и выше. Поэтому если вы зададите 8 колонок для средних устройств используя col-md-8, то устройства большего размера также будут иметь 8 колонок. Вам не нужно отдельно для таких устройств прописывать col-lg-8 и col-xl-8.

Такое поведение обусловлено использованием min-width внутри мультимедийных запросов Bootstrap.

// Средние устройства (планшеты, размер экрана 768px и выше)
@media (min-width: 768px) { ... }

Данный блок кода говорит нам о том, что: «для устройств с мимнимальной шириной 768px …».  Такой запрос охватывает все устройства с размером экрана больше 768px.

Могу ли я изменять Bootstrap-классы, отвечающие за определённые размеры экрана?

Да, такое можно реализовать, но не для всех Bootstrap-классов. Рассмотрим, например, класс отвечающий за стилизацию текста. Вот хотите вы, чтобы ваш текст был немного смещен в центр и только на мобильных устройствах, как это сделать?

Используйте класс text-sm-center к желаемому блоку текста:

      <p class="text-sm-center">How is it that you have no ears </p>

Наш текст «How is that you have no ears» будет абсолютно нормально отображен на всех устройствах, кроме мобильных девайсов. На данных устройствах текст будет немного смещен по центру.

Промежуточные итоги

Это был очень поучительный и познавательный раздел. Если до этого у вас было слабое представление о Bootstrap, то сейчас вы должны быть более уверены в том, как работает этот фреймворк. Если же вы тёртый калач, то скорее всего видели все эти новые возможности, которые привнесла эта версия Bootstrap. Также вы должны были в таком случае выявить все различия версий.

В следующем разделе мы перейдем к практике. Мы рассмотрим другие техники, различные хитрые приемы и новые «сладкие» фичи данного фреймворка на практических примерах.

Следующая статья

Дополнительные материалы по теме

  • Лучшие шпаргалки для веб-разработчиков
  • Объяснение современного JavaScript для динозавров
  • 16 cовременных ресурсов для обучения основам вёрстки

Ссылка на оригинальную статью
Перевод: Александр Давыдов

На этой странице


Как это работает

Контейнеры являются самым основным элементом макета в Bootstrap и необходимы при использовании нашей сеточной системы по умолчанию. Контейнеры используются для содержания, заполнения и (иногда) центрирования содержимого внутри них. Хотя контейнеры могут быть вложенными, для большинства макетов вложенный контейнер не требуется.

Bootstrap поставляется с тремя разными контейнерами:

  • .container, который устанавливает max-width для каждой контрольной точки
  • .container-{breakpoint}, который равен width: 100% до указанной контрольной точки
  • .container-fluid, который равен width: 100% во всех контрольных точках

В приведенной ниже таблице показано, как max-width каждого контейнера сравнивается с исходными .container и .container-fluid для каждой контрольной точки.

Посмотрите их в действии и сравните их в нашем примере сетки.

Extra small
Extra small

<576px

Small
Small

≥576px

Medium
Medium

≥768px

large
Large

≥992px

Extra large
X-Large

≥1200px

Extra Extra large
XX-Large

≥1400px

.container 100% 540px 720px 960px 1140px 1320px
.container-sm 100% 540px 720px 960px 1140px 1320px
.container-md 100% 100% 720px 960px 1140px 1320px
.container-lg 100% 100% 100% 960px 1140px 1320px
.container-xl 100% 100% 100% 100% 1140px 1320px
.container-xxl 100% 100% 100% 100% 100% 1320px
.container-fluid 100% 100% 100% 100% 100% 100%

Контейнер по умолчанию

Наш класс .container по умолчанию является адаптивным контейнером фиксированной ширины, что означает, что его максимальная ширина изменяется в каждой контрольной точке.

<div class="container">
  <!-- Контент здесь -->
</div>

Адаптивные контейнеры

Адаптивные контейнеры позволяют Вам указать класс шириной 100% до достижения указанной контрольной точки, после чего мы применяем max-width для каждой из более высоких контрольных точек. Например, .container-sm имеет 100% ширину для начала до тех пор, пока не будет достигнута контрольная точка sm, где он будет масштабироваться с помощью md, lg, xl и xxl.

<div class="container-sm">100% шириной до контрольной точки small</div>
<div class="container-md">100% шириной до контрольной точки medium</div>
<div class="container-lg">100% шириной до контрольной точки large</div>
<div class="container-xl">100% шириной до контрольной точки extra large</div>
<div class="container-xxl">100% шириной до контрольной точки extra extra large</div>

Подвижные контейнеры

Используйте .container-fluid для контейнера полной ширины, охватывающего всю ширину области просмотра.

<div class="container-fluid">
  ...
</div>

Sass

Как показано выше, Bootstrap генерирует серию предопределенных контейнерных классов, чтобы помочь Вам создать желаемые макеты. Вы можете настроить эти предопределенные классы контейнеров, изменив карту Sass (находится в _variables.scss), которая их поддерживает:

$container-max-widths: (
  sm: 540px,
  md: 720px,
  lg: 960px,
  xl: 1140px,
  xxl: 1320px
);

Помимо настройки Sass, Вы также можете создавать свои собственные контейнеры с помощью нашего миксина Sass.

// Исходный миксин
@mixin make-container($padding-x: $container-padding-x) {
  width: 100%;
  padding-right: $padding-x;
  padding-left: $padding-x;
  margin-right: auto;
  margin-left: auto;
}

// Применение
.custom-container {
  @include make-container();
}

Для получения дополнительной информации и примеров того, как изменить наши карты и переменные Sass, обратитесь к разделу Sass документации Сеток.

Введение в контейнерные запросы CSS

От автора: прототип долгожданных контейнерных запросов CSS добавлен в Chrome Canary и доступен для экспериментов. Давайте рассмотрим, какую проблему они решают, узнаем, как работают, и посмотрим, как они дополняют существующие функции CSS.

В настоящее время контейнерные запросы можно использовать в Chrome Canary, выполнив поиск и включив их в chrome://flags. (Потребуется перезагрузка браузера).

Введение в контейнерные запросы CSS

Просмотр результатов поиска в Chrome Canary на экране настроек chrome: // flags, на котором отображается элемент «Включить контейнерные запросы CSS» со статусом «Включено».

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

Профессия Frontend-разработчик PRO

Готовим Frontend-разработчиков с нуля

На курсе вы научитесь создавать интерфейсы веб-сервисов с помощью языков программирования и
дополнительных технологий. Сможете разрабатывать планировщики задач, мессенджеры, интернет-магазины…

Узнать подробнее

До 10 проектов в портфолио для старта карьеры

Подходит для новичков без опыта в программировании

Практика на вебинарах с разработчиками из крупных компаний

Какую проблему решают контейнерные запросы CSS?

Почти 11 лет назад Итан Маркотт познакомил нас с концепцией адаптивного дизайна. Центральным элементом этой идеи была доступность медиа-запросов CSS, которые позволяли устанавливать различные правила в зависимости от размера области просмотра. IPhone был представлен тремя годами ранее, и мы все пытались понять, как работать в этом новом мире, где нужно учитывать как размеры экрана мобильных устройств, так и размеры экрана монитора компьютера (которые в среднем были намного меньше, чем сегодня).

До и даже после внедрения адаптивного дизайна многие компании решали проблему изменения макета в зависимости от размера экрана, предоставляя совершенно разные сайты, часто на поддомене «m». Адаптивный дизайн и медиа-запросы открыли множество других решений для макетов и многолетнюю разработку передовых методов реагирования на размеры области просмотра. Кроме того, популярность таких фреймворков, как Bootstrap, выросла в основном благодаря предоставлению разработчикам адаптивных систем сетки.

В последнее время стали популярными дизайн-системы и библиотеки компонентов. Также есть желание написать один раз и развернуть где угодно. Это означает, что компонент, разработанный изолированно, предназначен для работы в любом количестве контекстов, чтобы сделать создание сложных интерфейсов более эффективным и согласованным.

В какой-то момент эти компоненты объединяются, чтобы создать веб-страницу или интерфейс приложения. В настоящее время, с медиа-запросами, часто используется дополнительный уровень для управления мутациями компонентов при изменении области просмотра. Как упоминалось ранее, распространенным решением является использование вспомогательных классов для наложения системы сеток, таких как фреймворки на подобе Bootstrap. Но эти служебные классы являются исправлением ограничений медиа-запросов и часто приводят к трудностям для вложенных макетов сетки. В таких ситуациях вам, возможно, придется добавить много служебных классов, но при этом не получить наиболее идеального представления.

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

Контейнерные запросы выводят нас за рамки рассмотрения только области просмотра и позволяют любому компоненту или элементу реагировать на определенную ширину контейнера. Таким образом, хотя вы все еще можете использовать адаптивную сетку для общего макета страницы, компонент в этой сетке может определять свои собственные изменения в поведении, запрашивая свой контейнер. Затем он может настроить свои стили в зависимости от того, отображается ли он в узком или широком контейнере.

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

С помощью контейнерных запросов вы можете очень точно и предсказуемо определить полный диапазон стилей компонента. Возможно, вы хотите увеличить или уменьшить отступ, изменить размер шрифта, добавить или удалить фоновые изображения или полностью изменить свойство отображения и ориентацию дочерних элементов.

Скоро мы рассмотрим другие примеры, но сначала давайте узнаем, как создать контейнерный запрос!

Начало работы с контейнерными запросами CSS

Первое, что нужно знать о контейнерных запросах CSS, это то, что «контейнеры» — это запрашиваемые элементы , а правила внутри запросов контейнера влияют только на потомков контейнера. Другими словами — вы можете определить main как контейнер, или, возможно, article или даже как элементы списка. Затем контейнерные запросы позволят определить правила того, как элементы в них меняются в зависимости от размера контейнера.

В текущем экспериментальном прототипе есть одно свойство, необходимое для определения элемента как контейнера, и это свойство contain. Оно может измениться как с точки зрения того, какие значения используются, так и с точки зрения возможности введения нового свойства вместо него, чтобы помочь определить ограничение размера.

Свойство contain принимает одно или несколько значений, и имеет все большую поддержку для начального сочетания размеров макета. Значение layout создает контекст форматирования блока , который будет содержать необходимые поля, чтобы его содержимое не влияло на содержимое в другом контейнере. Значение size требует установки явных значений высоты и ширины или получения размеров извне, например, от родительских элементов сетки, поскольку с этим значением элемент больше не будет определять свои размеры от своих дочерних элементов.

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

Предложение контейнерного запроса автора Мириам Сюзанной определяет новое значение inline-size. Принимая во внимание, что size используют для установки значений в обоих направлениях (ширина и высота), значение inline-size — основано на определении ширины.

Мириам предполагает, что чаще всего авторы CSS пытаются органичить элементы на основе ширины. Между тем, высота может быть внутренней — другими словами, увеличиваться или уменьшаться в зависимости от ограниченного элемента. Таким образом, inline-size считается одноосным ограничением. И это значение доступно в Chrome Canary и позволяет нам начать экспериментировать с контейнерными запросами.

Давайте создадим класс, который можно будет использовать для определения элементов как контейнеров:

.container {

  contain: layout inline-size style;

}

Нам нужно было включить значения layout и inline-size для успешной работы контейнерных запросов. Кроме того, Мириам также посоветовала добавить style чтобы избежать потенциального бесконечного цикла при настройке свойств, таких как счетчики, которые могут запускать изменения за пределами контейнера и влиять на его размер, вызывая цикл изменения размера.

Теперь, прежде чем мы напишем запрос, нужно узнать еще несколько вещей.

Когда вы используете контейнерный запрос, вы изменяете не сам контейнер, а элементы внутри этого контейнера.
Использование inline-size создает ограничение контекста для элементов в этом контейнере. Запрошенный элемент будет использовать своего ближайшего предка с примененным ограничением. Это важно, потому что можно вкладывать контейнеры. Поэтому, если вы не знаете, что это за контейнер, или создаете вложенный контейнер, результаты для потомков могут измениться.

Итак, как на самом деле выглядит контейнерный запрос? Синтаксис будет знаком из медиа-запросов, поскольку они начинаются с @container, а затем указывается необходимое значение, например (min-width: 300px). Предположим, мы разместили наш класс container в <main> элементе, и он содержит несколько <articles>:

<main class=«container»>

  <article>...</article>

  <article>...</article>

  <article>...</article>

</main>

Теперь мы можем настроить контейнерный запрос для изменения articles и любого из их потомков, который будет основан на ширине main, поскольку это содержащий элемент. До сих пор в своих экспериментах я счел полезным думать об этом как о концепции «сначала мобильные», за исключением того, что в данном случае это «сначала самый узкий контейнер». Это означает, что я сначала определю стили для моего наименьшего ожидаемого контейнера, а затем буду использовать контейнерные запросы для изменения стилей по мере увеличения контейнера.

article {

  padding: 1rem;

  font-size: 1rem;

}

@container (min-width: 60ch) {

  article {

    padding: 2rem;

    font-size: 1.25rem;

  }

}

Обратите внимание, что использование относительного к шрифту единиц измерения, таких как ch или em, предназначено для использования с параметром контейнера font-size, но на момент написания статьи еще не завершено. Итак, на данный момент мы будем использовать размер корневого шрифта. Существует проблема со спецификацией для изучения других функций, которые могут стать доступными для запросов.

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

Если мы настроим наш контейнер main и определим гибкую сетку, чтобы статьи реагировали как гибкие дочерние элементы, мы столкнемся с некоторой проблемой:

main {

  display: flex;

  flex-wrap: wrap;

}

article {

  flex: 1 1 30ch;

}

Вы можете ожидать, что, когда ширина статьи меньше, чем 60ch, она потребует уменьшенных отступов и размера шрифта. Однако, поскольку статьи являются прямыми дочерними элементами main, а main являются единственным контекстом ограничения, статьи не изменятся, пока ширина main не станет меньше ширины контейнерного запроса. Мы столкнулись бы с аналогичной проблемой, если бы использовали CSS-сетку для размещения статей.

Чтобы решить эту проблему, в каждую статью необходимо добавить ограничивающий элемент, чтобы правильно запрашивать ширину гибкого элемента. Это потому, что элемент main больше не представляет ширину элемента. В этом случае самое быстрое решение — добавить элементы div в наш класс container вокруг каждой статьи.

<main class=«container»>

  <div class=«container article»><article>...</article></div>

  <div class=«container article»><article>...</article></div>

  <div class=«container article»><article>...</article></div>

</main>

Нам также нужно будет переключить наше определение flex с article на новое div, в которое мы также добавили класс article для простоты написания нашего правила:

.article {

  flex: 1 1 30ch;

}

В результате, последняя статья охватывает всю ширину и будет иметь стили больших контейнеров. Вот CodePen этого примера контейнерных запросов для дочерних элементов Flexbox (напоминание для просмотра в Chrome Canary с включенными контейнерными запросами, как указано в начале!).

Введение в контейнерные запросы CSS

Статьи, гибко упорядоченные, имеют две статьи в первой строке с использованием стилей узких контейнеров и последнюю статью во второй строке, охватывающей всю ширину с стилями больших контейнеров.

Мы тоже определили main как контейнер. Это означает, что мы можем добавлять стили для класса .article, но они будут зависеть от ширины main, а не от самих. Я думаю, что возможность иметь правила внутри контейнерных запросов, отвечающих за несколько уровней контейнеров, вызовет наибольшую путаницу при первоначальной реализации и последующей оценке и совместном использовании таблиц стилей.

В ближайшем будущем обновления браузера DevTools, безусловно, помогут внести изменения в DOM, которые изменят эти типы отношений между элементами и контейнерами, которые они могут запрашивать. Возможно, новая передовая практика будет заключаться в том, чтобы запрашивать только один уровень выше в блоке @container и заставлять наследников иметь свой контейнер, чтобы уменьшить возможность негативного воздействия. Компромисс — это возможность большего количества элементов DOM, как мы видели в нашем примере статьи, и, следовательно, увеличение семантики.

В этом примере мы увидели, что произошло с обоими вложенными контейнерами, а также последствия введения гибкого или сеточного макета в контейнер. Что в настоящее время не определено в спецификации, так это то, что происходит, когда контейнерный запрос определен, но нет фактических предков контейнера для запрашиваемых элементов. Может быть принято решение считать ограничения ложным и отбросить правила, или же они могут вернуться в область просмотра. Вы можете отслеживать открытую проблему для ограничения отката и даже высказать свое мнение в этом обсуждении!

Правила выбора элемента контейнера

Ранее я упоминал, что сам контейнер не может быть оформлен в рамках запроса контейнера (если только он не является вложенным контейнером и не отвечает на запрос контейнера-предка). Однако контейнер можно использовать как часть селектора CSS для его дочерних элементов.

Почему это важно? Это позволяет сохранить доступ к псевдоклассам и селекторам CSS, которые могут возникнуть в контейнере, например :nth-child.

В нашем примере, если мы хотим добавить границу odd к каждой статье, мы можем написать следующее:

@container (min-width: 60ch) {

  .container:nth-child(odd) > article {

    border: 1px solid grey;

  }

}

Если вам нужно это сделать, вы можете использовать менее общие имена классов контейнеров, чтобы иметь возможность более читабельным способом идентифицировать, какие контейнеры запрашиваются для правила.

Пример для обучения: обновление тизеров статей на SmashingMagazine

Если вы посетите профиль автора здесь на Smashing (например, мой) и измените размер своего браузера, вы заметите, что расположение элементов тизера статьи меняется в зависимости от ширины области просмотра.

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

Введение в контейнерные запросы CSS

Снимок экрана с тремя настройками макета, описанными в предыдущем абзаце.

Комбинируя контейнерные запросы с обновлением до использования областей шаблона сетки CSS, мы можем обновить этот компонент, чтобы он реагировал на контейнеры, а не на область просмотра. Мы начнем с узкого представления, что также означает, что браузеры, не поддерживающие контейнерные запросы, будут использовать этот макет.

Для этой демонстрации я использовал минимально необходимые существующие стили из Smashing и сделал только одну модификацию существующей модели DOM, которая заключалась в перемещении заголовка в компонент header (и превращении его в h2).

Вот сокращенный фрагмент структуры DOM статьи, чтобы показать элементы, которые мы хотим переупорядочить (оригинальные имена классов сохранены):

<article class=«article—post»>

  <header>

    <div class=«article—post__image»></div>

    <span class=«article—post__author-name»></span>

    <h2 class=«article—post__title»></h2>

  </header>

  <footer class=«article—post__stats»></footer>

  <div class=«article—post__content»></div>

</article>

Предположим, что это прямые потомки, main и определим main как наш контейнер:

main {

  contain: layout inline-size style;

}

В самом маленьком контейнере у нас есть три секции : заголовок, статистика и контент. По сути, они появляются в макете блока по умолчанию в нашем DOM. Но мы продолжим и назначим сеточный шаблон и каждый из соответствующих элементов, потому что шаблон является ключом к нашим настройкам в контейнерных запросах.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

.article—post {

  display: grid;

  grid-template-areas:

    «header»

    «stats»

    «content»;

  gap: 0.5rem;

}

.article—post header {

  grid-area: header;

}

.article—post__stats {

  grid-area: stats;

}

.article—post__content {

  grid-area: content;

}

Сетка идеально подходит для этой цели, потому что возможность определять именованные области шаблона значительно упрощает внесение изменений в окружение. Кроме того, его фактический алгоритм компоновки более идеален, чем flexbox, с точки зрения того, как мы хотим управлять изменением размеров областей, что может стать более ясным, когда мы добавим обновления контейнерных запросов.

Прежде чем мы продолжим, мы должны также создать шаблон сетки для header, чтобы иметь возможность перемещаться между аватаром, именем автора и заголовоком. Мы добавим в правило .article—post header:

.article—post header {

  display: grid;

  grid-template-areas:

    «avatar name»

    «headline headline»;

  grid-auto-columns: auto 1fr;

  align-items: center;

  column-gap: 1rem;

  row-gap: 0.5rem;

}

Если вы не знакомы с grid-template-areas — то мы здесь делаем так, чтобы в верхней строке был один столбец для аватара и один для имени. Затем во второй строке мы планируем, чтобы заголовок охватывал оба этих столбца, которые мы определяем, используя одно и то же имя дважды.

Важно отметить, что мы также определяем grid-auto-columns, чтобы переопределить поведение по умолчанию, когда каждый столбец занимает 1fr или равную часть общего пространства. Это потому, что мы хотим, чтобы ширина первого столбца равнялась ширине аватара, а оставшееся пространство занимало имя.

Теперь нам нужно обязательно явно разместить связанные элементы в этих областях:

.article—post__image {

  grid-area: avatar;

}

.article—post__author-name {

  grid-area: name;

}

.article—post__title {

  grid-area: headline;

  font-size: 1.5rem;

}

Мы также определяем font-size для заголовка, который мы будем увеличивать по мере увеличения ширины контейнера. Наконец, мы будем использовать flex, чтобы расположить список статистики по горизонтали, до самого большого за размером контейнера:

.article—post__stats ul {

  display: flex;

  gap: 1rem;

  margin: 0;

}

Примечание: Safari недавно завершил поддержку gap для flexbox, то есть теперь он поддерживается для всех современных браузеров!

Введение в контейнерные запросы CSS

Результат стилей шаблона сетки, отображающий выровненные аватар и имя автора, за которым следует заголовок, затем статистика, а затем содержание тизера.

Теперь мы можем перейти к первому из двух контейнерных запросов, чтобы создать представление среднего размера. Давайте воспользуемся возможностью создавать запросы, относящиеся к шрифту, и основывать их на превышении контейнером 60ch. На мой взгляд, создание содержимого в зависимости от длины строки — это практичный способ управлять изменениями ширины контейнера. Тем не менее, вы, безусловно, можете использовать пиксели, rems, ems и возможно, другие опции в будущем.

Для среднего размера нам нужно настроить шаблоны сетки заголовка и общей статьи:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

@container (min-width: 60ch) {

  .article—post header {

    grid-template-areas:

      «avatar name»

      «avatar headline»;

    align-items: start;

  }

  .article—post {

    grid-template-areas: «header header» «. stats» «. content»;

    grid-auto-columns: 5rem 1fr;

    column-gap: 1rem;

  }

  .article—post__title {

    font-size: 1.75rem;

  }

}

При такой ширине мы хотим, чтобы аватар отображался в отдельной колонке слева от остального содержимого. Для этого в шаблоне сетки он назначается первому столбцу обеих строк, а затем смещается имя в строку один столбца два, а заголовок в строку два столбца два. Аватар также должен быть выровнен по верхнему краю, его можно отрегулировать с помощью align-items: start.

Затем мы обновляем шаблон сетки статей, чтобы заголовок занимал оба столбца в верхней строке. После этого мы используем сивол точки «.», чтобы назначить безымянную область сетки для первого столбца второго и третьего ряда, готовясь к визуальному отображению аватара в его собственном столбце. Затем мы настраиваем автоматические столбцы, чтобы сделать первый столбец эквивалентным ширине аватара, для завершения эффекта.

Введение в контейнерные запросы CSS

Макет запроса контейнера среднего размера с визуально отображаемым аватаром в собственном столбце слева от остального содержимого.

Для самого большого размера контейнера нам нужно переместить список статистики, чтобы он отображался справа от содержимого статьи, но под заголовком. Мы снова будем использовать единицы ch для нашей «точки останова», на этот раз — используем 100ch.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

@container (min-width: 100ch) {

  .article—post {

    grid-template-areas: «header header header» «. content stats»;

    grid-auto-columns: 5rem fit-content(70ch) auto;

  }

  .article—post__stats ul {

    flex-direction: column;

  }

  .article—post__title {

    max-width: 80ch;

    font-size: 2rem;

  }

  .article—post__content {

    padding-right: 2em;

  }

}

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

Глядя на окончательную версию этой страницы, мы видим, что статья не занимает 100% ширины макета Smashing. Чтобы сохранить такое расположение, внутри grid-auto-columns мы используем функцию fit-content, которую можно читать как: «расти до внутренней максимальной ширины содержимого, но не больше, чем предоставленное значение». Итак, мы говорим, что столбец может расти, но не превышать 70ch. Это не предотвращает его сжатие, поэтому столбец также остается чувствительным к доступному пространству.

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

Введение в контейнерные запросы CSS

При наибольшем расположении компонентов статьи время чтения и статистика комментариев перемещаются вправо от основного содержания, а содержание статьи занимает наибольшее горизонтальное пространство.

Теперь вы можете подумать, что мы как бы просто выполнили медиа-запросы, но все немного по-другому. Что — если мы остановимся на мгновение — это здорово! Это должно помочь почувствовать себя знакомыми с контейнерными запросами и упростить их настройку и включение в рабочий процесс. Что касается нашей демонстрации, то как вы видите, наша отдельная статья в настоящее время реагирует на один родительский элемент, который сам реагирует только на изменение области просмотра.

Что мы действительно сделали, так это заложили основу для размещения нашей статьи на странице статей или на домашней странице, где статьи расположены в столбцах (ради этой демонстрации мы проигнорируем другие изменения, которые происходит на домашней странице). Как мы узнали во вводном примере, если мы хотим, чтобы элементы реагировали на ширину элементов сетки CSS или на значение flex, нам нужно, чтобы они находились внутри своего контейнера. Поэтому давайте добавим явный контейнерный элемент вокруг каждой статьи вместо того, чтобы полагаться на main.

<div class=«article—post-container»>

    <article class=«article—post»></article>

</div>

Затем мы назначим .article—post-container контейнером:

.article—post-container {

  contain: layout inline-size;

}

Теперь, если мы создадим макет сетки, как мы это делали во вводном примере, мы разместим одну статью над сеткой и две внутри ее. Вот полный CodePen этой демонстрации, включая гибкую сетку:

Возможности и предостережения при использовании контейнерных запросов

Вы можете начать подготовку к использованию контейнерных запросов уже сегодня, включив их в качестве прогрессивного усовершенствования. Определяя стили, которые хорошо работают без контейнерных запросов, вы можете наслоить улучшения, которые их действительно используют. Тогда неподдерживающие браузеры все равно получат работоспособную — если не идеальную — версию.

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

Адаптивная типоргафика

Возможно, вы знакомы с концепцией адаптивной или плавной типографики. Решения по обновлению типографики для разных областей просмотра и ширины элементов претерпели множество улучшений, от поддержки JavaScript до решений CSS, использующих единицы области просмотра clamp().

Если спецификация получит контейнерную единицу (о которой мы вскоре поговорим), мы сможем достичь внутренней типографики. Но даже с текущей спецификацией мы можем определить адаптивную типографику, изменив значение font-size для различных размеров содержащихся элементов. Фактически, мы только что сделали это в примере со статьями Smashing Magazine.

Хотя это интересно с точки зрения дизайна и верстки, оно требует той же осторожности, что и существующие решения для гибкой типографии. Для доступности пользователь должен иметь возможность масштабировать макет и увеличивать его font-size до 200% от исходного размера. Если вы создадите решение, которое резко уменьшает размер шрифта в меньших контейнерах — который может быть вычисленным размером при масштабировании — пользователь никогда не сможет добиться увеличения базы font-size на 200%. Я уверен, что мы увидим больше рекомендаций и решений по этому поводу, когда мы больше познакомимся с контейнерными запросами!

Изменение отображаемых значений

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

Это категория, в которой вы найдете многие из текущих демонстраций, поскольку, похоже, это одна из вещей, которая делает возможность контейнерных запросов такой захватывающей. В то время как адаптивные сеточные системы основаны на медиа-запросах, привязанных к ширине области просмотра, вы можете добавить уровни служебных классов, чтобы получить желаемый результат. Но с помощью контейнерных запросов вы можете точно указать не только систему сеток, но и полностью изменить ее по мере увеличения и уменьшения элемента или компонента.

Возможные сценарии включают:

изменение формы подписки на новостную рассылку с горизонтальной на многослойную;

создание чередующихся разделов шаблона сетки;

изменение соотношения сторон изображений и их положения по сравнению с соответствующим контентом;

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

Здесь следует отметить, что, для доступности рекомендуется обеспечить логический порядок, особенно ради табуляции интерактивных элементов, таких как ссылки, кнопки и элементы формы.

Отображение, скрытие и перестановка

Для более сложных компонентов контейнерные запросы могут управлять вариантами отображеня. Рассмотрим меню навигации, которое включает в себя серию ссылок, и при уменьшении контейнера некоторые из этих ссылок должны скрыться и должен появиться раскрывающийся список.

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

Разрабатывать один раз и развертывать где угодно

Ладно, это может быть немного вдохновляющим. Но для систем проектирования, библиотек компонентов и разработчиков фреймворков контейнерные запросы значительно улучшат возможность предоставления самозащитных решений.

Способность компонентов управлять собой в любом заданном пространстве уменьшит сложности, возникающие, когда придет время фактически добавить их в макет.

На первый взгляд это кажется мечтой, особенно если вы, как и я, занимались разработкой дизайн-системы. Однако для некоторых компонентов плюсы и минусы могут быть одинаковыми, и вам не всегда может понадобиться динамический макет или поведение изменения положения. Я предполагаю, что это будет еще одна область, в которой сформируются лучшие практики, которые, возможно, позволят компонентам использовать поведение контейнерного запроса для каждого экземпляра, например, через класс модификатора.

Например, рассмотрим компонент карты, который предполагает, что его font-size должен измениться. Но в конкретном случае фактическое количество символов было намного больше или намного короче, и эти правила были неоптимальными. Согласиться с этим, вероятно, будет проще, чем пытаться переопределить каждый отдельный запрос контейнера, который был прикреплен.

Что может измениться в спецификации

В настоящее время даже синтаксис может быть изменен до того, как спецификация будет полностью завершена. Фактически, она была выпущена в качестве эксперимента, чтобы мы, как сообщество, могли предоставить обратную связь. Мириам Сюзанна создала проект GitHub для отслеживания проблем, и вы можете реагировать на них и добавлять комментарии.

Я уже упоминал о двух ключевых проблемах, которые еще предстоит решить:

# 6178: Как разрешить проблему с @container, если не определены контейнеры-предки?

# 5989: Какие возможности контейнера можно запрашивать?

Большое значение и влияние имеют:

Должен ли быть новый синтаксис для создания запрашиваемых контейнеров? (# 6174). Первоначальный выпуск от Мириам предлагает два варианта: либо нового набора выделенных значений contain, либо, возможно, вызываемого совершенно нового свойства containment. Если какое-либо из этих изменений произойдет на этапе прототипа, значения, показанные в начале этой статьи, могут больше не работать. Итак, еще раз обратите внимание, что экспериментировать — это здорово, но имейте в виду, что все будет продолжать меняться!

Также представляет интерес возможность появления новых контейнерных единиц, отслеживаемых в:

Единицы «ширина контейнера» и «высота контейнера» (# 5888). Это могло бы открыть собственное решение CSS для внутренней типографики, среди прочего, что-то вроде: font-size: clamp(1.5rem, 1rem + 4cw, 3rem)(где cw- заполнитель для неопределенной в данный момент единицы, которая может представлять ширину контейнера).

Автор: Stephanie Eckles

Источник: www.smashingmagazine.com

Редакция: Команда webformyself.

Профессия Frontend-разработчик PRO

Готовим Frontend-разработчиков с нуля

На курсе вы научитесь создавать интерфейсы веб-сервисов с помощью языков программирования и
дополнительных технологий. Сможете разрабатывать планировщики задач, мессенджеры, интернет-магазины…

Узнать подробнее

До 10 проектов в портфолио для старта карьеры

Подходит для новичков без опыта в программировании

Практика на вебинарах с разработчиками из крупных компаний

Читайте нас в Telegram, VK, Яндекс.Дзен

Мы познакомились с HTML и CSS, знаем как они выглядят и как выполнить некоторые основы. Теперь мы собираемся погрузиться немного глубже и подробно рассмотреть, как элементы отображаются на странице и задаются их размеры.

В процессе мы обсудим тему, известную как блочная модель и как она работает с HTML и CSS. Мы также рассмотрим несколько новых свойств CSS и используем некоторые значения размеров, о которых рассказывали в уроке 3. Давайте начнём.

Как отображаются элементы?

Прежде чем перейти к блочной модели, нам надо понимать, как отображаются элементы. В уроке 2 мы рассмотрели разницу между блочными и строчными элементами. Быстро напомним, что блочные элементы занимают всю доступную ширину независимо от их содержимого и начинаются с новой строки. Строчные элементы занимают ширину, которая требуется для содержимого и выстраиваются на одной строке, друг за другом. Блочные элементы, как правило, используются для больших кусков контента, таких как заголовки и структурные элементы. Строчные элементы, как правило, применяются для маленьких частей содержимого, таких как несколько слов, выделенных жирным или курсивным начертанием.

display

Как именно отображаются элементы — как блочные или строчные или как-то ещё, определяется свойством display. Каждый элемент содержит значение свойства display по умолчанию, но как и с любым другим значением свойств, это значение может быть переписано. Есть немало значений для свойства display, но наиболее распространённые это block, inline, inline-block и none.

Мы можем изменить значение свойства display элемента, выбрав этот элемент в CSS и задав новое значение свойства display. Значение block сделает этот элемент блочным.

p {
  display: block;
}

Значение inline сделает этот элемент строчным.

p {
  display: inline;
}

Самое интересное это значение inline-block. Его использование позволит элементу вести себя как блочный, включая все свойства блочной модели (которые мы вскоре рассмотрим). Однако, элемент будет отображаться на строке с другими элементами, а не будет начинаться с новой строки по умолчанию.

p {
  display: inline-block;
}

Демонстрация inline-block

Пространство между строчно-блочными элементами

Одним из важных отличий строчно-блочных элементов является то, что они не всегда соприкасаются или отображается непосредственно друг за другом. Обычно между двумя элементами будет небольшое пространство. Это пространство, возможно и раздражает, но это нормально. Мы обсудим, почему оно существует и как его убрать в следующем уроке.

В заключение, используя значение none полностью скрываем элемент и отображаем страницу, словно элемента не существует. Любые элементы, вложенные в такой элемент, также будут скрыты.

div {
  display: none;
}

Знание, как отображаются элементы и как изменить display довольно важно, так как display оказывает влияние на отображение блочной модели. В процессе обсуждения блочной модели мы обязательно взглянем на эти разные последствия и как они могут повлиять на представление элемента.

Что такое блочная модель?

В соответствии с концепцией блочной модели, каждый элемент на странице представляет собой прямоугольный блок и может иметь ширину, высоту, поля, границы и отступы.

Это стоит повторить: Каждый элемент на странице представляет собой прямоугольный блок.

Рис. 4.01. Когда мы смотрим на каждый элемент по отдельности, то можем увидеть, что все они прямоугольны, независимо от их представленных форм

Каждый элемент на каждой странице соответствует блочной модели, так что это невероятно важно. Давайте взглянем на неё, наряду с несколькими новыми свойствами CSS, чтобы лучше понять, как мы можем с этим работать.

Работа с блочной моделью

Каждый элемент представляет собой прямоугольный блок и есть несколько свойств, которые устанавливают размер этого блока. Внутренность блока определяется шириной и высотой элемента, который может быть задан свойством display, содержимым элемента или свойствами width и height. padding и затем border расширяют размеры блока наружу от ширины и высоты элемента. Наконец, любой указанный margin идёт за пределами рамки.

Каждая часть блочной модели соответствует свойству CSS: width, height, padding, border и margin.

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

div {
  border: 6px solid #949599;
  height: 100px;
  margin: 20px;
  padding: 20px;
  width: 400px;
}

В соответствии с блочной моделью общая ширина элемента может быть рассчитана по следующей формуле:

margin-right + border-right + padding-right + width + padding-left + border-left + margin-left

Для сравнения, в соответствии с блочной моделью общая высота элемента может быть рассчитана по следующей формуле:

margin-top + border-top + padding-top + height + padding-bottom + border-bottom + margin-bottom

Блочная модель включает базовую высоту и ширину плюс padding, border и margin

Рис. 4.02. Блочная модель включает базовую высоту и ширину плюс padding, border и margin

Используя эти формулы, мы можем найти общую высоту и ширину блока из нашего примера.

Ширина: 492px = 20px + 6px + 20px + 400px + 20px + 6px + 20px
Высота: 192px = 20px + 6px + 20px + 100px + 20px + 6px + 20px

Блочная модель, без сомнения, одна из наиболее запутанных частей HTML и CSS. Мы устанавливаем значение свойства width как 400 пикселей, но фактическая ширина нашего элемента 492 пикселя. По умолчанию блочная модель коробка аддитивна. Таким образом, для определения фактического размера блока мы должны принять во внимание поля, границы и отступы для всех четырёх сторон блока. Наша ширина включает не только значение свойства width, но и размер левого и правого поля, левую и правую границу, левые и правые отступы.

Пока многие из этих свойств не несут большого смысла и это нормально. Для уточнения давайте поближе посмотрим на все эти свойства width, height, padding, border и margin, которые формируют блочную модель.

width и height

У каждого элемента есть ширина и высота по умолчанию. Эта ширина и высота может быть равна нулю, но браузеры по умолчанию отображают каждый элемент с размером. В зависимости от того, как отображается элемент, ширина и высота по умолчанию может быть соответствующей. Если элемент является ключевым в макете страницы, для него может потребоваться задать определённые значения свойств width и height. В этом случае значения свойств для не строчных элементов могут быть указанными.

width

По умолчанию ширина элемента основана на значении display. У блочных элементов ширина по умолчанию 100% и занимает всё доступное горизонтальное пространство. Строчные и строчно-блочные элементы расширяются и сжимаются горизонтально для размещения их содержимого. Строчные элементы не могут иметь фиксированный размер, таким образом, ширина и высота относятся только к не строчным элементам. Чтобы задать определённую ширину для не строчных элементов, используйте свойство width:

div {
  width: 400px;
}

height

Высота элемента по умолчанию определяется его содержимым. Элемент будет расширяться и сжиматься по вертикали при необходимости, чтобы вместить его содержимое. Установить определённую высоту для не строчных элементов можно через свойство height:

div {
  height: 100px;
}

Размеры строчно-блочных элементов

Пожалуйста, помните, что строчные элементы не принимают свойства width и height и любые их значения. Блочные и строчно-блочные элементы, однако, принимают свойства width и height и соответствующие им значения.

margin и padding

В зависимости от элемента, браузеры могут применять отступы и поля по умолчанию для элемента, чтобы помочь с удобочитаемостью. Мы, как правило, видим это на текстовых элементах. Поля и отступы по умолчанию для этих элементов могут отличаться от браузера к браузеру и от элемента к элементу. В уроке 1 мы обсуждали использование сброса CSS чтобы все эти значения по умолчанию стали нулевыми. Это позволяет нам работать с нуля и задать собственные значения.

margin

Свойство margin позволяет нам установить пространство, которое окружает элемент. margin находятся за пределами любых границ и полностью прозрачны в цвете. Они могут использоваться для позиционирования элементов в конкретном месте на странице или добавить пустое пространство, сохраняя все другие элементы на безопасном расстоянии. Вот свойство margin в действии:

div {
  margin: 20px;
}

Одной из причуд margin являются вертикальные значения, сверху и снизу, они не применяются к строчным элементам, но применяются к блочным и строчно-блочным элементам.

padding

Свойство padding очень похоже на свойство margin, однако располагается внутри границ элемента. Свойство padding используется, чтобы задать пространство непосредственно внутри элемента. Вот код:

div {
  padding: 20px;
}

Свойство padding в отличие от margin работает вертикально для строчных элементов. Вертикальный padding может сливаться со строкой выше или ниже данного элемента, но будет отображаться.

margin и padding для строчных элементов

Строчные элементы ведут себя немного по-другому, чем блочные и строчно-блочные элементы, когда дело доходит до отступов и полей. Для строчных элементов margin работает только горизонтально — слева и справа от элементов. padding работает на всех четырёх сторонах строчных элементов, однако вертикальные поля сверху и снизу могут выходить за пределы строки выше и ниже элемента.

Отступы и поля работают как обычно для блочных и строчно-блочных элементов.

Установка margin и padding

В CSS существует несколько способов установить значения определённых свойств. Мы можем использовать обычную запись, в которой перечисляется несколько свойств и значений одно за другим, в котором у каждого значения есть собственное свойство. Или мы можем использовать сокращённую запись, перечисляя несколько значений одного свойства. Не у всех свойств есть сокращённый вариант, таким образом, мы должны убедиться что используем правильное свойство и структуру значений.

Свойства margin и padding существуют в обычном и сокращённом виде. При использовании сокращённого свойства margin, чтобы установить одно значение для всех четырёх сторон элемента мы задаём одно значение:

div {
  margin: 20px;
}

Чтобы установить одно значение для верхней и нижней стороны, а другое значение для левой и правой стороны элемента, укажите два значения: вначале сверху и снизу, затем слева и справа. Здесь для <div> мы задаём отступы 10 пикселей сверху и снизу и 20 пикселей слева и справа:

div {
  margin: 10px 20px;
}

Чтобы установить уникальные значения для всех четырёх сторон элемента, укажите эти значения в следующем порядке: сверху, справа, снизу и слева, двигаясь по часовой стрелке. Здесь мы задаём для <div> отступы 10 пикселей сверху, 20 пикселей справа, 0 пикселей снизу и 15 пикселей слева.

div {
  margin: 10px 20px 0 15px;
}

Использование свойства margin или padding с любым числом значений считается сокращением. В обычной записи мы можем установить значение только для одной стороны используя уникальные свойства. После имени каждого из свойств (margin или padding в данном случае) идёт дефис и сторона блока, к которой должно применяться значение: top, right, bottom или left. Например, свойство padding-left принимает только одно значение и установит левое поле для этого элемента, свойство margin-top принимает только одно значение и установит верхний отступ для этого элемента.

div {
  margin-top: 10px;
  padding-left: 6px;
}

Когда мы хотим определить только одно значение margin или padding, то лучше использовать обычную запись. Это сохраняет наш код наглядным и помогает избежать путаницы по пути вниз. Например, вы действительно хотите установить margin в 0 сверху, справа и слева элемента или же на самом деле хотите установить margin снизу в 10 пикселей? Использование обычной записи для свойств и значений помогает нам это делать осмысленно. С другой стороны, когда имеешь дело с тремя или более значениями, сокращение невероятно полезно.

Цвет отступов и полей

Свойства margin и padding полностью прозрачны и не принимают какие-либо цветовые значения. Но будучи прозрачными они показывают цвет фона связанных элементов. Для margin мы видим цвет фона родительского элемента, а для padding видим цвет фона элемента, к которому применяется padding.

Границы

Границы располагаются между отступами и полями, создавая рамку вокруг элемента. Для свойства border требуется три значения: ширина, стиль и цвет. Сокращённая запись для border задаётся этом же порядке — ширина, стиль, цвет. В обычной записи эти три значения могут быть разбиты по свойствам border-width, border-style и border-color. Обычная запись полезна для изменения или переписывания отдельного значения границы.

Ширина и цвет границ могут быть определены с помощью обычных единиц размера и цвета CSS, как описано в уроке 3.

У границ может быть различный внешний вид. Наиболее распространённые значения solid, double, dashed, dotted и none, но есть и несколько других на выбор.

Вот код для сплошной серой границы толщиной 6 пикселей для всех четырёх сторон <div>:

div {
  border: 6px solid #949599;
}

Демонстрация border

Границы для отдельных сторон

Как и со свойствами margin и padding границы могут быть размещены на одной стороне элемента за раз при желании. Это требует новых свойств: border-top, border-right, border-bottom и border-left. Значения для этих свойств такие же, как и для border: ширина, стиль и цвет. При желании можно сделать так, чтобы граница появлялась только внизу элемента:

div {
  border-bottom: 6px solid #949599;
}

Кроме того, стилями для отдельных сторон можно управлять на ещё более тонком уровне. Например, если мы хотим изменить только ширину нижней границы, то можем использовать следующий код:

div {
  border-bottom-width: 12px;
}

Такое довольно специфичное свойство границы включают в себя ряд разделённых дефисом слов, начинающихся с border, затем идёт выбранная сторона — top, right, bottom или left, а затем width, style или color, в зависимости от желаемого свойства.

Радиус границы

Пока мы рассматриваем границы и их разные свойств, нам нужно изучить свойство border-radius, которое позволяет нам закруглять углы элемента.

Свойство border-radius принимает единицы размера, в том числе проценты и пиксели, которые определяют радиус скругления углов элемента. Единственное значение закругляет все четыре угла элемента в равной степени; два значения закругляют левый верхний/правый нижний и правый верхний/левый нижний углы в таком порядке; четыре значения закругляют левый верхний, правый верхний, правый нижний и левый нижний углы в таком порядке.

При рассмотрении порядка, когда несколько значений применяются к свойству border-radius (заодно к margin и padding), помните, что они идут по часовой стрелке, начиная с левого верхнего угла элемента.

div {
  border-radius: 5px;
}

Демонстрация border-radius

Свойство border-radius также может быть разбито на ряд свойств, которые позволяют нам изменить радиусы отдельных углов элемента. Эти свойства начинается с border, продолжаются с положения угла по вертикали (top или bottom) и горизонтали (left или right) и завершаются radius. Например, для изменения правого верхнего угла <div> может быть использовано свойство border-top-right-radius.

div {
  border-top-right-radius: 5px;
}

Размеры блока

До сих пор блочная модель была аддитивной. Если вы установили для width 400 пикселей, затем добавили 20 пикселей padding и border 10 пикселей на каждой стороне, фактическая полная ширина элемента становится 460 пикселей. Помните, мы должны сложить значения свойств width, padding и border вместе, чтобы получить реальную полную ширину элемента.

Блочная модель, однако, может быть изменена, чтобы вычисления происходили иначе. CSS3 ввёл свойство box-sizing, которое позволяет нам точно менять, как блочная модель работает и как вычисляются размеры элемента. Это свойство принимает три основных значения — content-box, padding-box и border-box, каждое из которых оказывает несколько разное влияние на вычисление размера блока.

content-box

Значение content-box является значением по умолчанию, оставляя блочную модель в качестве аддитивной. Если мы не используем свойство box-sizing, то это будет значением по умолчанию для всех элементов. Размер элемента начинается со свойств width и height, далее к ним добавляются значения свойств padding, border или margin .

div {
  -webkit-box-sizing: content-box;
  -moz-box-sizing: content-box;
  box-sizing: content-box;
}

Свойства и значения специфичные для браузера

Что означают все эти дефисы и буквы в свойстве box-sizing?

Когда был представлен CSS3, браузеры постепенно начали поддерживать разные свойства и значения, включая свойство box-sizing, путём добавления вендорных префиксов. Когда части спецификации CSS3 будут завершены и выпущены новые версии браузеров, эти префиксы станут всё менее и менее актуальными. Со временем префиксы вряд ли будут проблемой, однако, они всё ещё обеспечивают поддержку некоторых старых браузеров. Мы можем работать с ними время от времени и, возможно, даже захотим использовать их, если нам нужна поддержка старых браузеров.

Вендорные префиксы можно увидеть для свойств и значений, всё зависит от спецификации CSS. Здесь они показаны для свойства box-sizing. Разработчики браузеров были свободны в выборе, когда использовать префикс, а когда нет. Таким образом, одни свойства и значения требуют префиксы для некоторых браузеров, а другие нет.

Ниже, когда свойство или значение требует вендорный префикс, то префикс будет использоваться только для представления этого свойства или значения (в интересах сохранения нашего кода простым и кратким). Не забудьте добавить необходимые префиксы, когда вы станете писать реальный код.

Для справки, наиболее распространённые префиксы изложены здесь:

  • Mozilla Firefox: -moz-
  • Microsoft Internet Explorer: -ms-
  • Webkit (Google Chrome и Apple Safari): -webkit-

padding-box

Значение padding-box изменяет блочную модель путём включения всех значений свойства padding внутри width и height элемента. При использовании значения padding-box, если у элемент width равно 400 пикселей и padding 20 пикселей вокруг всех сторон, фактическая ширина останется 400 пикселей. При увеличении padding на любое значение, размер содержимого внутри элемента сжимается пропорционально.

Если мы добавим border или margin, эти значения будут добавлены к свойствам width или height для вычисления полного размера блока. Например, если мы добавим border 10 пикселей и padding 20 пикселей вокруг всех сторон элемента, у которого width 400 пикселей, фактическая полная ширина будет 420 пикселей.

div {
  box-sizing: padding-box;
}

border-box

Наконец, значение border-box изменяет блочную модель так, чтобы любые значения свойств border или padding включались внутри width и height элемента. При использовании значения border-box, если для элемента указаны width 400 пикселей, padding 20 пикселей и border 10 пикселей вокруг всех сторон, фактическая ширина останется 400 пикселей.

Если мы добавим margin, эти значения должны учитываться для расчёта полного размера блока. Независимо от того, какое значение свойства box-sizing применяется, любые значения margin не будут добавляться в вычисления полного размера элемента.

div {
  box-sizing: border-box;
}

Различные значения box-sizing позволяют по разному вычислять ширину элемента и блока целиком

Рис. 4.03. Различные значения box-sizing позволяют по разному вычислять ширину элемента и блока целиком

Выбор размера блока

Вообще говоря, лучшее значение box-sizing для применения — это border-box. Это значение намного упрощает нам математику. Если мы хотим, чтобы весь элемент был 400 пикселей в ширину, он останется 400 пикселей в ширину, независимо от того, какие значения padding или border мы к нему добавляем.

Кроме того, мы можем легко смешивать значения длины. Скажем, мы хотим, чтобы наш блок занимал 40% в ширину. Добавление padding 20 пикселей и border 10 пикселей для всех сторон элемента не сложно и мы по-прежнему можем гарантировать, что фактическая ширина нашего блока останется 40%, несмотря на использование пикселей в другом месте.

Единственный недостаток свойства box-sizing в том, что как часть спецификации CSS3 она не поддерживается во всех браузерах, особенно не хватает поддержки в старых версиях. К счастью, это становится всё менее и менее актуальным, поскольку выходят новые версии. Скорее всего, мы можем безопасно использовать свойство box-sizing, но если вы заметили какие-то проблемы, стоит посмотреть с каким браузером они связаны.

Инструменты разработчика

В большинстве браузеров есть то, что известно как Инструменты разработчика. Эти инструменты позволяют нам проверить элемент на странице, увидеть, где этот элемент живёт в HTML-документе и посмотреть, какие свойства и значения CSS к нему применяются. Большинство из этих инструментов также включают в себя схему блочной модели, чтобы показать вычисленный размер элемента.

Чтобы увидеть Инструменты разработчика в Google Chrome, откройте меню, выберите «Дополнительные инструменты», а затем «Инструменты разработчика». После этого откроется панель в нижней части окна браузера, которая предлагает несколько инструментов для проверки нашего кода.

Щелчок по стрелке в нижней части этой панели позволяет выделять и щёлкать по разным элементам на странице, чтобы узнать о них больше информации.

После выбора элемента мы увидим несколько вкладок в правой части панели «Elements» в инструментах разработчика. Выбор вкладки «Computed» покажет нам подробную блочную модель для нашего выбранного элемента.

Поиграйте с инструментами разработчика, будь они в Google Chrome, Mozilla Firefox, Apple Safari или других браузерах; можно многое узнать просматривая наш код. Я вообще оставляю панель инструментов всегда открытыми при написании HTML и CSS. И также часто проверяю код других сайтов, чтобы увидеть, как они сделаны.

Инструменты разработчика Google Chrome, которые помогают нам проверять HTML и CSS на любой странице

Рис. 4.04. Инструменты разработчика Google Chrome, которые помогают нам проверять HTML и CSS на любой странице

Блочная модель является одной из самых запутанных частей при изучении HTML и CSS. Она также является одной из самых мощных частей HTML и CSS и как только мы это освоим, практически всё остальное, вроде позиционирования содержимого, пойдёт довольно легко.

На практике

Давайте перепрыгнем обратно к нашему сайту Styles Conference к центральной части страницы и добавим ещё немного содержимого.

  1. Начнём настройку размера нашего блока с версии border-box, которая упростит установку размеров всех наших элементов. В нашем файле main.css, чуть ниже сброса, добавим комментарий, чтобы определить код для создания нашей сетки и макета сайта. Мы положим всё это ниже сброса, чтобы они шли в правильном порядке в каскаде.

    Отсюда мы можем использовать универсальный селектор *, наряду с универсальными псевдоэлементами *:before и *:after для выбора всех мыслимых элементов и изменения box-sizing на border-box. Помните, что мы собираемся включить вендорные префиксы для свойства box-sizing, так как это относительно новое свойство.

    /*
      ========================================
      Сетка
      ========================================
    */
    
    *,
    *:before,
    *:after {
      -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
      box-sizing: border-box;
    }
  2. Далее мы хотим создать класс, который будет служить контейнером для наших элементов. Мы можем использовать этот класс для различных элементов, чтобы установить общую ширину, выровняв элементы по центру страницы и применить некоторые общие горизонтальные поля.

    Чуть ниже набора универсальных селекторов создадим селектор класса container. В этом селекторе зададим width как 960 пикселей, padding слева и справа по 30 пикселей, margin сверху и снизу как 0, а слева и справа как auto.

    Установка width сообщает браузеру какая ширина элемента с классом container однозначно должна быть. Использование margin слева и справа как auto в сочетании с width позволяет браузеру автоматически выставить равные левые и правые поля для элемента, таким образом, выровняв его по центру на странице. Наконец, padding слева и справа гарантирует, что наше содержимое не занимает непосредственно края элемента и обеспечивает небольшое пространство для содержимого.

    .container {
      margin: 0 auto;
      padding-left: 30px;
      padding-right: 30px;
      width: 960px;
    }
  3. Теперь у нас есть класс container доступный для использования, пойдём вперёд и применим этот класс в HTML к элементам <header> и <footer> на каждой странице, включая файлы index.html, speakers.html, schedule.html, venue.html и register.html.

    <header class="container">...</header>
    
    <footer class="container">...</footer>
  4. Пока мы здесь, давайте расположим по центру остальное содержимое наших страниц. На главной странице (файл index.html) добавим класс container к каждому элементу <section> на странице, по одному на героя нашего раздела (раздел, который представляет нашу конференцию) и одному для раздела тизеров.

    <section class="container">...</section>

    Кроме того, обернём все элементы <h1> на каждой странице элементом <section> с классом container.

    <section class="container">
      <h1>...</h1>
    </section>

    Мы позже вернёмся и настроим эти элементы и классы, но сейчас движемся в правильном направлении.

  5. Теперь, когда всё наше содержимое выровнено по центру, установим некоторое вертикальное пространство между элементами. Для начала разместим 22-пиксельный нижний margin для некоторых заголовков и абзацев. Мы добавим и прокомментируем стили ниже стилей сетки.

    /*
      ========================================
      Типографика
      ========================================
    */
    
    h1, h3, h4, h5, p {
      margin-bottom: 22px;
    }

    Мы намеренно пропустили <h2> и <h6>, так как по дизайну не требуются отступы для элементов <h2> и мы не будем использовать любые элементы <h6> в данный момент.

  6. Давайте также попробуем наши силы в создании границ и некоторых закругленных уголков. Мы начнём с размещения кнопки в верхней части элемента <section> на главной странице, чуть ниже заголовка.

    Ранее мы добавили элемент <a> внутри <section>. Давайте добавим классы btn и btn-alt к этой ссылке.

    <a class="btn btn-alt">...</a>

    Теперь создадим некоторые стили для этих классов в нашем CSS. Ниже нашего набора правил типографики сделаем новый раздел для кнопок.

    Для начала добавим класс btn и применим некоторые общие стили, которые будут для всех кнопок. Мы хотим, чтобы у всех кнопок был border-radius 5 пикселей. Кнопки должны отображаться как inline-block, поэтому мы можем добавить поля со всех четырёх сторон без проблем и уберём все margin.

    /*
      ========================================
      Кнопки
      ========================================
    */
    
    .btn {
      border-radius: 5px;
      display: inline-block;
      margin: 0;
    }

    Мы также хотим включить стили, характерные для этой кнопки, которые делаем с помощью класса btn-alt. Сюда добавим однопиксельную рамку серого цвета, padding 10 пикселей сверху и снизу и padding 30 пикселей слева и справа от кнопки.

    .btn-alt {
      border: 1px solid #dfe2e5;
      padding: 10px 30px;
    }

    Применение двух классов btn и btn-alt к одному элементу <a> позволяет накладывать эти стили, отображая их для одного элемента.

  7. Поскольку мы работаем с главной страницей, давайте также добавим небольшой padding к элементу <section>, содержащий наш элемент <a> с классами btn и btn-alt. Мы сделаем это путём добавления атрибута class со значением hero к элементу <section>, наряду с классом container, так как это будет ведущий раздел нашего сайта.

    <section class="hero container">
      ...
    </section>

    Далее мы хотим создать новый раздел в файле CSS для стилей главной страницы и как только будем готовы, станем использовать класс hero, чтобы установить padding для всех четырёх сторон элемента <section>.

    /*
      ========================================
      Главная страница
      ========================================
    */
    
    .hero {
      padding: 22px 80px 66px 80px;
    }

Наш сайт начинает складываться воедино, особенно главная страница.

Главная страница Styles Conference постепенно принимает форму после нескольких обновлений

Рис. 4.05. Главная страница Styles Conference постепенно принимает форму после нескольких обновлений

Демонстрация и исходный код

Ниже вы можете просмотреть сайт Styles Conference в его нынешнем состоянии, а также скачать исходный код сайта на данный момент.

Просмотр сайта Styles Conference или Скачать исходный код

Универсальный селектор

На первом этапе данного упражнения мы представили универсальный селектор. В CSS звёздочка (*) это универсальный селектор, который выбирает каждый элемент. Вместо перечисления всех отдельных элементов мы можем использовать звёздочку для выбора всех элементов.

Псевдоэлементы :before и :after также упомянутые на этом этапе — это элементы, которые могут динамически генерироваться через CSS. Мы не станем применять эти элементы в нашем проекте, однако, при упоминании универсального селектора также хорошим тоном будет включить эти псевдоэлементы на случай, если они когда-нибудь появятся.

Резюме

Возьмите пирожок и погладьте себя по голове. Я подожду.

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

Вкратце, в этом уроке мы говорили о следующем:

  • Как отображаются разные элементы.
  • Что такое блочная модель и почему она так важна.
  • Как изменить размер элементов с учётом высоты и ширины.
  • Как добавить к элементам margin, padding и border.
  • Как изменить размер элементов и влияние блочной модели.

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

Ресурсы и ссылки

  • The CSS Box Model via CSS-Tricks
  • HTML Borders via Quackit.com

#статьи

  • 23 янв 2023

  • 0

Большой гайд для тех, кто хочет правильно находить и выбирать элементы при вёрстке.

Иллюстрация: Оля Ежак для Skillbox Media

Антон Сёмин

Пишет об истории IT, разработке и советской кибернетике. Знает Python, JavaScript и немного C++, но предпочитает писать на русском.

Удачный выбор селектора не только позволяет избежать ошибок в коде, но и упрощает вёрстку, поэтому желательно знать разновидности селекторов и хорошо в них ориентироваться. Эта статья будет полезна как новичкам, так и опытным фронтенд-разработчикам и верстальщикам, которые хотят освежить знания.

Содержание

  • Что такое CSS-селекторы
  • Основные виды селекторов
  • Селекторы отношений
  • Селекторы по атрибуту
  • Немного о псевдоклассах
  • Как определить приоритет селектора

Селектор (от англ. select — выбирать) — это шаблон, который позволяет обратиться к элементу или группе элементов веб-страницы, чтобы применить к ним стили CSS. Его указывают перед блоком со свойствами:

a {
		text-decoration: none;
  }

В примере выше селектор указывает на тег <a> (гиперссылка). Так мы говорим браузеру отключить подчёркивание у всех ссылок на странице, устанавливая для свойства text-decoration значение none.

Подключим CSS-стили к следующему HTML-файлу:

<p>Содержание статьи:</p>
	<ul>
		<li><a href="#">Emmet на практике: пишем HTML</a></li>
		<li><a href="#">Создаём шапку документа</a></li>
		<li><a href="#">Подключаем стили и скрипты</a></li>
		<li><a href="#">Добавляем ссылки</a></li>
		<li><a href="#">Вводим теги</a></li>
	</ul>

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

Страница в браузере
Скриншот: Skillbox Media

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

Та же страница, но ссылки не подчёркнуты
Скриншот: Skillbox Media

CSS-селектор работает! Но это, конечно, далеко не единственный способ обращения к элементам.

О том, как подключить CSS к HTML, читайте в другой нашей статье.

Структура реальных проектов гораздо сложнее. Веб-страницы интернет-магазинов, корпоративных сайтов и блогов наполнены множеством вложенных и однотипных элементов — всем нужно задать уникальный дизайн. Если бы мы могли обращаться к ним только по названию, то даже с CSS веб оставался бы хранилищем скучного гипертекста.

К счастью, есть около 20 способов выбрать нужный элемент. Рассмотрим основные.

Он применяет стили ко всем элементам страницы и обозначается символом * (звёздочка). С его помощью удобно сбрасывать отступы и задавать значение box‑sizing для всех блочных элементов:

* {
  margin: 0;
  box-sizing: border-box;
}

Этот селектор CSS применяет стили ко всем элементам с одинаковым тегом. Например, для всех <div>, <h2>, <p> и так далее.

Мы уже познакомились с ним, когда убирали подчёркивание у ссылок:

a {
		text-decoration: none;
  }

Селектор по идентификатору обозначается символом # (решётка) и применяет стили к элементу, для которого задан атрибут id с соответствующим значением. При этом у элемента может быть только один id, и этот id должен быть уникальным в пределах веб-страницы.

<p id="intro">Сегодня мы расскажем вам об Emmet.</p> 
<p id="article_content">В этой статье вы узнаете:</p>

CSS-код:

#intro{
		color: red;
		font-weight: bold;
	}

#article_content{
		font-family: sans-serif;
		font-weight: bold;
	}

Текст в блоке p с идентификатором intro окрасится в красный, а текст с идентификатором article_content выделится жирным и получит шрифт без засечек:

Скриншот: Skillbox Media

CSS-селектор по классу выбирает элементы, для которых назначен атрибут class с соответствующим значением. При этом один элемент может принадлежать нескольким классам — в таком случае их перечисляют через пробел:

<p class="plain_text article">Сегодня мы расскажем вам про Emmet.</p> 

Абзац входит в классы plain_text и article. Значит, к нему применяются стили обоих классов:

.plain_text{
		font-size: 20px;
	}

.article{
		font-family: "Montserrat"; 
	}

CSS-селекторы можно сгруппировать, чтобы применить стили к нескольким группам и/или классам элементов. Для этого достаточно перечислить их через запятую:

.plain_text, p, h1, figure, div {
    margin-top: 0;
    margin-left: 0;
}

re>

Есть группа селекторов, которые позволяют выбрать элемент по его отношению к другим элементами (родитель — потомок) и по расположению в DOM (Document Object Model).

Чтобы обратиться ко всем потомкам В элемента A, независимо от уровня их вложенности, используют конструкцию A B (селекторы разделяют пробелом):

figure img {
    margin-bottom: 20px;
}

В примере выше мы устанавливаем всем изображениям внутри элемента figure значение нижних отступов 20 пикселей.

Если нужно применить CSS-стили к потомкам B элемента A только на первом уровне вложенности, то вместо пробела пишут символ >:

.container > img {
    margin-bottom: 40px;
}

Здесь мы задали изображениям внутри контейнера с классом .container значение нижних отступов 40 пикселей.

Селектор A ~ B выбирает все элементы B, которые идут после A. Обратите внимание: «идут после», а не вложены в него. Например, так мы задали цвет фона #f2f3f5 всем карточкам, которые идут после блока из класса .about_us:

.about_us > .card {
    background-color: #f2f3f5;
}

Селектор A + B выбирает только первый элемент B, который следует за A:

.about_us + .card {
    background-color: #f2f3f5;
}

В этом примере цвет фона #f2f3f5 установится только для той карточки, которая идёт сразу после .about_us.

Ещё один полезный инструмент — селекторы по атрибуту. Они позволяют выбрать элемент по имени атрибута, его значению или части значения. Кратко расскажем обо всех.

Применяет стили к элементам, для которых задан этот атрибут:

[title] {
		font-weight: bold;
	}

Работает по имени и значению атрибута:

[title="what_is"] {
		font-weight: normal;
	}

Находит элементы с заданным атрибутом, значение которого начинается с value:

[class^="form"] {
		background-color: #7aacba;
	}

Ищет по названию атрибута и значению, которое равно или начинается с value:

[class|="form"] {
		border: 5px outset black;
	}

Применяет CSS-стили к элементам, у которых значение заданного атрибута оканчивается на value:

[class$="primary"] {
		font-weight: bold;
	}

Селектор по названию атрибута и значению, которое должно содержать value:

[class$="control"] {
		padding: 15px;
	}

Этот шаблон выбирает элементы с атрибутом attr, значение которого состоит из нескольких слов, разделённых пробелом, одно из которых — value:

[class$="control"] {
		padding: 15px;
	}

Псевдокласс выбирает элементы, находящиеся в определённом состоянии или положении в иерархии DOM.

Вот несколько примеров таких состояний:

  • на кнопку наведён курсор мыши;
  • пользователь перешёл или не перешёл по ссылке;
  • курсор установлен на поле ввода.

Например, так с помощью CSS можно увеличить размер ссылок, на которые пользователь навёл курсор:

a:hover {
		font-size: 20px;
	}

Вот как это выглядит в браузере:

Изображение: Skillbox Media

А в следующем примере мы добавляем нижний отступ последнему параграфу-потомку контейнера («Параграф 3»).

<div class="container">
		<p>Параграф 1</p>
		<p>Параграф 2</p>
		<p>Параграф 3</p>
	</div>
	<p>Параграф 4</p>
	<p>Параграф 5</p>

CSS-код:

.container p:last-child {
  		margin-bottom: 30px;
	}

Если зайти в DevTools, то можно увидеть, что под третьим элементом p появилось поле margin (подсвечивается бежевым цветом):

Скриншот: Skillbox Media

Вот список основных псевдоклассов:

Название Состояние элемента
:hover Наведён курсор
:focus Элемент находится в фокусе (например, по нему кликнули мышью или его выбрали клавишей Tab)
:visited Ссылка, которая была посещена
:active Активный элемент (в промежутке времени между нажатием и отпусканием кнопки мыши)
:checked Элементы radio, checkbox или option, которые были выбраны
:first-child Первый потомок элемента
:last-child Последний потомок элемента
:nth-child() Каждый n-й потомок — число n передаётся в качестве аргумента
:last-nth-child() Последние n потомков — число n передаётся в качестве аргумента
:read-write Элементы, доступные для редактирования

Посмотреть другие псевдоклассы можно на сайте Mozilla.

Для одного и того же элемента веб-страницы можно прописать сколько угодно стилей. Если в разных местах CSS-файла какому-то его свойству заданы разные значения, то браузер должен выбрать одно из них.

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

Специфичность — это показатель, по которому браузер определяет, какие стили применить к элементу. Её можно представить в виде четырёх чисел 0.0.0.0, где каждый разряд — это вес, определяемый специальными правилами.

Вот эти правила:

  • Наивысший приоритет — у стилей, прописанных в атрибуте style (1.0.0.0).
  • На втором месте — селекторы по идентификатору (0.1.0.0).
  • Затем идут три равноправные группы: селекторы по классу, атрибуту и псевдоклассы (0.0.1.0).
  • На четвёртом месте — селекторы по тегу и псевдоэлементы (0.0.0.1).
  • Комбинаторы ~, >, + и универсальный селектор * веса не добавляют.
  • Вес псевдоклассов :is(), :has() и :not() равен весу самого специфичного селектора внутри скобок.

Чтобы определить самый «тяжёлый» селектор, браузер сначала взвешивает каждый, а затем сравнивает их поразрядно.

Попробуем порассуждать как браузер. Допустим, на странице есть элемент, на который указывают два CSS-селектора:

.container div ul  {/**/} 
#our_team div.developers  {/**/} 

Рассчитаем их вес:

  • Класс .container добавляет 1 в третий разряд, а div и ul — по единице в четвёртый. Результат: 0.0.1.2.
  • Идентификатор our_team добавляет 1 во второй разряд, тег div — 1 в четвёртый разряд, а класс .developers — 1 в третий. Получаем 0.1.1.1.

Браузер применит стили селектора #our_team div.developers, потому что он указывает на идентификатор (см. правило №2 в списке).

А если бы исследуемый элемент обладал атрибутом style, то и считать ничего бы не пришлось. Ведь, как мы уже знаем, style обладает наивысшим приоритетом:

<a style="color: red;" class="article media code" id="definition">Программист — это...</p>

А теперь секретный приём. Вы можете перебить любое правило, если добавите к нему ключевое слово !important. В таком случае стили намертво приклеятся к элементу:

a {
		font-weight: bold !important;
	}

После этого изменить начертание текста в ссылках можно будет, только если использовать !important в более специфическом селекторе. Например, таком:

#stronger a {
		font-weight: normal !important;
	}

Опытные разработчики не рекомендуют использовать !important, потому что это усложняет поддержку кода и ломает каскад. Поэтому просто помните о его существовании во время дебаггинга: возможно, это словечко спряталось где-то в документе styles.css.

CSS предоставляет большое количество селекторов для удобной стилизации веб-страниц. Запомните их и используйте всё разнообразие, чтобы писать понятный и легко поддерживаемый код. А закрепить знания можно в замечательной браузерной игре CSS Dinner.

Научитесь: Профессия Frontend-разработчик
Узнать больше

Понравилась статья? Поделить с друзьями:

Не пропустите также:

  • Как найти красивых котят
  • Как исправить плохое мелирование волос в домашних условиях
  • Как найти друга по вязанию
  • Как исправить розовый экран монитора на ноутбуке
  • Как найти файл терминале ubuntu

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии