Статьи

Быстрое Адаптивное Развитие с Sass и Flint

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

Что такое Флинт?

Flint — это адаптивная сеточная система, написанная на Sass, созданная для того, чтобы позволить разработчикам быстро создавать адаптивные макеты, построенные на сложной основе. Будучи дизайнером сам, большое количество времени было потрачено на сам синтаксис. Flint очень уникален тем, что для всего вывода используется только один миксин: _( ) Да, это действительно просто подчеркивание. Легко запомнить, а? Это исключает функцию mumbo-jumbo и позволяет нам сосредоточиться на наиболее важном аспекте: макете.

Начиная

Начать работу с Flint очень просто: вы можете настроить собственную сетку или использовать настройки сетки по умолчанию, которые поставляются с Flint. Возможность быстро настроить сетку была на переднем крае моих целей при разработке Flint; и поэтому он предлагает огромную карту конфигурации, которая, по сути, является картой Sass со всеми настройками сетки и точками останова вашего проекта. Вам не нужно связываться с бесконечными переменными, чтобы запустить ваш проект. Вместо этого вы просто создаете одну переменную с именем $flint

 $flint: (
    "config": (

        "desktop": (
            "columns": 16,
            "breakpoint": 80em
        ),

        "laptop": (
            "columns": 12,
            "breakpoint": 60em
        ),

        "tablet": (
            "columns": 8,
            "breakpoint": 40em
        ),

        "mobile": (
            "columns": 4,
            "breakpoint": 20em
        ),

        // ...
    )
);

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

Одним из непосредственных преимуществ использования Flint является то, что он позволяет создавать неограниченное количество точек останова для вашего проекта с любым псевдонимом, который вы хотите. Если вам нравится называть свои контрольные точки сумасшедшими именами, такими как «прилив» или «экс-президенты», это совершенно нормально для меня.

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

Основы

Теперь, когда мы рассмотрели базу данных what и коснулись основы конфигурации, которую предлагает Flint, давайте перейдем к хорошему: создание вещей! Начать работу с Flint очень просто. Вы говорите ему, что делать, и он делает это. Если вы думаете, что я преувеличиваю, читайте дальше! Вот несколько быстрых примеров:

 .foo {
    @include _(4);
}

И вот вывод CSS:

 .foo {
    display: block;
    float: left;
    width: 93.75%;
    margin-right: 3.125%;
    margin-left: 3.125%;
}

@media only screen and (min-width: 60.0625em) {
    .foo {
        width: 23.4375%;
        margin-right: 0.78125%;
        margin-left: 0.78125%;
    }
}

@media only screen and (min-width: 40.0625em) and (max-width: 60em) {
    .foo {
        width: 31.25%;
        margin-right: 1.04167%;
        margin-left: 1.04167%;
    }
}

@media only screen and (min-width: 20.0625em) and (max-width: 40em) {
    .foo {
        width: 46.875%;
        margin-right: 1.5625%;
        margin-left: 1.5625%;
    }
}

Здесь мы попросили Флинта создать блок, охватывающий 4 columns Это хороший код для такого маленького объявления, а? Я называю этот тип аргумента рекурсивным сокращением . Вы заметите, реальные поля выводятся; ничего подобного. Он также думает о мобильных устройствах в первую очередь, хотя это полностью настраивается через параметры конфигурации, о которых я упоминал ранее.

Также обратите внимание, что Flint автоматически выводит запросы @media Вам не понадобится отдельный плагин для обработки всех ваших точек останова. Все связано с Флинтом, но об этом мы поговорим позже.

Пока мы находимся на теме точек останова… Что если нам понадобятся разные промежутки для каждой точки останова? Ну, Флинт тоже тебя прикрыл! И нет, вам не нужно создавать объявление для каждой точки останова. Здесь все не так. Опять же, просто скажите Флинту делать то, что вы думаете:

 .foo {
    @include _(8 6 4 2);
}

И вывод:

 .foo {
    display: block;
    float: left;
    width: 43.75%;
    margin-right: 3.125%;
    margin-left: 3.125%;
}

@media only screen and (min-width: 60.0625em) {
    .foo {
        width: 48.4375%;
        margin-right: 0.78125%;
        margin-left: 0.78125%;
    }
}

@media only screen and (min-width: 40.0625em) and (max-width: 60em) {
    .foo {
        width: 47.91667%;
        margin-right: 1.04167%;
        margin-left: 1.04167%;
    }
}

