Статьи

Представляем GSS: таблицы стилей сетки

Возможно, вы недавно слышали о таблицах стилей сетки (GSS) в мире HTML и CSS. GSS переоценивает макет CSS и заменяет механизм компоновки браузера на тот, который использует Cassowary Constraint Solver . Те из вас, кто не понял ни слова об этом … привет и добро пожаловать!

СОБ обещает лучшее будущее. GSS обещает относительное расположение и размеры. GSS обещает центрировать любой элемент внутри другого с помощью одной строки кода. И GSS доставляет. Вопрос в том, как?

В этой статье я рассмотрю краткую историю GSS и углубленный обзор возможностей, которые она может предложить. Я также рассмотрю GSS для макетов на основе ограничений, алгоритм ограничений Cassowary и проведу вас через процесс установки и использования GSS.

Те из вас, кто предпочел бы не ждать, пока W3C или браузеры наверстают упущенное, я призываю вас остаться там и обратить пристальное внимание, пока я объясняю загадку, которая является GSS. На этой ноте давайте начнем с небольшой истории.

Краткая история

GSS — это создание The Grid с Дэном Токкини в качестве его основателя и генерального директора. Это объясняет, почему таблицы стилей, не основанные на сетке, называются таблицами стилей сетки.

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

Flexbox — одно из самых последних решений, но даже небольшие изменения требуют от вас углубления в HTML-контент и CSS-презентацию и внесения изменений.

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

По сути, GSS — это препроцессор CSS и среда выполнения JavaScript, которая использует Cassowary.js. Те из вас, кто еще не знает, Cassowary.js — это порт JavaScript, который Apple использует в Autolayout Cocoa .

И GSS, и Cassowary основаны на ограниченном программировании, что делает его идеальным для расширения возможностей декларативных языков, таких как CSS. Ограниченное программирование — это парадигма, с помощью которой веб-разработчики должны заявить «что» и оставить «как» до математического решателя.

Ограниченное программирование фокусируется на намерениях, а не на реализации.

Теперь, когда мы установили некоторую справочную информацию, давайте перейдем к функциям, которые предлагает GSS.

Обзор GSS

Одна из самых больших проблем с CSS — это относительность. Можно ожидать, что любой элемент CSS будет иметь бесконечный список свойств — отступы, высота, ширина, плавание, поля, границы, контуры — но ни одна из этой информации не говорит нам, где будет расположен элемент со ссылкой на другие элементы на странице ( или даже страницы в целом). Бесконечный список также не отвечает, где элемент будет отображаться с разными размерами экрана.

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

Поскольку мы уже обсуждали, что GSS использует Cassowary.js, здесь есть еще одна замечательная особенность GSS: элемент может быть центрирован внутри любого другого с помощью одной строки кода . Это делает много обходных путей ненужными и вещами прошлого.

Например, если вы хотите добавить кнопку «Подписаться» в вертикальной строке, скажем, с заголовком справа на странице вашего сайта, вы должны использовать следующий код:

.subscribe-button[right] == ::window[width]; .subscribe-button[center-y] == .header[center-y]; 

Еще одна особенность: GSS делает поплавки, ячейки таблицы, clearfix и горизонтальное / вертикальное центрирование устаревшими. Попрощайтесь с опасной ловушкой, которая является поплавком, потому что у нас есть сам W3C, говорящий, что поплавки не идеальны для макетов приложений.

«Поскольку веб-сайты превратились из простых документов в сложные интерактивные приложения, инструменты для разметки документов, например плавающие объекты, не всегда подходили для макета приложения».
W3C Grid Layout Module (рабочий проект)

А как насчет CSS-функций, таких как !important ? Четвертая особенность GSS делает нечто подобное: GSS использует иерархию ограничений, чтобы расставить приоритеты с преимуществами . Мы говорим о четырех встроенных уровнях силы здесь:

  • !weak
  • !medium
  • !strong
  • !require

Обратите внимание, что !require — это особая сила, которая гарантирует, что ограничение будет выполняться, а если нет, то все нарушается. Желательно использовать его осторожно и нечасто.

