К вопросу о типах форм в HTML5, регулярных выражениях и валидации форм на основе регулярных выражений. Философское рассуждение на ночь глядя.

Атрибут required

Наиболее простой способ реализации валидации html-форм - это добавить к

1
input(type="text")
атрибут
1
required
.

Данный атрибут сообщает браузерам, что содержимое поля ввода необходимо для заполнения. Теперь браузеры будут проверять содержимое поля ввода - то есть, выполнять его валидацию.

Заметьте - браузеры сами будут это выполнять, без какого-либо участия Javascript/jQuery с нашей стороны (это и есть одна из многогранных сторон HTML5).

В CSS3 для форм ввода разработаны два псевдо-класса:

  • :valid
  • :invalid

Оба псевдокласса предназначены для управления видом форм (

1
border
,
1
background
, помещения маркеров внутрь или снаружи формы) в случае валидности или невалидности содержимого этой формы.

Например, такой простейший код будет изменять фон поля ввода при валидности или невалидности содержимого:

&__input
  border 1px solid #ddd
  border-radius 5px
  padding 3px 10px

  &:valid
    background-color rgba(245,255,250,.5)

  &:invalid
    background-color rgba(220,20,60,.5)

Тут возникает законный вопрос - а каким образом браузер определяет, валидное или невалидное содержимое у этого поля?

В данном случае - очень просто и примитивно (для наглядности примера). Если поле не содержит никакого (любого) символа, то поле считается невалидным и браузер генерирует для данного поля псевдо-класс

1
:invalid
.

Если же поле содержит хотя бы один символ (любой - не обязательно текстовый), то данное поле уже считается валидным и браузер генерирует для этого поля псевдо-класс

1
:valid
.

Note! Содержимое атрибута

1
placeholder
не рассматривается браузером как содержимое формы. Другими словами, если поле ввода имеет атрибут
1
placeholder
с каким-то значением, то это поле будет считаться браузером все равно невалидным.

Типы input

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

Одним из таких способов фильтрации введенных данных является задание для элемента

1
input
его типа. Это также одна из “фишек” HTML5 и заключается она в том, что для поля ввода
1
input
можно указать, какого типа данные ожидаются в нем.

Например,

1
input(type=“email”)
говорит о том, что в это поле нужно вводить только адреса электронной почты;
1
input(type=“number”)
- только числа;
1
input(type=“tel”)
- только номера телефонов;
1
input(type=“date”)
- только дату;
1
input(type=“url”)
- только URL-адреса; и так далее.

Краткий список HTML5-типов

1
input
’ов:

  • email
  • number
  • tel
  • date
  • url
  • time
  • week
  • color
  • search

Эти различные типы input’ов в HTML5 - не просто блаж в угоду призрачной HTML-семантики, как я сам воспринимал их ранее. На самом деле - это именованные регулярные выражения.

Ну как - испугал я читателя? На самом деле регулярные выражения - это очень просто. Фактически - это набор символов, собранных воедино по определенному правилу и записанных в определенном синтаксисе.

Грубо говоря -

1
[1,2,3,4,5,6,7,8,9]
- это уже регулярное выражение. Если этому регулярному выражению присвоить имя
1
number
, то получится именованное регулярное выражение
1
number
.

Фактически типы

1
input
’ов, которые были рассмотрены выше - это именованные регулярные выражения, предустановленные разработчиками HTML5\браузеров.

И когда для элемента

1
input
устанавливается тип
1
type="email"
(к примеру), то этим фактом браузеру всего лишь указывается предустановленное регулярное выражение, которое браузер должен будет использовать при проверке введенных данных.

Вот я и подошел к самому интересному моменту - для чего нужны регулярные выражения? А нужны они для проверки введенных данных. Это маска, которую браузер накладывает на введенные пользователем данные. Совпала маска и данные - данные валидные; не совпала маска и введенные данные - данные невалидные.

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

Подключаются пользовательские регулярные выражения в HTML с помощью атрибута

1
pattern
и выглядит это таким образом (регулярное выражение для проверки IPv4-адреса):

input type="text" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"

Note! Использование пользовательского

1
pattern
совместно с любым HTML5-типом (email, date, range, tel, number и так далее) для элемента input почти никогда не имеет смысла по определению.