@media only screen and (min-width: 20.0625em) and (max-width: 40em) {
    .foo {
        width: 46.875%;
        margin-right: 1.5625%;
        margin-left: 1.5625%;
    }
}

Что тут происходит? Мы сказали Flint, что мы хотим создать блок, который охватывает 8 columns6 columns4 и наконец, что не менее важно, 2 columns Мы сделали это, передав простой список аргументов, разделенный пробелами. Я называю этот тип аргумента переменной переменной. Если вы заметили, порядок операций соответствует порядку, используемому в нашей карте конфигурации, которая соответствует порядку DESC. Довольно круто, а?

Flint — это гораздо больше, чем просто создание столбцов. Он действительно разработан, чтобы упростить управление всем процессом адаптивного дизайна и сделать его таким простым.

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

Держать все это на связи

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

В большинстве современных систем сетки ваши точки останова и ваша сетка не связаны так, как должны быть. У вас есть плагин для ваших точек останова, а затем у вас есть плагин для вашей системы сетки. Это создает серьезное расхождение по моему мнению. Что я имею в виду под этим?

Вы должны настроить точки останова, а затем настроить сетку в этих точках останова. Конфигурирование точек останова само по себе может быть головной болью, особенно если он не обрабатывает математику, необходимую для определенных комбинаций точек останова (например, запрос между двумя размерами). Но! Есть плагин для этой проблемы тоже, верно?

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

Поэтому включение Flint в рабочий процесс решает эту проблему. И как это сделать? Что ж, дамы и господа, это подводит нас к нашей первой концепции! (Для краткости я собираюсь использовать код-гиперболу — прости меня.)

Ускорение Вещи

Хорошо, наконец-то! Наша первая концепция! Я знаю, я знаю … это был долгий путь; но, надеюсь, к настоящему времени вы можете обратиться к различным вопросам, которые мы будем быстро решать. Первый — страшный контейнер. Настройка для этого зависит от многих вещей, например, статична ли ваша сетка или изменчива; фиксированный или эластичный. Вы получаете смысл. Давайте предположим, что это исправлено. Чтобы создать реальные точки останова, которые работают с нашей сеткой, нам, вероятно, придется сделать что-то вроде этого:

 // Breakpoints
$desktop: 80em;
$laptop: 60em;
$tablet: 40em;
$mobile: 20em;

// Now the math...
$mobile-to-tablet: (min-width: ($mobile + 0.0625em)) and (max-width: $tablet);
$tablet-to-laptop: (min-width: ($tablet + 0.0625em)) and (max-width: $laptop);
$laptop-to-desktop: (min-width: $laptop + 0.0625em));

// Finally, the actual container!
.container {
    @include container(4); 

    @include breakpoint($mobile-to-tablet) {    
        @include container(8);
    }

     @include breakpoint($tablet-to-laptop) {    
        @include container(12); 
    }

    @include breakpoint($laptop-to-desktop) {    
        @include container(16);
    }
}

Здорово. Это много кода и много места для ошибок. Я знаю, что это, вероятно, нереальная настройка для обычного читателя, но помните, мы преувеличиваем здесь (даже если я видел эту точную настройку раньше). Как бы мы сделали это с Флинтом? Я рад, что ты спросил!

 .container {
    @include _("container");
}

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

Хорошо, я сказал быстро, так что к нашей следующей концепции!

Как мы держим все на связи

Мы говорили о плагине для точек останова, а затем о плагине для вашей сетки. Есть причина для этого, я знаю. Вы, наверное, думали, что я немного скучаю по адаптивному дизайну. Как тот факт, что точки останова используются не только для сетки, но и для других вещей. Такие вещи, как стиль точки останова. Я согласен. Но не волнуйтесь, Флинт тоже с этим справится!

 .foo {
    background: black;

    @include _(tablet) {
        background: white;
    }
}

И вывод:

 .foo {
    background: black;
}

@media only screen and (min-width: 20.0625em) and (max-width: 40em) {
    .foo {
        background: white;
    }
}

Здорово. Это не много кода. Есть целый ряд аргументов, которые вы можете использовать для таких работ, и самое лучшее? Нет математики! Ты говоришь Флинту, что делать по-человечески, и он это делает. Надеюсь, вы заметили здесь тенденцию. Вот небольшой вкус многих аргументов, которые вы можете использовать при определении медиа-запросов.

 .bar {
    // ...

    @include _(from tablet to laptop) {
        // Anything between tablet and laptop
    }

    @include _(less than laptop) {
        // Anything less than laptop
    }

    @include _(greater than mobile) {
        // Anything greater than mobile
    }

    @include _(10em greater than tablet) {
        // Anything 10em greater than tablet
    }
}