Уровень силы увеличивается вниз по списку, и более сильные ограничения получают более высокий приоритет во время выполнения. Давайте посмотрим на пример:

 #light[years] == 50 !weak; #light[years] == 20 !medium; #light[years] == 35 !strong; /* #light[years] will hold the value 35 */ 

Вы сделали это далеко, давайте теперь посмотрим на некоторые макеты на основе ограничений.

GSS для макетов на основе ограничений

Ограничения — это, по сути, отношения между двумя или более переменными, которые могут сохраняться или не сохраняться. Все числовые свойства элементов могут быть ограничены. Вот пример:

 p[line-height] >= 10; p[line-height] <= ::window[height] / 20; 
  • p называется selector
  • line-height — это свойство, для которого GSS будет вычислять значение для
  • [] используется для доступа к свойству
  • <= и >= определить ограничения неравенства
  • 10 и 20 — числовые значения в пикселях

В приведенном выше примере оба ограничения остаются в силе. Вот пример ограничений, которые не выполняются.

 #elementa[height] == 150; #elementb[height] == 150; #elementa[height] + #elementb[height] == 225; 

Первоначально оба элемента elementa и elementb должны иметь высоту elementb . В третьей строке сумма двух элементов составляет 225 пикселей. Следовательно, одно из ограничений двух элементов не будет выполнено.

Селекторы в GSS

Selectors в GSS — это запросы к группе элементов HTML, и они используются для определения элементов, которые в конечном итоге будут затронуты ограничением. Selectors важны, потому что вы должны выбирать и наблюдать элементы из DOM, прежде чем применять к ним ограничения.

Следующие фундаментальные selectors поддерживаются GSS.

 #elementID[height] == 150; /* id */ div[height] == 150; /* element */ .className[height] == 150; /* class */ 

Наборы правил в GSS

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

Этот вложенный набор правил:

 section < article { .aclass { height: == 150; } } 

Такой же как:

 (section < article .aclass)[height] == 150; 

Недвижимость в ГСС

Я уже рассмотрел свойства в приведенных выше примерах, но давайте посмотрим на них чуть подробнее. В GSS свойства — это переменные, которые принадлежат элементу. Когда мы используем свойства, которые известны CSS, их соответствующее значение, рассчитанное GSS, назначается как встроенные стили элемента.

