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

Автор оригинала: 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;
}
Поделиться публикацией

Комментарии 66

    +2
    Приятное решение под современные браузеры.
    Опера не учтена, так как ее процент на рынке США ничтожен.

    Но что-то меня все равно смущает…
      +18
      Даже нашла что смущает!!!

      :last-of-type — поддержка начинается с ИЕ9. Как, простите, это отлично работает в ИЕ8? 0_о
        +3
        Спасибо за замечание. Добавил решение для IE8.
      +2
      Ну когда же CSS разовьётся настолько, чтобы в HTML коде не нужны были обёртки, да и вообще какие-то ссылки на вёрстку типа class=«col-2-3»? Вопрос риторический…
        +5
        Уже близко к этому. Модуль CSS Flexible Box Layout уже решено перевести в статус Candidate Recommendation, что позволяет реализовывать его уже без префиксов. Впрочем ещё браузеры ещё не соответствуют последней редакции, кроме альфы Хрома и, отчасти, превью IE10.

        Вслед идёт предложенный Майкрософтом модуль CSS Grid Layout, который позволяет делать лучшее из того, что могут таблицы, но без их ограничений, таких как расположение в ряды и строгий порядок следования. Поддерживается пока только в превью IE10.

        Лет через 3–5 можно будет уже вовсю пользоваться. Предполагали ли вы три года назад, что можно будет пользоваться градиентами, тенями, трансформациями и анимациями?
          +2
          Не испытывал нужды :) Вот раскладка и скругленные уголки — это да.
          Спасибо за инфу о CR — как-то пропустил.
            +1
            К сведению, в Flexbox есть даже пример №5 к свойству «order» как раз про колоночную раскладку.
        +2
        Можно пойти дальше и извратиться — уместить сетку в твит:

        [class*=_]{float:left;box-sizing:border-box}._{width:100%}._1{width:16.67%}._2{width:33.33%}._3{width:50%}._4{width:66.67%}._5{width:83.33%}
        

        Пример использования.
          0
          класс! :)
          –1
          One Line CSS Grid
          .oh,.ot,.tt{float:left;padding:0 2% 2% 0;width:48%}.ot{width:31%}.tt{width:65%}.cl{clear:both}
          
            –2
            Очередная попытка применить плавающие элементы (float) для сеточной верстки. Да, дельфинов можно научить ползать по песку, но зачем? Так и с плавающими элементами — вместо того, чтобы заставлять их плавать по песку одинаково в разных браузерах, лучше использовать предназначенные для этого таблицы.
            В итоге — статья ни о чём. Чисто поездить по мозгам начинающим html-верстальщикам. Потом эту дурь из них фиг выбьешь.
            Единственный правильный способ верстки многоколоночных макетов — это сетка, она же таблица.
            Пока массово не внедрили grid-верстку из CSS3, единственным правильным способом нормальной html-верстки таких остаются html-таблицы (<table>). Да, это несемантично, зато работает именно так, как нужно, во всех браузерах без каких-либо шаманств. Господа инженеры, оставьте семантику гуманитариям! Ваша задача — сделать так, чтобы работало! Плавающие элементы — они для плавающих элементов.
              +1
              Таблица говорите? Ну ок, сделайте так, чтобы центральная, она же основная, колонка шла первой. Это реальное требование.
                –6
                Реальное требование — это попиксельная верстка, потому что иначе извращения дизайнера разваливаются.
                Гуманитарные 66% и 33% это НЕ попиксельная верстка.
                Даже если вы сделаете 66.66666 и 33.3333% — это всё равно НЕ попиксельная верстка. Возьмите любой браузер, особенно ИЕ, и подёргайте за правый нижний угол, изменяя размеры окна. Ну надо же, плавающие элементы начнут плавать! ВНЕЗАПНО!
                Google
                Yandex
                Facebook
                Twitter
                ВКонтакте
                ЖЖ
                Amazon
                Озон
                EBay
                все эти сайты ВНЕЗАПНО так или иначе используют <table> для верстки, а не для семантики.
                Потому что их делали инженеры, а не гуманитарии с их width: 66%
                  +1
                  Попиксельная вёрстка ни разу не реальное требование. Каприз, может быть.

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

                  Если заказчик этого ещё не знает, то быстро понимает, стоит объяснить что к чему. А где же ваше решение на таблицах?
                    –1
                    Да-да, расскажите про нереальность попиксельной верстки маркетологам, которые наняли крутых дизайнеров :)
                    PS. Если вы вдруг не в теме, «крутые дизайнеры» на фриланс-биржах зарабатывают в 5-10 раз больше «крутых программистов». Соответственно, сменить программиста или верстальщика, который начинает что-то бормотать про несемантичность, в 5-10 раз дешевле, чем сменить дизайнера, который к тому же согласовал дизайн с биг-боссами.
                      +1
                      А причём тут несемантичность? Попиксельная вёрстка — это картинка.
                        –1
                        Попиксельная верстка — это картинка в браузере биг-босса. Она либо есть, либо нет. И заранее неизвестно, будет ли она на ведроиде, ыпаде или fullHD мониторе.
                  • НЛО прилетело и опубликовало эту надпись здесь
                      0
                      Типа того. А вы попробуйте!
                      • НЛО прилетело и опубликовало эту надпись здесь
                          0
                          Ссылочку, где попробовать, можно?

                          Пожалуйста
                          • НЛО прилетело и опубликовало эту надпись здесь
                      0
                      Или лыжи не едут, или…
                      Открыл только гугл и фейсбук… и где там таблицы? — Все сделано исключительно на дивах.
                      • НЛО прилетело и опубликовало эту надпись здесь
                      0
                      А как же Responsive Design? Если на таблице такое и возможно сделать, то явно гораздо сложнее, чем на автономных блоках.

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

                        –4
                        Назовите хоть один действительно популярный сайт, ну скажем Aleksa Rank < 1 000 000, который использует новомодный Responsive Design?
                          +5
                          Ранг Алексы меньше миллиона, да?
                          Ваша самоуверенность граничит с полным невежеством.
                            0
                            В только чего ж оно таблицами-то сверстано?
                              0
                              Кэп подсказывает, что дизайну чуть ли не 10 лет.
                                0
                                А может это не дизайну 10 лет, а просто семантика << работоспособности в любых браузерах?
                                  0
                                  «Работает — не трогай». Тем более в такой бюрократической структуре, которая имеет множество других дел, заслуживающих внимания.
                            +1
                            Во первых: не новомодный, ему уже > 2 лет.

                            Во вторых: для сайтов в < 1 000 000 довольно сложно (а главное дорого) сделать редизайн и перенести всё накопленное содержимое в новые реали быстро и сразу.

                            В третьих: совсем немного примеров (что вспомнилось, остальное погуглите сами): iso.org. bostonglobe.com (подразделение The New York Times Company), smashingmagazine.com, starbucks.com…

                            Вы и в четвёртых (последнее но главное): ВНЕЗАПНО! — ни один из приведённых вами сайтов не использует таблицы для вёрстки !, а использует таблицы для вывода в них табличных данных.
                            Если лично вы до сих пор вы верстаете на уровне каменного века таблицами — не навязывайте свои заблуждения другим.
                              –1
                              Ну прежде чем что-то утверждать, вы откройте html-исходник того же yandex.ru, да?
                                –1
                                Но нет, зачем, какая разница, как именно сверстана поисковая строка Яндекса! Главное — вера в Бога Семантики!
                                • НЛО прилетело и опубликовало эту надпись здесь
                            0
                            А разве задача машинного чтения, ИИ, не связана с семантикой? Эти области тоже оставим гуманитариям?
                              0
                              Эээ, намного проще научить программы машинного чтения обнаруживать таблицы, используемые для верстки, чем заставить владельцев миллионов сайтов сверстать какой-нибудь хитрый дизайн без использования таблиц. Grid-layout как раз и придуман, чтобы решить эти трудности.
                              +7
                              > лучше использовать предназначенные для этого таблицы

                              Таблицы предназначены для вывода табличных данных. Шапка-содержимое-подвал — это не табличные данные. Не смешите людей своими выводами.
                                –5
                                В идеале — да, с этим никто и не спорит.
                                К сожалению, сеточную верстку придумали веке этак в XXVII-ом, а вот grid-layout в CSS до сих пор утверждают.
                                И пока этот самый grid-layout не станет для браузеров стандартом де-факто, HTML-таблицы останутся представлением по умолчанию для сеточной верстки в вебе. Нравится это семантистам-гуманитариям или нет.
                                Использовать плавающие элементы для сетки — это ересь и мракобесие. Оно совсем для другого предназанчено, вроде обтекания текстом картинки.
                                  +3
                                  Использовать плавающие элементы для сетки — это ересь и мракобесие.

                                  Равно как и использовать table для сетки.
                                    –5
                                    Пока нет массовой поддержки grid-layout, альтернатив table нету.
                                      +3
                                      Альтернатив полно, все они сходятся в одном — использование элементов или их стилей не по назначению.
                                        –4
                                        Да, давайте использовать несаментичные элеметны HTML+CSS (те же float), чтобы не использовать несематничные элементы вроде <table>!!!!
                                        • НЛО прилетело и опубликовало эту надпись здесь
                                    +1
                                    Предназначение у CSS одно — оформительское. Всё остальное только у вас в голове (в отличие от назначения элемента , описанного в спеке). Я имею полное право сделать поле рамкой, рамку тенью, а отступ смещением текста — если мне это нужно именно так. Так что хватит говорить глупости. Стабильность раскладки на плавающих блоках зависит только от кривизны рук.

                                    Не верите? Проверьте: доклад Василия Аксёнова «Сетки для всего» с РИТа. СКБ Контур — не последняя контора на российском рынке.
                                      0
                                      назначения элемента <table>, чёртов парсер
                                        –5
                                        Ну вот в этом и состоит отличие гуманитария от инженера.
                                        Гуманитарий ссылается на то, что где-то там написано некоторым другим признанным гуманитарием.
                                        Инженеру важно только то, как оно работает на практике.
                                        Проблема в том, что, в отличие от инженеров, гуманитарии умеют писать зажигательные тексты про то, как оно должно быть в идеальном мире. У многих инженеров тоже хватило бы на это мозгов, но увы — они сталкиваются с бесконечным списком «но» и «если», и их статьи становятся слишком скучными для гуманитариев.
                                          +3
                                          Мне, строго говоря, плевать на вашу систематизацию «инженер/гуманитарий» — я не вижу в ней никакого смысла. Просто я знаю все «за» и «против» табличного и плавающего методов и выбираю плавающий. Точка.

                                          Я-то глупый попытался показать вам успешный опыт, но вы же инженер! Голыми руками, без говна! (Хотя зачем-то сами ссылаетесь на опыт Alexa-100)
                                            –6
                                            Спасибо за попытку что-то мне показать, но успешный опыт — тут.
                                              +2
                                              Слезли бы с таблиц, глядишь — научились бы чему-нибудь новому.
                                                –2
                                                Чему, например? Написанию 50 строк кода CSS там, где не нужно и 10?
                                            0
                                            Быстро на личности перешли. А вот с аргументами туго. Домашняя работа не сделана.
                                          0
                                          Сорри, век конечно был XVII, а не XXVII :)
                                        +1
                                        При верстке таблицами сложно работать с функционалом сайта — блоки могут появляться и исчезать (не только при переходе по страницам, но и при обновлении данных Ajax'ом). Если убрать какую-то ячейку из таблицы, придется переписывать значения rowspan и collspan.

                                        Однако я тоже не очень дружелюбно отношусь к верстке плавающими блоками — стараюсь использовать где возможно inline-block
                                          0
                                          ЭЭЭ зачем обновлять rowspan и colspan? Типичный макет «шапка — три колонки — подвал» состоит из трех строк и трех столбцов. Что там у них внутре — вообще неважно и никак не влияет на внешнюю таблицу.
                                            +2
                                            Вот именно, что это типичный макет. А как насчет макета «Шапка — контент — три блока в одну строку — футер»?

                                            И как быть с таким:

                                            image
                                              –1
                                              И в чём проблема, если мы берем bootstrap и присваиваем соответствующие классы последовательным таблицам?
                                                0
                                                Делать три независящих друг от друга таблицы?
                                                  0
                                                  … и какая религия это запрещает?
                                        +2
                                        Мне одному кажется, что вместо
                                          <div class="col-2-3">
                                             Main Content
                                          </div>
                                          <div class="col-1-3">
                                             Sidebar
                                          </div>
                                        
                                        и
                                        [class*='col-'] {...}
                                        .col-2-3 {...}
                                        .col-1-3 {...}
                                        

                                        Лучше использовать
                                          <div class="col 2-3">
                                             Main Content
                                          </div>
                                          <div class="col 1-3">
                                             Sidebar
                                          </div>
                                        
                                        и
                                        .col {...}
                                        .col.2-3 {...}
                                        .col.1-3 {...}
                                        


                                        а вместо padding использовать margin, ведь padding — это внутренние отступы, а для отступов между элементами предназначен именно маргин?
                                          +1
                                          Можно и так. В вашем случае вы выделяете отдельный класс для всех колонок, а в статье для этого используются селекторы:
                                          [class*='col-'] {...}
                                          Тут наверное дело в привычке и целесообразности введения нового класса.

                                          В статье паддинги используются для эмуляции отступов. А вот маргины вместо паддингов тут использовать нельзя. У нас же колонки резиновые, а отступы фиксированные. Если мы сделаем маргины, то придется уменьшать колонки примерно как-то так:
                                          width: 66.6%-10px;
                                          Но CSS пока так не может.

                                          По-моему, отступы между колонок лучше делать через «модули». У колонок мы убираем паддинги, а модулям назначаем маргины:
                                          .module { margin: 0 10px; }
                                          +1
                                          И, кстати, поговаривают, что такие правила:

                                          *, *:after, *:before {...}
                                          

                                          негативно сказываются на скорости отрисовки страницы уже в самом браузере…
                                          • НЛО прилетело и опубликовало эту надпись здесь
                                            0
                                            Еще меньше заморочек с Gridset — gridsetapp.com
                                              0
                                              Лучший способ делать сетку увидел у Чикуёнка два года назад. Для пиксльной тоже подходит.
                                                0
                                                а в самом деле, что происходит с потерянной 0.01 %. это как-то сказывается, на больших мониторах, например?

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

                                                Самое читаемое