Pull to refresh

Сетки без заморочек

Reading time 4 min
Views 79K
Original author: Chris Coyier
Подавляющее большинство сайтов создано с использованием сеточных макетов. Они могут не использовать их в явном виде, но если на сайте присутствует блок с основным контентом, расположенный справа, и боковой блок (сайдбар), расположенный слева, то это и есть простейшая сетка.

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

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

Обертка


Ширина обертки колонок равна ширине её родителя. Можем принять её ширину за 100%. Так как обертка не имеет никакого семантического значения, то для нее мы будем использовать простой div.
<div class="grid">
  <!-- 100% wide -->
</div>



Колонки


Давайте начнем с часто применяемого в практике макета, состоящего из: области с основным контентом шириной в 2/3 и бокового блока шириной в 1/3 (от ширины родителя). Для этого мы создадим два div'а с соответствующими классами:
<div class="grid">
  <div class="col-2-3">
     Main Content
  </div>
  <div class="col-1-3">
     Sidebar
  </div>
</div>


Чтобы расположить их рядом друг с другом мы устанавливаем им свойство float и задаем ширину. Float можно установить сразу нескольким колонкам вот так:
[class*='col-'] {
  float: left;
}

а ширина устанавливается индивидуально:
.col-2-3 {
  width: 66.66%;
}
.col-1-3 {
  width: 33.33%;
}


Вот и вся предпосылка к сеткам без заморочек.

Очистка потока


Так как наша обертка содержит только плавающие элементы (колонки с установленным свойством float), то его высота схлопывается до нуля (т.к. плавающие элементы не влияют на размеры родителя — прим. пер.). Чтобы исправить это, нужно очистить поток. В настоящее время достаточно добавить это:
.grid:after {
  content: "";
  display: table;
  clear: both;
}


Отступы между колонками


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

В качестве первого шага мы воспользуемся свойством box-sizing со значением border-box. Я люблю применять его ко всем элементам сразу.
*, *:after, *:before {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}


Теперь ни отступы, ни границы не будут влиять на размеры элементов.

В качестве второго шага мы устанавливаем фиксированный отступ с правой стороны всем колонкам, кроме самой последней.
[class*='col-'] {
  padding-right: 20px;
}
[class*='col-']:last-of-type {
  padding-right: 0;
}


Это все, что касается отступов между колонками в самом простом случае.

Внешние отступы


Нужны внешние отступы между колонками? Я использую для этого дополнительный класс:
<div class="grid grid-pad">
  Сетка с внешними отступами
</div>


Первым делом мы добавляем левый отступ обертке колонок (а также верхний и нижний отступ на ваше усмотрение):
.grid-pad {
  padding: 20px 0 20px 20px;
}


Затем вернем правый отступ последней колонке:
.grid-pad > [class*='col-']:last-of-type {
  padding-right: 20px;
}



Больше различных колонок


Это очень просто:
.col-1-2 {
  width: 50%;
}
.col-1-4 {
  width: 25%;
}
.col-1-8 {
  width: 12.5%;
}

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


Sass


Я не часто им пользуюсь, но весь наш код становиться более компактным благодаря SCSS/Compass:
* {
  @include box-sizing(border-box);
}

$pad: 20px;

.grid {
  background: white;
  margin: 0 0 $pad 0;
  
  &:after {
    /* Or @extend clearfix */
    content: "";
    display: table;
    clear: both;
  }
}

[class*='col-'] {
  float: left;
  padding-right: $pad;
  .grid &:last-of-type {
    padding-right: 0;
  }
}
.col-2-3 {
  width: 66.66%;
}
.col-1-3 {
  width: 33.33%;
}
.col-1-2 {
  width: 50%;
}
.col-1-4 {
  width: 25%;
}
.col-1-8 {
  width: 12.5%;
}

/* Opt-in outside padding */
.grid-pad {
  padding: $pad 0 $pad $pad;
  [class*='col-']:last-of-type {
    padding-right: $pad;
  }
}


Модули


При работе с такими сетками я люблю использовать «модули».
<div class="grid">
  <div class="col-2-3">
     <article class="module">
        stuff
     </article>
     <article class="module">
        stuff
     </article>
  </div>
  <div class="col-1-3">
    <aside class="module">
       Sidebar stuff. Sub modules?
    </aside>
  </div>
</div>


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

Результат


Демонстрацию результата можно посмотреть здесь.

Разборки с браузерами


Код работает отлично в IE 9 версии и выше, а также во всех остальных браузерах. Если вам нужен IE7, то займитесь чем-нибудь другим.

(Следует отметить, что в Опере поддержка дробных значений процентов появиласть только в 12 версии. — прим. пер.)

К слову, модель «гибких блоков» (flexbox, flexible box) в будущем упростит реализацию сеточных макетов и даже улучшит её (самым разным образом, включая возможность перестройки колонок по первому требованию). Но я думаю, что нам потребуется ещё около года, чтобы могли начать хотя бы думать об использовании «гибких блоков».

Информация по теме


Посмотрите сетки из фреймворка OOCSS.

Решение для IE8 (добавление от переводчика)


В оригинальной статье автор указал на то, что этот метод отлично работает в Internet Explorer 8 версии. Но он ошибся, т. к. IE8 не поддерживает псевдокласс :last-of-type. Зато он поддерживает псевдокласс :first-child который и поможет нам решить эту проблему.

В CSS меняем :last-of-type на :first-child и вместо правых отступов у колонок устанавливаем левые:
[class*='col-'] {
  padding-left: 20px;
}
[class*='col-']:first-child {
  padding-left: 0;
}

И подобным же образом правим код для вешних отступов:
.grid-pad {
  padding: 20px 20px 20px 0;
}
.grid-pad > [class*='col-']:first-child {
  padding-left: 20px;
}
Tags:
Hubs:
+41
Comments 66
Comments Comments 66

Articles