Что-то вроде этого:

 .container { height: == #elm[height]; } 

Будет равно:

 .container { &[height] == #elm[height]; } 

Введение в алгоритм ограничения казуары

В GSS используется порт JavaScript (Cassowary.js) алгоритма решения линейных арифметических ограничений Кассовари, разработанный Badros, Borning and Stuckey, 1999. Алгоритм находит оптимальные решения для макетов на основе входных ограничений, заданных пользователем на естественном языке.

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

Вычислительные ограничения казуарного алгоритма

Решатель ограничений GSS называется алгоритмом Казуары. Этот алгоритм может вычислять только линейные ограничения (т. Е. В форме y = mx + c ). Основные операторы (+, -, *, /) поддерживаются алгоритмом. Умножение и деление двух (или более) ограниченных переменных не является линейным и, следовательно, приведет к ошибке.

 /* this expression is not linear */ #elementa[height] * #elementb[width] == newElement; 

Установка GSS

Для установки на стороне клиента установите через Bower:

 $ bower install gss 

Затем добавьте этот код в раздел <head> вашей разметки:

 <script src="/bower_components/gss/dist/gss.js"></script> <script type="text/javascript"> window.engine = new GSS(document); </script> 

Вы также можете скачать версию 2.0.0 через GitHub в виде zip-файла .

После установки GSS загрузите таблицы стилей .gss, добавив type=text/gss к тегу <link> :

 <link rel="stylesheet/gss" type="text/gss" href="my-first-gss-styles.gss"></link> 

Или используя элемент <style> :

 <style type="text/gss"> /* GSS code ... */ </style> 

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

Учебник для начинающих GSS

Примеры, которые я буду создавать, будут отображаться через CodePen, но я пройдусь по учебному пособию, как стандартный документ HTML. Сначала я добавлю следующую строку кода в свой HTML-код, чтобы добавить скрипт механизма GSS:

 <!-- GSS engine script --> <script src="gss.js"></script> 

Я буду использовать версию файла, размещенную на CodePen, но вы можете найти версию, размещенную на CDN, здесь . Затем я добавлю следующий код в сценарий ссылки GSS (строка, которую я только что добавил выше), чтобы передать GSS объект document .

 <!-- Giving GSS the document object --> <script type="text/javascript"> window.engine = new GSS(document); </script> 

Если вы предпочитаете, это может быть помещено в отдельный файл JavaScript, который включается после сценария движка.

Пример 1: Вертикальное центрирование элемента

Я создам div и вложу некоторый текст в теги h2 в макет GSS и добавлю это в HTML:

 <div class="foo"> <h2>When in doubt, use GSS.</h2> </div> 

После добавления некоторого базового стиля я могу добавить немного GSS для создания макета. Здесь начинается самое интересное.

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

Вот ограничения, которые я буду применять для достижения этой цели:

  • Используйте селектор ::window , чтобы центрировать элемент с видимой частью страницы в браузере.
  • Используйте атрибут ::[intrinsic-height] чтобы получить относительное значение height элемента, которое будет использоваться для определения относительной width .

Сначала я добавлю блок <style> в HTML с атрибутом type установленным в text/gss :

 <style type="text/gss"> </style> 

Блок <style> необходим для определения GSS, который я собираюсь добавить. Я собираюсь расположить элемент в центре экрана, добавив следующий код внутри тегов <style> :

 <style type="text/gss"> .foo { center: == ::window[center]; height: == ::[intrinsic-height]; width: == height / 2; } </style> 

И это все, что нужно. Элемент теперь центрируется (с динамической высотой) по вертикали с использованием GSS. Ниже приведена демоверсия:

Попробуйте полноэкранную демонстрацию и попробуйте изменить размер браузера по вертикали, чтобы элемент оставался по центру при любом размере окна.

Пример 2: Поворот элемента на основе динамического изменения ширины окна

В следующем примере я создам простую цветную квадратную форму и динамически вращаю ее. Сначала давайте загрузим GSS, добавив следующие строки кода в раздел <head> документа:

 <script> GSS_CONFIG = { worker: "/path/worker.js", useWorker: false, fractionalPixels: false } </script> <script src="/path/gss.js"></script> 

Обратите внимание, что вам придется отредактировать код выше, чтобы указать правильное расположение файлов. Вы можете получить файл worker.js здесь , а файл gss.js здесь .

Примечание. Из-за некоторых ошибок приведенные выше пути к файлам указывают на версии GSS, предшествующие 2.0.0, для того, чтобы это работало.

Теперь давайте создадим квадратную форму, добавив это в HTML:

 <div class="square"></div> 

… и добавьте немного стиля в CSS:

 .square { background: rgb(255, 0, 0); } 

Теперь я вернусь к HTML и добавлю некоторые ограничения GSS.

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

Вот ограничения, которые я буду применять для достижения этой цели:

  • Используйте селектор ::window[center] , чтобы центрировать элемент в видимой части страницы в браузере.
  • Используйте ::window[width] чтобы создать ограничение с помощью rotate-z , которое создаст эффект вращения элемента вокруг его оси z. Здесь значение, полученное из ::window[width] представляет степень поворота.

Я добавлю блок стиля в HTML с type text/gss , как я делал в первом примере. Помните, что блок style необходим для определения GSS, который я собираюсь добавить.

 <style type="text/gss"> </style> 

Я собираюсь связать квадратное поле с экраном, используя ограничения GSS, добавив следующий код в теги style :

 <style type="text/gss"> .square { center: == ::window[center]; rotate-z: == ::window[width]; size: == 175; } </style> 

И с этим все готово. Ознакомьтесь с финальной демонстрацией CodePen:

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

Будущее СОБ

Будущее GSS выглядит многообещающе. Пришло время двигаться вперед с использованием передовых технологий. Я советую вам потренироваться в прототипах меньшего масштаба, прежде чем разорвать всю библиотеку таблиц стилей.

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

Вы уже использовали GSS? Как прошел ваш опыт? Дайте мне знать в разделе комментариев.