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

Original author: Nick La
  • Translation
  • Tutorial
При создании колонок обычно приходится применять специальные CSS-классы к первому и последнему элементу. В этой статье рассказано о небольшом трюке, который упрощает верстку колонок, а также делает их адаптивными.

Суть метода сводится к использованию псевдокласса nth-of-type: количество и ширина колонок меняется на экранах разных размеров (Демонстрация).

Недостатки использования классов для первого и последнего элементов


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



Использование nth-of-type


Выражение :nth-of-type(An+B) помогает очень легко очистить float'ы и отступы элементов, например:
  • .grid4 .col:nth-of-type(4n+1)— каждый четвертый элемент .col начинается с новой строки
  • .grid2 .col:nth-of-type(2n+1) — каждый второй элемент .col начинается с новой строки



.grid4 .col:nth-of-type(4n+1),
.grid3 .col:nth-of-type(3n+1),
.grid2 .col:nth-of-type(2n+1) {
	margin-left: 0;
	clear: left;
}


Добавление адаптивности


Для того, чтобы страница стала адаптивной, используем media queries, все значения в процентах:

/* col */
.col {
	background: #eee;
	float: left;
	margin-left: 3.2%;
	margin-bottom: 30px;
}

/* grid4 col */
.grid4 .col {
	width: 22.6%;
}

/* grid3 col */
.grid3 .col {
	width: 31.2%;
}

/* grid2 col */
.grid2 .col {
	width: 48.4%;
}


Вот как происходит переход с четырехколоночной на трехколоночную сетку при изменении размера окна (менее 740px):
  • Меняется .grid4 .col, если ширина становится менее 31,2% (треть всей ширины окна)
  • Сбрасывается левый отступ
  • Переопределяется левый отступ с помощью nth-of-type(3n+1) для создания трехколоночной сетки



@media screen and (max-width: 740px) {
	.grid4 .col {
		width: 31.2%;
	}
	.grid4 .col:nth-of-type(4n+1) {
		margin-left: 3.2%;
		clear: none;
	}
	.grid4 .col:nth-of-type(3n+1) {
		margin-left: 0;
		clear: left;
	}
}


Переход с четырехколоночной и трехколоночной на двухколоночную сетку происходит при ширине окна менее 600px:

@media screen and (max-width: 600px) {
	/* change grid4 to 2-column */
	.grid4 .col {
		width: 48.4%;
	}
	.grid4 .col:nth-of-type(3n+1) {
		margin-left: 3.2%;
		clear: none;
	}
	.grid4 .col:nth-of-type(2n+1) {
		margin-left: 0;
		clear: left;
	}

	/* change grid3 to 2-column */
	.grid3 .col {
		width: 48.4%;
	}
	.grid3 .col:nth-of-type(3n+1) {
		margin-left: 3.2%;
		clear: none;
	}
	.grid3 .col:nth-of-type(2n+1) {
		margin-left: 0;
		clear: left;
	}
}


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

@media screen and (max-width: 400px) {
	.col {
		width: 100% !important;
		margin-left: 0 !important;
		clear: none !important;
	}
}


Работа в Internet Explorer


В Internet Explorer версии 8 и младше не поддерживается media queries и nth-of-type. Для решения этой проблемы можно использовать selectivizr.js (фикс nth-of-type) и respond.js (фикс media queries). к сожалению selectivizr.js и respond.js не очень хорошо работают вместе: nth-of-type не будет работать внутри media queries.
Ads

Comments 35

    +11
    Забудьте про эмуляцию Media Queries в IE, они там не нужны.
      +1
      Спасибо, пригодилось.
        +1
        Ух ты. А вот это весьма полезно, а то наш верстальщик как-то несколько костыльно сделал.
        Спасибо, Кирилл!
          +1
          Действительно современное и элегантное решение. Плюсую автора.
            +1
            Очень грамотно. А главное — более чистый HTML.
            • UFO just landed and posted this here
                +3
                А поделились с общественностью?
                  +1
                  То есть это решение давно устарело и теперь у вас есть более правильное?
                  • UFO just landed and posted this here
                  +1
                  Именно так и решил задачу, когда с ней столкнулся. Спасибо, что разложили по полочкам.

                  Добавлю, что между selectivizr и Respond.js были успешные попытки заставить их работать вместе в IE<9 (примеры: раз, два), но, к сожалению, до production- ready решения дело не дошло. :( Если дружите с JavaScript, можно попробовать этот хак.
                    0
                    Использовать «!important» — плохая практика.
                      0
                      Я не верстальщик, конечно, но всё же… А не проще ли в этом случае использовать display: inline-block?

                      В этом случае вообще никаких заморочек с адаптивностью нет.

                      Просто давеча была об этом статья…
                      • UFO just landed and posted this here
                          0
                          Дык, между колонками в схемах автора всё равно есть некий марджин. Так что в данном случае пробелы мне не кажутся проблемой… Вопрос лишь в том, как в этом случае правильнее/удобнее регулировать расстояние между колонками…
                          • UFO just landed and posted this here
                              +1
                              Колоночная верстка на inline-block по определению требует удаления пробелов между блоками в HTML-коде.

                              Если у вас там пробелы, you're doing it wrong.

                              Если пробелов нет, то и недостатка у данного метода нет.
                            • UFO just landed and posted this here
                              • UFO just landed and posted this here
                                • UFO just landed and posted this here
                                  0
                                  Ну как это не готов. 65% пользователей его смогут оценить.
                                  • UFO just landed and posted this here
                                      0
                                      Можно для новых браузеров сделать поддержку через @supports, старые браузеры этот код будут игнорировать.
                                      • UFO just landed and posted this here
                                          0
                                          Ну это в любом случае, без фоллбэка применять flexbox слишком опасно.
                                          • UFO just landed and posted this here
                                              0
                                              Использовать полифилы в современном вебе плохо, вместо этого надо верстать так что сайт выглядит хорошо в старых браузерах и отлично в современных. К старым я отношу IE8 и 9.
                                              • UFO just landed and posted this here
                                                  0
                                                  Я пока не встречал быстрых полифилов, особенно если их примнять на тяжёлых страницах. Как в примере с флекбоксом можно вообще убрать колонки и оставить элементы списком для старых браузеров. Это так же читаемо и не тормозит.
                                                  • UFO just landed and posted this here
                                        0
                                        Не пугайте людей. Вы привели акумулированную статистику за весь год, а за 12 месяцев ситуация все таки изменилась: мир, РФ.
                                        0
                                        Спецификация flexbox недавно была существенно переделана.

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

                                        Полифилл Flexie.js и SASS-тулкит Compass работают с устаревшей версией flexbox.

                                        Пруфлинк (август 2012): css-tricks.com/old-flexbox-and-new-flexbox/

                                        Так что до использования flexbox в деле еще пока очень далеко. :(
                                        • UFO just landed and posted this here
                                          • UFO just landed and posted this here
                                    0
                                    Хм, я использовал как раз inline-block и сабж применял для отмены margin'а у последнего элемента в строке.

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

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