На этом все.


Обширная и достаточно сложная тема. Однако необходимая, если стоит задача изучить и иметь возможность работать в Git.

Эта тема касается отмены изменений в Git. Так как эта система контроля версий представляет из себя три ветки - рабочая директория, буфер, репозиторий - то будут рассмотрены все три способа.

Отмена изменений в рабочей директории

Для отмены изменений в рабочей директории необходимо выполнить одну команду:

git checkout -- name_of_file

Данная команда говорит Git вернуть состояние файла name_of_file до того, каким оно было зафиксировано в репозитории. Другими словами, произойдет сброс изменений файла в рабочей директории проекта.

Обязательным условием использования команды checkout является двойной дефис. Это “говорит” команде checkout, что в данном случае нужно оставаться в текущей ветке (branche).

Отмена изменений в буфере

Для отмены изменений в буфере нужно использовать команду:

git reset HEAD name_of_file

Эта команда “вернет” файл name_of_file из буфера в рабочую директорию.

Отмена изменений в репозитории

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

Нельзя просто так взять и изменить какой-либо определенный коммит - все они находятся в своеобразной цепочке и один коммит проистекает из предыдущего коммита.

Другими словами, у каждого коммита есть свой коммит-родитель и коммит-потомок. Изменить какой-либо коммит - это значит вырвать его из этой цепочки взаимосвязей. Тем самым нарушится целостность всего репозитория и работа Git также нарушится. Ведь дело в том, что сама суть системы контроля версий Git основана на такой взаимосвязанной цепочке коммитов - один коммит проистекает из другого, второй из первого, третий из второго и так далее.

Как же поступить в данной ситуации?

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

Опция amend

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

Соответственно, раз у этого коммита нет потомков, то изменение этого коммита не повлечет за собой нарушение целостности всей цепочки коммитов. Измениться только этот коммит - и только.

Изменить крайний коммит можно просто перезаписав его. Для этой цели служит ключ –amend. Команда в целом представляет из себя следующее:

git commit --amend -m "Add some commit"

Как только будет выполнена подобная команда, крайний коммит (тот, на котором находится указатель HEAD) будет перезаписан и это очень легко проследить - достаточно сравнить контрольную сумму SHA этого коммита до и после изменений.

Команда checkout

С помощью команды checkout можно выполнять откат репозитория до нужной версии. Данный способ основан на самом факте существования цепочки коммитов, в которой в роли узлов выступают сами коммиты.

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

Команда checkout может заставить указатель HEAD вернуться назад, на предыдущее место остановки - на предыдущий коммит. И необязательно этот коммит должен быть предыдущим - он может быть любым более ранним.

Все что для этого нужно - это указать тот коммит, к которому должен вернуться HEAD. Указать коммит просто - у каждого коммита есть уникальный идентификатор - контрольная SHA-сумма.

Команда возврата к нужному коммиту выглядит таким образом:

git checkout -- 4a2f59a32bd1074c42 name_of_file

Можно указать только часть SHA-суммы, так как это показано выше.

И тогда Git произведет сброс состояния (которые были сделаны в последнем коммите) файла name_of_file в буфер. Если ввести команду git status то увидим, что в буфере будут изменения, готовые для коммита. Это те самые изменения файла name_of_file, которые мы “выбросили” из репозитория.

Дальше выполняем “выброс” изменений файла name_of_file из буфера в рабочую директорию, чтобы мы смогли внести правки в этот файл:

git reset HEAD name_of_file

Все, что будет внесено в этот файл, а затем закоммичено - будет иметь уже другую контрольную сумму. А следовательно - это уже будет совсем другой коммит.

Зеркалирование коммитов

Одной из разнообразных команд Git для внесения изменений в репозиторий является команда revert.

Суть ее очень проста - она отменяет все изменения, зафиксированные в крайнем коммите; и создает новый коммит, который является потомком предыдущего коммита, но в тоже время его зеркальной копией, противоположностью.

Синтаксис команды revert также прост:

git revert 4a2f59a32bd1074c42

где 4a2f59a32bd1074c42 - это часть SHA-суммы крайнего коммита.

