Пользователь
0,0
рейтинг
10 июля 2014 в 10:42

Разработка → Адаптивная верстка с Restive.JS

Для начала хотел бы вам сказать, что моя специализация — это Backend, но версткой и клиентской частью приходится заниматься постоянно, особенно в своих проектах, которые я делаю в одиночку. Уже давно стало негласным правилом то, что сайт должен быть удобен на всех устройствах, включая всё их разнообразие, особенно в век популяризации мобильного интернета. Благо, CSS3 позволяет это делать при помощи медиа-выражений (media queries). Но есть еще один способ, показавшийся мне более удобным. В зависимости от размера экрана, его ориентации, типа устройства, устанавливать глобальные стили тегу html (можно и другим элементам). А в CSS, отталкиваясь от этих классов, задавать особые стили для разных случаев. Так CSS станет более понятным и мы избавимся от использования медиа-выражений. Для этого нам и понадобится Restive.JS. Так как я человек-практик, да и полное описание лучше читать на сайте плагина, то в статье я ограничусь созданием адаптивной мини-страницы, в процессе которого, надеюсь, станет понятно, для чего всё это необходимо.

Упорно искал статьи про Restive.JS на Хабре, но так и не нашел.

Принцип работы следующий. При смене ориентации или размера окна (а также при загрузке страницы) к выбранному элементу вашей DOM (рекомендуют html или body) добавляются глобальные классы. Это могут быть как стандартные классы, устанавливаемые Restive.JS (is_mobile, is_landscape и др.), так и ваши кастомные, устанавливающиеся при определенных условиях.

Подключение Restive.js

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
    <script type="text/javascript" src="restive.js"></script>
    <link rel="stylesheet" href="normalize.css">
    <link rel="stylesheet" href="styles.css">

    <script type="text/javascript">
        $(document).ready(function () {
            $('html').restive({
                breakpoints: ['320', '720'],
                classes: ['lt320', 'lt720'],
                turbo_classes: 'is_phone=phone,is_tablet=tablet,is_pc=pc,is_portrait=portrait,is_landscape=landscape'
            });
        });
    </script>
</head>
<body>
</body>
</html>


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

Вся конфигурация передается в конструктор в виде объекта, который должен содержать 3 основных элемента: breakpoints, classes, turbo_classes.

Breakpoints

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

Classes

А в этом массиве указываются классы для каждой точки. Точке с индексом N соответствует класс с индексом N. Т.е. длина этих массивов идентична. В нашем примере будет так: если ширина экрана пользователя <= 320, то установится класс lt320, от 321 до 720 — lt720, от 721 и выше — без класса.

Turbo classes

Без этого параметра Restive.JS не будет добавлять свои стандартные классы. По сути, это строка с перечислением классов, которые вы хотите отслеживать. Стандартные значения, которые можно отслеживать: is_mobile, is_phone, is_retina, is_tablet, is_pc, is_tv, is_portrait, is_landscape. Например, если вы зайдете на наше демо с iPhone, то установятся классы-алиасы mobile, phone, portrait (landscape).

Когда я открываю эту страницу на своём ноутбуке, то у html имеется только 2 класса: landscape и pc.

CSS для Restive.JS

Добавим немного контента нашему HTML. Это будет список, но на разных экранах в одну строку будет помещаться разное количество элементов списка. “Слишком простая задача”, скажете вы и будете правы. Но я хотел бы показать именно суть Restive.JS, до остального каждый доберется сам, благо, сложного ничего там нет. Еще сделаем проверку на устройство.

<div class="device device-phone">Phone</div>
<div class="device device-pc">PC</div>
<div class="device device-tablet">Tablet</div>

<ul>
    <li class="casablanca">Casablanca</li>
    <li class="moscow">Moscow</li>
    <li class="caracas">Caracas</li>
    <li class="dehli">Dehli</li>
</ul>


А вот так мы будем использовать классы-границы в CSS. По-моему, так намного понятней, чем использовать медиа-выражения (внимание, абсолютно субъективное мнение).

.device {
    display: none;
    width: 96%;
    font-size: 20px;
    padding: 2%;
    text-align: center;
    background: #eee;
}
.pc .device-pc,
.tablet .device-tablet,
.phone .device-phone {
    display: block;
}