Хочешь взглянуть на это! Помните, когда я сказал, что человек читается ? Я имел в виду это. Это очень полезно, особенно при работе в команде разработчиков. Если это легко понять, все на одной странице. И это довольно аккуратно. Вы даже можете создавать произвольные медиа-запросы, такие как @include _(from 12em to 55em)

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

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

Это все контекстно, чувак

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

 .foo {
    @include span(12);

    .bar {
        @include span(6, 12);
    }
}

Здесь нет ничего захватывающего. Если вы используете приличную систему сетки, она делает это. Это хорошая вещь. Флинт тоже это делает. То, что Флинт также может сделать, это выполнить эту повторяющуюся задачу для вас. Видите ли, под капотом Флинт является чрезвычайно сложным. Когда вы говорите ему создать диапазон, он выводит то, что вам нужно, но за кулисами он также создает журнал того, что вы только что сделали, и переменных, задействованных в этой задаче.

В лучшем случае это, вероятно, сбивало с толку, поэтому позвольте мне уточнить. Flint имеет изящный маленький debug-mode Итак, давайте включим режим отладки и посмотрим. Я также собираюсь перейти на фиксированную сетку по причинам читабельности — я не думаю, что кто-то хочет попробовать читать проценты.

 $flint: (
    "config": (
        // ...

        "debug-mode": true
    )
);

.foo {
    @include _(desktop, 12);
}

При включенном режиме отладки выводится:

 @media only screen and (min-width: 60.0625em) {
    .foo {
        width: 73.4375%;
        margin-right: 0.78125%;
        margin-left: 0.78125%;
        -flint-instance-count: 1;
        -flint-parent-selector: none;
        -flint-key: desktop;
        -flint-breakpoint: 80em;
        -flint-columns: 16;
        -flint-span: 12;
        -flint-output-width: 73.4375%;
        -flint-output-margin-right: 0.78125%;
        -flint-output-margin-left: 0.78125%;
    }
}

Это журнал переменных, которые Флинт отслеживает по всей таблице стилей. В зависимости от элемента, может быть даже больше. Обратите внимание на строку -flint-parent-selector: none Это значение равно none.foo Давайте продолжим и дадим .foo

 .foo {
    @include _(desktop, 12);

    .bar {
        @include _(desktop, 12, "auto"); // Equivalent to: _(desktop, 12, 12)
    }
}

Выход:

 @media only screen and (min-width: 80em) {

    .foo {
        width: 940px;
        margin-right: 10px;
        margin-left: 10px;
        -flint-instance-count: 1;
        -flint-parent-selector: none;
        // ... etc ...
    }

    .foo .bar {
        width: 920px;
        margin-right: 10px;
        margin-left: 10px;
        -flint-instance-count: 2;
        -flint-parent-selector: .foo::desktop;
        -flint-key: desktop;
        -flint-breakpoint: 1280px;
        -flint-columns: 16;
        -flint-span: 12;
        -flint-context: 12;
        -flint-output-width: 920px;
        -flint-output-margin-right: 10px;
        -flint-output-margin-left: 10px;
    }
}

Обратите внимание, что .bar.foonone Как мы этого добились? Мы передали в контексте значение "auto" Это говорит Flint, что нужно автоматически находить контекст вложенного элемента.

Я, вероятно, не должен подчеркивать, насколько полезна такая функция. Хотите изменить диапазон столбцов? Измените это в одном месте, в то время как Флинт обрабатывает это везде. Быстро и без усилий. Думаешь, это слишком хорошо, чтобы быть правдой? Посмотрите на -flint-context: 12 Это значение родительского диапазона! Кроме того, ребенок отрегулировал его ширину в соответствии с шириной родителя. Довольно мило, а?

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

Заключительные мысли

Как я упоминал ранее, этот тип системы подходит не для всех рабочих процессов. Некоторые требуют, чтобы вы держали эти различные аспекты отдельно, а другие нет. Я надеюсь, что к настоящему моменту вы сможете увидеть преимущества, которые Флинт может предоставить при борьбе со зверьком, обладающим адаптивным дизайном. Если вы хотите узнать больше или помочь в разработке Flint, посетите домашнюю страницу Flint , посмотрите проект на Github или поиграйте с ним на Sassmeister .

Есть мысли или две? Я хотел бы услышать это в комментариях!