Команда reset

Команда reset также может изменять репозиторий Git. Делает она это путем смещения указателя HEAD на нужный коммит.

После такого смещения HEAD все более поздние коммиты никуда не пропадут из репозитория - они все еще там. Но теперь любое закоммиченное изменение произведет перезапись более поздних коммитов - и тогда они будут потеряны навсегда.

Ситуация очень похожа на то образное сравнение цепочки коммитов Git с магнитофонной лентой. Стоит отмотать ленту на 10-20 минут назад и снова начать запись, то все более поздние записи (относительно этого места) будут перезаписаны.

У команды reset есть три ключа, которые незначительно видоизменяют ее работу:

  • -soft
  • -mixed
  • -hard

Команда git reset –soft 4a2f59a32bd1074c42 произведет смещение указателя HEAD на указанный коммит 4a2f59a32bd1074c42. При этом Git произведет сброс изменений в буфер. В результате буфер и рабочая директория будут идентичными между собой; а репозиторий будет переведен в более ранее состояние.

Команда git reset –mixd 4a2f59a32bd1074c42 аналогична предыдущей. Также будет произведено смещение указателя HEAD. Но теперь Git сбросит изменения в рабочую директорию. Репозиторий и буфер будут идентичными друг другу и находиться в более раннем состоянии.

Команда git reset –hard 4a2f59a32bd1074c42 самая “жесткая”. Также будет произведено смещение указателя HEAD на указанный коммит, но при этом будет произведен сброс всех трех деревьев Git - репозитория, буфера и рабочей директории. Все три будут идентичными друг другу.

Команда clean

В системе Git существует команда clean для удаления не отслеживаемых файлов в рабочей директории.

Разница между командой git rm и clean заключается в том, что при удалении файлов из рабочей директории первой командой они вроде как удаляются. Но на самом деле удаленные файлы все еще остаются в системе Git. Просто они помещены в раздел мусора и являются теперь мусором.

Команда clean как раз и выполняет очистку мусора в системе. Она удаляет все не отслеживаемые и неиспользуемые файлы.

Но даже это она делает очень осторожно. Если просто запустить git clean, то ничего не произойдет. Система Git скажет, что команду clean необходимо запускать либо с ключом -n, либо с ключом -f.

Запуск git clean -n - это тестовый запуск команды удаления. Ничего удалено не будет - система лишь покажет, что она собирается удалить, какие файлы.

А вот запуск git clean -f произведен реальное удаление всех файлов, которые Git считает мусором. И в этом случае эти файлы будут потеряны навсегда.

На этом все.


Два способа игнорирования файлов - локальный и глобальный. Шаблоны для игнорирования файлов в для различных операционных систем, языков программирования, CMS и т. д. Игнорирование уже отслеживаемого файла в Git. Отслеживание пустых директорий.

Шаблоны правил для .gitignore

Два ресурса на GitHub, в которых собраны шаблоны файла

1
.gitignore
для разных случаев - разных операционных систем, разных языков программирования и т. д.

Общий список правил

По ссылке ниже представлен набор общих правил и рекомендаций при создании файла

1
.gitignore
. Помимо этого, в данном разделе показан шаблон для самого общего случая использования
1
.gitignore
:

Общий список правил игнорирования файлов в Git

Детализированный список правил

По ссылке ниже представлен более детальный и полезный список правил, по которым создается файл

1
.gitignore
. В этом списке можно найти рекомендации для разных операционных систем (Linux, Mac OS X, Windows, Android), разных языков программирования (Java, Perl и т. д.), различных CMS (к примеру - Joomla, Magento, Jekyll). Даже для README есть свой набор правил!

Деталированный список правил игнорирования файлов в Git

Помимо списка языков программирования, в котором для каждого пункта этого списка представлены рекомендованные правила для файла

1
.gitignore
, имеется еще дополнительная директория “Global”.

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

Глобальное игнорирование

В Git возможно игнорирование файлов двумя способами:

  • локально
  • глобально

В последнем случае (глобально) имеется ввиду, что Git будет игнорировать указанные файлы всегда, в любом из проектов.

Ярким примером такого глобального игнорирования являются служебные файлы операционной системы - они должны игнорироваться всегда и в любом проекте Git.

