Bootstrap 3 - Изменение порядка следования адаптивных блоков в макете

Александр Мальцев
114K
1
Bootstrap 3 - Изменение порядка следования адаптивных блоков в макете
Содержание:
  1. Классы push и pull
  2. Пример использования классов push и pull
  3. Рекомендации по разработке макета с помощью сетки Bootstrap
  4. Комментарии

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


Фреймворк Bootstrap содержит большое количество классов и компонентов. Но перед тем как переходить к наполнению сайта этими элементами, необходимо сначала создать каркас (макет) страницы. Данное действие в Bootstrap выполняется с помощью «строительных» элементов сетки. К этим элементам относятся обёрточные контейнеры, ряды, адаптивные блоки и др. Более подробно ознакомиться с этими элементами можно в статье «Bootstrap 3 – Сетка».

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

Классы push и pull

Классы push и pull предназначены для изменения порядка следования адаптивных блоков для конкретных типов устройств в пределах некоторой строки. Это означает, что адаптивные блоки на одном устройстве могут иметь один порядок следования, а на другом другой.

Классы push и pull должны использоваться вместе с классами сетки Bootstrap. Класс push выполняет смещение адаптивного блока на определённое количество колонок вправо, а класс pull - на определённое количество колонок влево.

Синтаксис классов push и pull:

col-{breakpoint}-push-{nc}
col-{breakpoint}-pull-{nc}

{breakpoint} - тип устройства (xs, sm, m или lg)
{nc} - количество колонок (по умолчанию 0...12)

В следующей таблице показан синтаксис классов push и pull для различных размеров экрана.

Ширина viewport Классы push Классы pull
>0px (xs) .col-xs-push-{nc} .col-xs-pull-{nc}
>=768px (sm) .col-sm-push-{nc} .col-sm-pull-{nc}
>=992px (md) .col-md-push-{nc} .col-md-pull-{nc}
>=1200px (lg) .col-lg-push-{nc} .col-lg-pull-{nc}

Пример использования классов push и pull

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

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

Bootstrap 3 - Пример макета, в котором порядок следования блоков на разных экраных разный

Разработку макета начнём с устройств, имеющих маленький размер экрана (xs и sm):

<div class="row">
  <div class="col-xs-12">
    2 блок
  </div>
  <div class="col-xs-12">
    1 блок
  </div>
  <div class="col-xs-12">
    3 блок
  </div>
</div>

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

<div class="row">
  <div class="col-xs-12 col-md-6">
    2 блок
  </div>
  <div class="col-xs-12 col-md-3">
    1 блок
  </div>
  <div class="col-xs-12 col-md-3">
    3 блок
  </div>
</div>

Теперь изменим порядок следования адаптивных блоков. Для этого второй (2) адаптивный блок сдвинем вправо на 3 колонки, а первый (1) сдвинем влево на 6 колонок Bootstrap.

Bootstrap 3 - Пример использования классов push и pull
<!-- Boostrap 3 -->  
<div class="row">
  <div class="col-xs-12 col-md-6 col-md-push-3">
    2 блок
  </div>
  <div class="col-xs-12 col-md-3 col-md-pull-6">
    1 блок
  </div>
  <div class="col-xs-12 col-md-3">
    3 блок
  </div>
</div>

Рекомендации по разработке макета с помощью сетки Bootstrap

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

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