ul {
    list-style: none;
    width: 100%;
    float: left;
    padding: 0;
    margin: 0;
}
li {
    width: 25%;
    height: 200px;
    line-height: 200px;
    font-size: 20px;
    float: left;
    text-align: center;
    color: #fff;
    background-position: cover;
}
li.casablanca {
    background: url(casablanca.jpg);
}
li.moscow {
    background: url(moscow.jpg);
}
li.caracas {
    background: url(caracas.jpg);
}
li.dehli {
    background: url(dehli.jpg);
}
.lt720 li {
    width: 50%;
}
.lt320 li {
    width: 100%;
}


Также в Restive.JS есть несколько удобных событий, которые могут быть особенно полезны (например, при смене ориентации телефона).

Открывайте Демо на разных устройствах, изменяйте экран и т.д.

Ссылки для дальнейшего изучения

Страница на GitHub
Официальная документация
Плютов Александр @plutov
карма
7,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

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

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

  • +3
    А какие у данного решения преимущества по сравнению аналогичными, не требующими jquery, вроде head.js?
    • 0
      В сравнении с head.js Restive.JS более узконаправленный плагин, именно для адаптивной верстки.
      • 0
        Ну фичи-то какие-то есть кроме добавления классов, кастомных брейкпоинтов и событий, раз спеуиализация такая узкая? Потому что учитывая отвязанность от jquery и модульного при прочих равных переходить на restive.js с head.js смысла я пока не вижу.
  • +5
    Я всё равно буду пользоваться media queries
    • +1
      .scr {
          float: left;
          display: inline-block;
          width: 25%;
      }
      
      @media screen and (max-width: 680px) {
          .scr {
              width: 50%;
          }
      }
      
      • 0
        .scr {
            float: left;
            display: inline-block;
            width: 25%;
        }
        
        .mobile .scr {
            width: 50%;
        }
        
      • 0
        // Sass
        
        .scr {
          float: left;
          display: inline-block;
          width: 25%;
        
          @media #{$medium-or-less} {
            width: 50%;
          }
        }
        
        • +1
          // Less
          
          .scr {
            float: left;
            display: inline-block;
            width: 25%;
          
            @media @mobile {
              width: 50%;
            }
          }
          
          • +2
            Ребята, вы в самом деле написали бы такой код?
            float: left; display: inline-block;
            • 0
              Нет) Это вопрос к lampa
      • 0
        display: inline-block; в этом примере лишний.
        Если задаётся float: left;, то элемент автоматически будет display: block;.
    • 0
      Насколько я понимаю, к достоинствам можно отнести:
      — верстка зависит от css-классов (дополнительный уровень абстракции) вся конфигурация находится в одном месте. Например, если вы захотите изменить значение минимальной ширины, то не нужно будет искать все media queries, где оно используется.
      — можно навешивать дополнительные классы (например, зависящие от ориентации экрана, типа устройства или браузера, ОС и т.д.). Например, вместо применения css-хаков для старых версий ie можно пометить контейнер классом и прописать стили для него.

      Как мне кажется, в небольших проектах потребность в таком функционале редко возникает. Я бы использовал media queries (чтобы не подключать в проект лишний скрипт). Но в проектах со сложной версткой такой подход может быть удобнее. Например, насколько я знаю, этот подход используют в outlook.com.
      • 0
        — давно есть утилитки, группирующие media queries
        — ну такое делать лучше через feature detection (f.e. modernizr)
  • +11
    Не очень понимаю чем не удобны media queries. Подключать лишний скрипт, чтобы подключить функциональность, которая уже есть…
    • 0
      … и вместо всего этого пользоваться LESS/SASS/..., делая запись и удобной, и приятной)
  • 0
    Вот интересно как рисуется адаптивный дизайн? Есть же какие-то правила для дизайнера, которые нельзя нарушать.
    • 0
      Самое первое из их длинного списка правил: Не пытайся впихнуть невпихуемое.
  • +1
    Я рекомендую руководствоваться следующими принципами:
    — за одну сессию устройство сменить нельзя, а ориентацию можно;
    — пользователь не должен ждать загрузки стилей / отрисовки страницы при смене ориентации экрана.

    Решение такое:
    — определяем на сервере устройство;
    — отдаем стили для различных ориентаций в одном файле;
    — на продакшене стили лежат исключительно в CSS;
    — а при разработке использовать переменные, а-ля $device и миксины а-ля tablet_p.

    .bla {
    	// common style
    	
    	@if $device == desktop {
    		// style for desktop
    		}
    
    	@if $device == tablet {
    		// style for tablet portrait
    		
    		@include tablet_p {
    			// style for tablet portrait
    			}
    		
    		@include tablet_l {
    			// style for tablet landscape
    			}
    		}
    	}
    
    
  • 0
    Аналогичное решение. Только подход с другого боку.

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