Файл конфигурации с глобальным игнорированием может быть назван как угодно (в отличие от файла

1
.gitignore
). Главное - он должен располагаться в домашней директории пользователя, а не в директории с проектом. И это его главное отличие от файла
1
.gitignore
.

После того, как файл глобального игнорирования создан, необходимо добавить его в конфигурационный файл Git. То есть, “сказать” Git, что “у тебя есть список файлов, которые ты должен игнорировать; этот список называется так и расположен он здесь”.

Выполняется это командой:

git config --global core.excludesfile ~/.gitignore_global

Если теперь взглянуть на конфигурационный файл Git, то увидим следующее:

$ cat ~/.gitconfig
[user]
    name = g*e
    email = g*e@gmail.com
[core]
    excludesfile = /Users/g*e/.gitignore_global

Игнорирование отслеживаемого файла

Может возникнуть ситуация, когда файл был создан и помещен в репозиторий Git. То есть, теперь он является отслеживаемым.

Но это была ошибка - этот файл не нужно было отслеживать! Как сказать Git, чтобы он не отслеживал этот файл?

Для этого нужно выполнить два шага.

Первый - это внести имя нужного файла в список игнорируемых файлов - отредактировать файл

1
.gitignore
.

Однако, этот шаг еще ничего не даст - Git все также будет его отслеживать, так как он уже внесен в буфера обмена.

Для этого нужно “вынуть” данный файл из буфера обмена. Это выполняется командой:

git rm --cached name_of_file

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

Осталось только выполнить коммит обоих изменений - добавление файла в игнорируемые и удаление его из репозитория.

Все последующие изменения в этом файле отслеживаться не будут.

Отслеживание пустых директорий

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

Заключается он в том, что Git - это система контроля версий для файлов! Другими словами - Git умеет отслеживать только файлы!

Поэтому, если в проекте имеется пустая директория, то Git ее просто “выкинет”. По той простой причине, что точки зрения Git директория - всего лишь путь к файлу, способ найти отслеживаемый файл. А раз файла нет, то путь ведет вникуда, так как отслеживать нечего.

Кстати сказать, я сам когда-то был таким новичком и столкнулся с этим непонятным для меня фактом. Интуитивно догадался, в чем дело и поступал таким “корявым” (как я считал) способом.

К примеру, для директории psd я создавал файл-заглушку

1
dummy.psd
размером 1px*1px. Главное - чтобы в директории psd что-то лежало - тогда Git не удалит ее! )

Как оказалось, я был прав! И это единственный правильный способ заставить Git отслеживать пустые директории.

Одна только маленькая поправка - в мире Unix такой файл-заглушку можно создать с помощью команды

1
touch
и выглядеть такой файл будет так (общепринятое соглашение):

.gitkeep

Что же - этот способ более аккуратный и грамотный!

На этом все.


Краткое знакомство с системой контрольных точек Rupture под препроцессор Stylus.

Ниже приведено краткое и сбивчивое описание (знакомство) с системой

1
breakpoints
под препроцессор Stylus. Оно основано на двух материалах, оба являющихся официальными:

А больше в Сети материалов по Rupture и нет, даже на английском языке. Есть, правда, очень краткий - на французском, которым я совсем не владею.

Rupture был создан на примере плагина Breakpoint Slicer под препроцессор Sass.

Шкала Rupture

Основа Rupture - шкала значений

1
breakpoints
, которая так и называется -
1
scale
. Фактически
1
scale
- это объект со своими свойствами и методами. Перечень контрольных точек (
1
breakpoints
) - это массив значений, передаваемых объекту
1
scale
.

Ниже представлена

1
scale
по умолчанию (но которую можно легко изменить при необходимости):

scale = 0 400px 600px 800px 1050px 1800px

Количество этих значений -

1
0, 400px, 600px 800px, 1050px
- может быть необязательно равно 5 (пяти). Их может быть неограниченное количество - столько, сколько нужно.

Перечень значений

1
breakpoints
, показанных выше, можно представить в виде диапазонов; каждому диапазону можно присвоить порядковый номер
1
slice number
и “обозвать” как
1
slice
:

Rupture Scale