Комментарии ()

  1. Serega Novikov
    18 сентября 2017, 20:11
    А можно применять col-*-push-* БЕЗ указания в паре с ним класса col-*-pull-*? Наверное, если нет необходимости в col-*-pull-* для иного блока, то он и не нужен? То есть вопрос: col-*-push-* и col-*-pull-* обязательно ли должны идти в паре? Ну вот так «в одиночку» col-*-push-* возможен ли:
    <div class="row">
      <div class="col-md-4">
        <p>Левый блок</p>
      </div>
      <div class="col-md-4 col-md-push-4">
        <p>Правый блок</p>
      </div>
    </div>
    
    Дело в том, что ровно такой же результат (как и для col-*-push-* выше) можно получить col-*-offset-*. Но, наверное, именно col-*-offset-* нужно применять в данном случае?
    <div class="row">
      <div class="col-md-4">
        <p>Левый блок</p>
      </div>
      <div class="col-md-4 col-md-offset-4">
        <p>Правый блок</p>
      </div>
    </div>
    
    Наталкивает на такой вывод пример на сайте Бутстрапа, там именно в паре одновременное применение col-*-push-* и col-*-pull-* показано:
    Easily change the order of our built-in grid columns with .push-md-* and .pull-md-* modifier classes.
    <div class="row">
      <div class="col-md-9 push-md-3">.col-md-9 .push-md-3</div>
      <div class="col-md-3 pull-md-9">.col-md-3 .pull-md-9</div>
    </div>
    
    1. Александр Мальцев
      19 сентября 2017, 14:49
      Да, конечно можно. Просто когда вы используете offset, то данное действие осуществляется с помощью CSS свойства margin. А когда push и pull, то с помощью CSS свойств left и right.

      В примере их приводят вместе, чтобы показать, что с помощью них можно поменять местами адаптивные блоки Bootstrap в пределах линии, на которой они расположены. Если это не нужно, то можете их использовать по отдельности.
    2. Aleksey
      04 июня 2017, 19:04
      Добрый день, Александр
      Вы можете подсказать, почему у меня на тестовом сайте колонки ведут себя именно так?
      Колонки после заголовка «Новости»
      test.artsmm.ru/

      Где-то похоже ошибся, а где не могу понять
      Спасибо за ответ заранее)
      1. sergey
        12 марта 2017, 21:43
        Если трехколоночная верстка:
        блок 1, блок 2, блок 3
        Но если использовать CMS (Joomla или MODX), то, как сделать, чтобы колонка отображалась только тогда, когда в ней есть активные модули.
        Например, 1 и 2 блок отображаются, а третий только тогда когда в нём есть модуль.
        Есть такое или будет «дырка» в шаблоне?
        1. Александр Мальцев
          15 марта 2017, 17:21
          В MODX можно в сниппете написать логику, которая будет формировать не только внутреннее содержимое блока, но и внешнюю обёртку. Т.е. разработать простое условие, если данных нет, то и обёртки тоже. Или же использовать плейсхолдер, которому устанавливать значение в зависимости от некоторого условия. А в шаблоне, например, проверять это условие и формировать необходимый HTML-код. Вариантов можно придумать много, можно даже попробовать это сделать на клиенте с помощью JavaScript.
        2. Westus
          29 марта 2016, 06:13
          А как поменять местами 4 блока?
          На большом экране есть:
          1 2 3 4
          А на маленьком нужно получить:
          1 4
          2
          3
          1. Westus
            29 марта 2016, 07:02
            Разобрался. Просто в тексте явно не указано, что в col-md-push-3 цифра 3 означает на сколько столбиков нужно сместить.
          2. Владимир
            21 февраля 2016, 12:09
            Может кто подсказать. Есть верхнее меню. В нем пункты при больших разрешениях через pull-right добавлены вправо.
            При маленьких рахрешениях, нужно, чтобы эти элементы были слева, как это можно сделать?
            1. Александр Мальцев
              21 февраля 2016, 17:02
              А что Вам мешает его сделать с помощью стилей.
              1. Удалите у этого элемента данный класс.
              2. Добавьте к элементу некоторый идентификатор (например, myElem).
              3. Добавьте в CSS стиль:
              @media (min-width: 768px) {
                #myElem {
                  float: right !important;
                }
              }
              
              1. Владимир
                21 февраля 2016, 17:13
                Я так делал, не помогает, может быть я не там выставляю этот класс (у меня это testclass)?
                HTML-код:
                <div class="navbar navbar-fixed-top navbar-inverse" role="navigation">
                  <div class="container">
                    <div class="navbar-header">
                      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="sr-only">Toggle navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                      </button>
                      <a class="navbar-brand" href="#">test</a>
                    </div>
                    <div class="collapse navbar-collapse">
                      <ul class="nav navbar-nav testclass">
                        <li><a href="#">Пункт 1</a></li>
                        <li><a href="#">Пункт 2</a></li>
                        <li><a href="#">Пункт 3</a></li>
                      </ul>
                    </div><!-- /.nav-collapse -->
                  </div><!-- /.container -->
                </div><!-- /.navbar -->
                1. Александр Мальцев
                  22 февраля 2016, 05:47
                  Укажи вместо 768px нужную ширину.
                  1. Владимир
                    22 февраля 2016, 10:53
                    Указывал, тоже не помогает
            2. Лариса
              26 января 2016, 12:27
              большое спасибо за статью! очень помогла!
              1. linda
                19 марта 2015, 06:01
                Сразу говорю, я только начала изучать Bootstrap, читаю документацию. Поэтому, вопрос, может глупый… Но, не проще ли все сделать с помощью медиа=запросов @media only screen and (max-width: 480px) Так можно указать любую ширину, а не стандартные, все будет вынесено в .css файл. Или я что-то не так поняла?
                1. Александр Мальцев
                  20 марта 2015, 13:55
                  Давайте в качестве примера рассмотрим очень простую разметку, состоящую всего из 2 блоков. Т.к. разметка адаптивная, то она будет зависеть от ширины рабочей области окна браузера:
                  • На устройствах с очень маленькой шириной экрана (размер рабочей области до 768рх) блоки будет располагаться вертикально, и занимать всю ширину родительского элемента;
                  • На устройствах с маленьким размером экрана (размер рабочей области окна браузера больше 768рх и меньше 992рх) блоки будут располагаться горизонтально. При этом 1 блок будет занимать 42% от ширины родительского элемента, а 2 блок оставшиеся 68% ширины родительского элемента.
                  • На устройствах со средним экраном (ширина рабочей области окна браузера больше 992рх и меньше 1200рх) блоки то же будут располагаться горизонтально. Но при этом блоки будут иметь уже другую ширину: 1 блок будет занимать 33% от ширины родительского элемента, а 2 блок — 67%;
                  • На устройствах с большим экраном (ширина рабочей области окна браузера больше 1200рх) блоки будут располагаться аналогично, но ширина блоков уже будет следующей: 1 блок будет занимать 25% от ширины родительского элемента, а 2 блок — 75%.
                  На Bootstrap 3 данная разметка будет выглядеть следующим образом:
                  <div class="col-lg-3 col-md-4 col-sm-5 col-xs-12"></div>
                  <div class="col-lg-9 col-md-8 col-sm-7 col-xs-12"></div>
                  
                  А теперь, попробуйте создать данную разметку с помощью CSS.
                  Я сомневаюсь, что это будет так просто и быстро :)
                  1. Александр Мальцев
                    19 марта 2015, 17:02
                    Добрый день.
                    Фреймворк Bootstrap 3 состоит не только из классов, предназначенных для создания адаптивной разметки, но и многих других «вкусностей» которые значительно облегчают создание веб-интерфейсов.
                    Что касается разметки, то её конечно можно создать с помощью CSS, но это будет намного сложнее и займёт в разы больше времени. Но использование Bootstrap даёт не только плюсы, но, конечно же, и минусы. Один из них заключается в том, что файл CSS Bootstrap будет конечно «тяжелей» чем стили, разработанные под конкретный веб-проект.
                  2. nad
                    24 ноября 2014, 17:04
                    Спасибо большое за помощь!
                    Для тех, кто не знает js я «придумала» хитрый способ с помощью класса hidden:
                    <div class="row">
                      <div class="col-md-6 col-md-offset-6 hidden-xs">
                        <div class="video">
                          <div class="embed-responsive">
                            <iframe class="embed-responsive-item" src=""></iframe>
                          </div>
                        </div>
                      </div>
                      <div class="col-md-6 col-md-offset-6">
                        <div class="row">
                          <div class="col-xs-6"><a href=""><img src=""></a></div>
                          <div class="col-xs-6"><a href=""><img src=""></a></div>
                        </div>
                      </div>
                      <div class="col-md-6 col-md-offset-6 hidden-lg hidden-md hidden-sm">
                        <div class="video">
                          <div class="embed-responsive">
                            <iframe class="embed-responsive-item" src=""></iframe>
                          </div>
                        </div>
                      </div>
                    </div>
                    
                    1. Александр Мальцев
                      24 ноября 2014, 18:39
                      Вот решение на jQuery:
                      <script src="js/jquery-1.11.1.min.js"></script>
                      <script>
                      function windowSize(){
                        if ($(window).width() >= '975')
                        {
                          $('#block1').detach().insertAfter('#block2');
                        } 
                        else 
                        {
                          $('#block2').detach().insertAfter('#block1');
                        }
                      }
                      $(window).load(windowSize); 
                      $(window).resize(windowSize);
                      </script>
                      ...
                      <div class="container">
                        <div class="row">
                          <div class="col-md-offset-6 col-md-6 col-xs-12"> 
                            <div class="row">
                             
                              <div id="block1" class="col-xs-12">
                                <div class="video">
                                  <div class="embed-responsive embed-responsive-16by9">
                                    <iframe class="embed-responsive-item" src=""></iframe>
                                  </div>
                                </div>
                              </div>
                              
                              <div id="block2" class="col-xs-12">
                                <div class="row">
                                  <div class="col-xs-6"><a href="" target="_blank"><img src="" class="img-responsive"></a></div>
                                <div class="col-xs-6"><a href="" target="_blank"><img src="" class="img-responsive"></a></div>
                              </div>
                            
                            </div>
                          </div>
                        </div>
                      </div>
                      
                      1. Дмитрий
                        02 июля 2016, 09:03
                        Работа с DOM довольно дорогая по ресурсам. Поэтому, проще переверстать без js, я считаю
                    2. nad
                      24 ноября 2014, 16:26
                      Я прихожу к выводу, что если в одном блоке row находится два блока col-md-12, то поменять местами их нельзя?
                      1. Александр Мальцев
                        24 ноября 2014, 16:56
                        Только с помощью JavaScript.
                      2. nad
                        24 ноября 2014, 16:08
                        Извините, я плохо объяснила задачу, выкладываю картинку, чтобы было понятно.
                        1. nad
                          24 ноября 2014, 16:00
                          Картинка:
                          Порядок расположения блоков в Bootstrap
                          1. неуверенный
                            14 января 2016, 10:22
                            А по-моему можно, просто нужно сделать в первом варианте офсет, ну а дальше пуш и пул.
                            1. Александр Мальцев
                              24 ноября 2014, 16:56
                              С помощью классов push и pull так сделать не получится.
                              Решить такую задачу можно только с помощью JavaScript. Если такой вариант устраивает, то могу выложить решение этой проблемы немного попозже.
                            2. nad
                              24 ноября 2014, 15:33
                              Эти два блока должны стоять друг под другом справа на любых размерах экрана, а не в ряд — в этом то и проблема, и я не могу найти способ поменять их местами с помощью Bootatrap.
                              1. Александр Мальцев
                                24 ноября 2014, 16:02
                                А назначение места слева?
                                Может так:
                                <div class="col-xs-6">
                                  <!-- Место слева -->
                                </div>
                                <div class="col-xs-6"> 
                                  <div class="row">
                                    <div class="col-xs-12 block2">
                                      <div class="video">
                                        <div class="embed-responsive embed-responsive-16by9">
                                          <iframe class="embed-responsive-item" src=""></iframe>
                                        </div>
                                      </div>
                                    </div>
                                    <div class="col-xs-12 block1">
                                      <div class="row">
                                        <div class="col-xs-6"><a href="" target="_blank"><img src="" class="img-responsive"></a></div>
                                        <div class="col-xs-6"><a href="" target="_blank"><img src="" class="img-responsive"></a></div>
                                      </div>
                                    </div>
                                  </div>
                                </div>
                                
                                1. Александр Мальцев
                                  24 ноября 2014, 15:57
                                  Если у вас макет не изменяется, то зачем вам его переупорядочивать. Может тогда так:
                                  <div class="col-xs-offset-6 col-xs-6"> 
                                    <div class="row">
                                       <div class="col-xs-12 block2">
                                        <div class="video">
                                          <div class="embed-responsive embed-responsive-16by9">
                                            <iframe class="embed-responsive-item" src=""></iframe>
                                          </div>
                                        </div>
                                      </div>
                                      <div class="col-xs-12 block1">
                                        <div class="row">
                                          <div class="col-xs-6"><a href="" target="_blank"><img src="" class="img-responsive"></a></div>
                                          <div class="col-xs-6"><a href="" target="_blank"><img src="" class="img-responsive"></a></div>
                                        </div>
                                      </div>
                                    </div>
                                  </div>
                                  
                                2. nad
                                  24 ноября 2014, 14:23
                                  Я так понимаю, что pull и push действуют, если только элементы все лежат в одном row.
                                  1. Александр Мальцев
                                    24 ноября 2014, 15:17
                                    Да push и pull должны располагаться не просто в одном row, а в одной строке.
                                    Тут немного по-другому, нужно сначала правильно расположить блоки на маленьком экране, а уже потом переупорядочивать их для остальных экранов.
                                    Насколько понял, на маленьком экране сначала должен идти block2, а потом block 1. А на md block1, а потом block2.
                                    Только не понятно про смещение col-md-offset-6. Зачем оно?
                                    <div class="row">
                                      <div class="col-md-6 col-md-push-6 col-xs-12 block2">
                                        <div class="video">
                                          <div class="embed-responsive embed-responsive-16by9">
                                            <iframe class="embed-responsive-item" src=""></iframe>
                                          </div>
                                        </div>
                                      </div>
                                      <div class="col-md-6 col-md-pull-6 col-xs-12 block1">
                                        <div class="row">
                                          <div class="col-xs-6"><a href="" target="_blank"><img src="" class="img-responsive"></a></div>
                                          <div class="col-xs-6"><a href="" target="_blank"><img src="" class="img-responsive"></a></div>
                                        </div>
                                      </div>
                                    </div>
                                    
                                    1. nad
                                      24 ноября 2014, 15:29
                                      Да, блоки нужно поменять местами. col-md-offset — потому что на большом экране слева должно быть пустое место.
                                  2. nad
                                    24 ноября 2014, 14:21
                                    Извините, код такой.
                                    <div class="row">
                                      <div class="col-md-6 col-md-offset-6 col-xs-12 block1">
                                        <div class="row">
                                          <div class="col-xs-6">
                                            <a href="" target="_blank"><img src="" class="img-responsive"></a>
                                          </div>
                                          <div class="col-xs-6">
                                            <a href="" target="_blank"><img src="" class="img-responsive"></a>
                                          </div>
                                        </div>
                                      </div>
                                      <div class="col-md-6 col-md-offset-6 col-xs-12 block2">
                                        <div class="video">
                                          <div class="embed-responsive embed-responsive-16by9">
                                            <iframe class="embed-responsive-item" src=""></iframe>
                                          </div>
                                        </div>
                                      </div>
                                    </div>
                                    
                                    1. nad
                                      24 ноября 2014, 13:36
                                      А можно поменять местами не колонки (адаптивные блоки), а ряды?
                                      1. Александр Мальцев
                                        24 ноября 2014, 14:07
                                        Ряды (row) переупорядочивать нельзя.
                                        1. nad
                                          24 ноября 2014, 14:19
                                          Мне нужно на маленьком размере экрана поменять местами block1 и block2.
                                      Войдите, пожайлуста, в аккаунт, чтобы оставить комментарий.