Подключать библиотеку Rupture в проект нет необходимости. Достаточно установить библиотеку командой:

$ sudo npm install rupture --global

После этого Rupture готова к использованию. Можно запустить компиляцию из командной строки (не рекомендуется):

$ stylus -u rupture -c example.styl

Здесь

1
-c
- это сокращение от
1
--compress
, то есть - минифицировать CSS-код на выходе. Почему не рекомендуется использовать командную строку? Просто для этих целей лучше (и целесообразнее) использовать Gulp.

Миксины Rupture

В Rupture все управляется миксинами. Есть заранее созданный набор миксинов, которые необходимо применять для определенного случая (

1
breakpoints
).

Все миксины Rupture делятся на два вида:

  • простые миксины для практического использования каждый день
  • сложный набор миксинов, которые фактически представляют из себя
    1
    
    grid sistem
    

В этом кратком обзоре я буду рассматривать только “практические” миксины. Более сложные - нет, ибо “не зачем”.

Набор практических миксинов Rupture

Первые три миксина - наиболее применимые и удобные на практике.

+above(measure)

  • если размер окна браузера больше указанного значения (
    1
    
    > measure
    
    ), то применить стили
  • 1
    
    +from-width(measure)
    
    - это алиас миксина +above(measure)

+below(measure)

  • если размер окна браузера меньше указанного значения (
    1
    
    < measure
    
    ), то применить стили
  • 1
    
    +to-width(measure)
    
    - это алиас миксина +below(measure)

+between(measure1, measure2)

  • если размер окна браузера находится в указанных пределах (
    1
    
    measure1 <= between <= measure2
    
    ), то применить стили

Дальше пошли миксины - “по обстоятельствам”.

+at(measure)

  • если размер окна браузера
    1
    
    >=
    
    указанного значения, то применить стили

+mobile()

  • если размер окна браузера
    1
    
    <= 400px
    
    , то применить стили
  • 1
    
    rupture.mobile-cutoff
    
    - переменная, в которой хранится значение для миксина
    1
    
    mobile()
    

+tablet()

  • если размер окна браузера находится в пределах
    1
    
    >= 1050px
    
    и
    1
    
    < 400px
    
    , то применить стили

+desktop()

  • если размер окна браузера
    1
    
    > 1050px
    
    , то применить стили
  • 1
    
    rupture.desktop-cutoff
    
    - переменная, в которой хранится значение для миксина
    1
    
    desktop()
    

+hd()

  • если размер окна браузера
    1
    
    >=
    
    1800px, то применить стили
  • 1
    
    rupture.hd-cutoff
    
    - переменная, в которой хранится значение для миксина
    1
    
    hd()
    

+retina()

  • если плотность размещения пикселей больше 1.5
    1
    
    (retina display)
    
    , то применить стили

+landscape()

  • если у окна браузера высота меньше, чем ширина, то применить стили

+portrait()

  • если у окна браузера высота больше, чем ширина, то применить стили

Настройка Rupture

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

К примеру, Rupture имеет возможность автоматического конвертирования значений

1
breakpoints
из пикселей (px) в
1
em
. Как говорится в официальном руководстве, в веб-разработке существует мнение, что задавать контрольные точки в
1
em
- это хорошая практика.

Поэтому, такой пример иллюстрирует включение автоматической конвертации из

1
px
в
1
em
; и задание базового размера шрифта в 18px (базовый размер шрифта равен 16px):

rupture.enable-em-breakpoints = true
base-font-size = 18px

rupture.scale - одна из важнейших переменных Rupture. В этой переменной можно в виде массива переопределить значения breakpoints.

Например, таким образом:

rupture.scale = 0 380px 768px 1200px

Пример работы Rupture

Перейдем от теории к практике и рассмотрим маленький рабочий пример - как будет отрабатывать Rupture:

div.wrapper
  div.left
  div.right
@import 'nib'
@import 'jeet'

// Partials
@import 'partials/*.styl'

rupture.enable-em-breakpoints = true

.wrapper
  center()

.left
  col(1/3)
  height 20vh
  background-color lighten($color,10%)
  +below(800px)
    col(1/4)
    background-color lighten($color,20%)
  +below(400px)
    stack()
    margin-bottom 10px

.right
  col(2/3)
  height 20vh
  background-color lighten($color,20%)
  +below(800px)
    col(3/4)
    background-color lighten($color,30%)
  +below(400px)
    stack()

Комментировать вышеприведенный код мне как-то не особого желания. Он очень простой и наглядный - слова тут излишни.

Кроме одного вопроса, который чуть не забыл упомянуть! В этом коде (и всех примерах выше) применялось точное значение для миксинов -

1
+below(400px)
, к примеру.

Но ничто не мешает использовать любые произвольные переменные, в которые можно “загружать” нужные значения. К примеру, код выше можно преобразовать таким образом:

@import 'nib'
@import 'jeet'

// Partials
@import 'partials/*.styl'

// Breakpoint Variables
$bp1 = 800px
$bp2 = 400px

rupture.enable-em-breakpoints = true

.wrapper
  center()

.left
  col(1/3)
  height 20vh
  background-color lighten($color,10%)
  +below($bp1)
    col(1/4)
    background-color lighten($color,20%)
  +below($bp2)
    stack()
    margin-bottom 10px

.right
  col(2/3)
  height 20vh
  background-color lighten($color,20%)
  +below($bp1)
    col(3/4)
    background-color lighten($color,30%)
  +below($bp2)
    stack()

Заключение о Rupture

Вот я и познакомился с Rupture. Что можно сказать - система мне (в очередной раз - все из мира Stylus) понравилась, она очень проста и наглядна. Достаточно полчаса, чтобы ознакомиться с ее возможностями и начать применять на практике.


Вступление

Сегодня приступим к знакомству с системой построения сеток jeet.gs.

Читатели могут спросить - отлично, но чем плоха Susy? Ответ прост - Susy работает на Ruby, она просто несовместима со Stylus.

Так как с недавнего времени я перешел с Sass(SCSS) на Stylus и совсем не жалею об этом, то сразу принялся искать замену Susy. Надо сказать, я быстро ее нашел и этой заменой оказалась jeet.gs. “Grid system для людей” - как ее “обозвали” в прекрасном task runner CodeKit. Кстати, сам факт присутствия jeet.gs в CodeKit говорит за себя.

Система jeet.gs изначально адаптивная, она проста в использовании и изучении. Если честно, Susy я так до конца и не освоил (только необходимые основы), так как она достаточно сложна в изучении, несмотря на прекрасную документацию. Еще можно сказать, что jeet.gs очень молода - ей всего 9 месяцев и поэтому я с вами, уважаемый читатель, иду в ногу со временем, я на cutting edge!

Существование и использование jeet.gs имеет мало смысла без системы контрольных точек (breakpoint). В Susy в этом качестве служит хороший инструмент Breakpoint. Под jeet.gs конечно же существует аналог под названием Rupture. Эта система также проста и наглядна, как и jeet.gs.

Стоит также оговориться, что под Stylus имеются не менее прекрасные проекты Typographic и Axis, с которыми я планирую познакомиться в свое время.

Jeet.gs - grid system под Stylus

Итак, фанфары прозвучали в честь обоих героев сегодняшнего дня. Пора приступать к более детальному знакоству с ними. И начнем с главного героя - системы сеток (grid system) jeet.gs.

Установка Jeet.gs под Stylus

Любое знакомство начинается с установки пакета. На официальной странице jeet.gs прекрасно оформлено описание инсталляции - она проста. Кстати, стоит оговориться, что jeet.gs можно установить и под Sass(SCSS). Но я этого делать не буду - мне это не интересно и не нужно.

Предполагается, что у читателя рабочей операционной системой является MacOSX или Linux OS (все команды в этой статье будут показаны применительно к этим двум родственным системам). Также предполагается, что в любой из этих систем уже установлены Node.js и Stylus (иначе вы немного забежали вперед, уважаемый читатель).

Установка jeet.gs выполняется одной строкой:

sudo npm install jeet --global

Далее библиотека jeet.gs импортируется в файл проекта

1
*.styl
с помощью директивы
1
@import
:

@import 'jeet'

После этого можно запустить мониторинг и компиляцию командой:

sudo stylus -u jeet -w style.styl

где

1
-u
- это сокращение от
1
--using
,
1
-w
- от
1
--watch
. То есть, мониторить (watch) все изменения файла
1
style.styl
и при этом учитывать (
1
using
) возможности подключенной библиотеки jeet.gs.

Пакет jeet.gs можно заставить работать несколько иначе - крутиться под Gulp. Для этого достаточно правильно оформить файл

1
gulpfile.js
:

var gulp = require('gulp'),
...
nib = require('nib'),
jeet = require('jeet'),
rupture = require('rupture');


// STYLUS WITH NIB AND JEET AND RUPTURE
gulp.task('stylus', function(){
  gulp.src('app/styles/style.styl')
    .pipe(plumber())
    .pipe(stylus({use:[nib(),jeet(),rupture()]}))
    .pipe(gulp.dest('dist/'));
});

Возможности Jeet.gs

С документацией по jeet.gs можно ознакомиться на оф. сайте в разделе Jeet’s API или же на страничке GitHub - jeet/stylus.

Функция column()

Синтаксис:

column(ratios = 1, offset = 0, cycle = 0, uncycle = 0, gutter = jeet.gutter)

Основой любой современной grid system являются колонки\столбцы -

1
column
. Так как jeet.gs изначально является адаптивной системой, то задать ширину column можно как дробную часть от ширины блока-контейнера -
1
1/3
,
1
1/6
,
1
1/10
,
1
1/100
и так далее. Не обязательно можно задавать в виде дроби, можно в десятичном виде -
1
.3
,
1
.25
,
1
.15
.

Пример задания ширины для двух блоков

1
.sidebar
и
1
.main
. В обоих случаях используется функция
1
column()
, у которой есть более используемое сокращение -
1
col()
:

.sidebar
  col(1/4)
.main
  col(3/4)

Функция

1
column()
может принимать целый ряд аргументов, с помощью которых возможна тонкая настройка блоков в разметке.

Смещение колонок\столбцов выполняется с помощью аргумента

1
offset
, который может принимать как положительное, так и отрицательное значение. Положительное значение
1
offset
задает у столбца
1
margin-left
- и столбец смещается влево. Отрицательное значение задает
1
margin-right
- и блок смещается вправо.

.block
  column(1/3, offset: 1/4)

Аргумент

1
cycle
позволяет создавать галлереи. Допустим, необходимо создать галлерею из картинок, в которой должно быть 4 (четыре) картинки в ряду. Тогда для функции
1
column()
задаем параметр
1
cycle: 4
:

.block
  column(1/3, cycle: 4)

Аргумент

1
uncycle
позволяет создавать мобильные версии галерей. Допустим, desktop-версия галлереи -
1
column(1/3, cycle: 4)
. Чтобы создать мобильную версию этой галлереи, в которой картинки будут располагаться по две в ряд, достаточно прописать так:

.block
  column(1/3, uncycle: 4, cycle: 2)

Аргумент

1
gutter
позволяет управлять шириной gutter между столбцами в каждом конкретном случае. Допустим, таким образом:

.block
  column(1/3, uncycle: 4, cycle: 2, gutter: .5)

Функция span()

Синтаксис:

span(ratio = 1, offset = 0)

Эта функция является своего рода облегченным вариантом функции

1
column()
. Функция
1
span()
не “понимает” такого свойства, как отступы
1
gutter
у блоков. По одной простой причине - функция
1
span()
создает разметку из блоков, плотно прилегающих друг к другу, без
1
margin
.

Такая разметка крайне полезна при создании горизонтальной навигации. Например, создать навигацию из восьми пунктов:

.nav
  cf()
  a
    span(1/8)

Функция shift()

Синтаксис:

shift(ratios = 0, col_or_span = column, gutter = jeet.gutter)

Эта функция служит для изменения порядка расположения элементов в нормальном потоке, с помощью свойства

1
position: relative
. Величина смещения задается аргументом
1
ratios
и применяется подобное смещение в виде свойства
1
left
к блоку. При этом функции
1
shift()
с помощью задания или не задания аргумента
1
gutter
можно указать, является ли данный блок столбцом (через функцию
1
column()
) или блоком span (через функцию
1
span()
).

Функция

1
shift()
точно также, как и аргумент
1
offset
, может принимать отрицательные значения для изменения направления смещения блока. Также, функция
1
shift()
может принимать не только целые, но и дробные значения для точного позиционирования.

Функция unshift()

Синтаксис - отсутствует

Эта функция не принимает каких-либо аргументов. Ее задача - отменить действие функции

1
shift()
.

Функция edit()

Синтаксис - отсутствует

Данная функция не создает разметку напрямую. Ее задача - помочь в создании разметки. С ее помощью каждый элемент на странице окрашивается в определенный оттенок серого цвета. Это помогает визульно контролировать правильность процесса создания разметки.

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

edit()

Вид разметки будет примерно таким:

Функция edit() в jeet.gs

Функция center()

Синтаксис:

center(max-width = 1410px, pad = 0)

Задача функции

1
center()
- быстро и грамотно выполнять центрирование блока в разметке. Как видно из синтаксиса, функция принимает два аргумента:

  • максимальную ширину
    1
    
    max-width
    
    , равную по умолчанию
    1
    
    1410px
    
    ;
  • 1
    
    padding-left
    
    и
    1
    
    padding-right
    
    для блока, задаваемые в виде шортката
    1
    
    pad
    
    и равного нулю по умолчанию; то есть, нельзя управлять
    1
    
    padding-left
    
    и
    1
    
    padding-right
    
    по отдельности - только одно значение сразу для двух свойств.

Функция cf()

Синтаксис - отсутствует

Данная функция - это всего лишь

1
clearfix
от Nicholas Gallagher. Думаю, дальнейшее объяснение излишне. Принимать - маленькими дозами для любых блоков с
1
column()
или
1
span()
.

Функция align()

Функция для выравнивания блока внутри блока-контейнера с помощью

1
position: absolute
. Вертикальное выравнивание в браузерах IE9+ теперь простая вещь.

Функция stack()

Синтаксис:

stack(pad = 0, align = false)

Данная функция предназначена для расположения блоков стопкой (stack), друг над другом. Такой вид расположения блоков применим для модильной версии страницы. Функция

1
stack()
принимает два вида аргументов:

  • 1
    
    pad
    
    - отступы
    1
    
    padding-left
    
    и
    1
    
    padding-right
    
    для блока;
  • 1
    
    align
    
    - выпавнивание текста внутри блока.

Функция unstack()

Синтаксис - отсутствует

Данная функция отменяет действие функции

1
stack()
. Однако, действие этой функции не возвращает разметку к прежнему виду, с применением функции
1
column()
. Чтобы вернуть разметку к такому результату, необходимо снова использовать функцию
1
column()
.

Настройки Jeet.gs

Настройки системы jeet.gs очень просты. Первоначально необходимо создать файл

1
_settings.styl
, который нужно подключить в файл стилей директивой
1
@import '_settings'
. При этом необходимо, чтобы строка
1
@import '_settings'
размещалась сразу после строки
1
@import 'jeet'
.

Содержимое файла настроек

1
_settings.styl
- это несколько переменных:

  • 1
    
    jeet[&#8216;gutter'] = 3
    
    - размер ширины gutter в процентах, от общей ширины страницы
  • 1
    
    jeet[&#8216;parent-first'] = false
    
    - если сказать коротко, каким образом будет производиться вычисление ширины блока; относительно конкретного блока-родителя; или же относительно корневого блока-родителя
  • 1
    
    jeet[&#8216;layout-direction'] = LTR
    
    - направление текста внутри разметки

Заключение по Jeet.gs

Итак, познакомились с системой создания разметки jeet.gs. На удивление, она оказалась проста и достаточно полчаса, чтобы разобраться в ней. Не сравнить с Susy, конечно.

Но этого мало, естественно. Хотелось бы посмотреть на живые примеры сайтов, созданных с помощью jeet.gs. В этом вопросе может помочь сам официальный сайт Jeet.gs - милости просим.

Создано по материалам:

P.S.

В данной статье возможны (и 100% - что есть) неточности и мелкие ошибки. Это и понятно - это мое первое знакомство с Jeet.gs. Поэтому, если будут замечания - милости просим.

На этом все.