S.Tominoff

Fullstack JavaScript разработчик

Рука помощи

Вёрстка и скриптинг лендинга для частной клиники в Ульяновске

Инструменты

При вёрстке сайтов я использую такой стек — gulp + sass + nunjucks + postcss плагины + browsersync, на мой взгляд — это оптимальная подборка инструментов. Подключил также webpack + babel — жир конечно для лендинга, но очень уж сильно мне нравится es2015 — на nodejs проектах уже активно использую новые возможности Javascript. Разумеется, в проекте используются оптимизаторы изображений — gulp–image или gulp–tinypng, а также плагин usemin, который я использую для финальной обработки и оптимизации js/css/html.

 

Webpack vs Yandex Metrika

Столкнулся с одной сложностью, связанной с яндекс.метрикой. В связи с тем, что в Webpack модулях по умолчанию не доступен объект window, пришлось пойти на некоторые ухищрения. В частности, заюзал секцию external:

/* ... */
'webpack' : {
    'externals' : {
        'window' : 'window'
    },
    /* ... */
}
/* ... */

Это позволяет импортировать объект window как модуль:

import $ from 'jquery';
import 'window';

const initGoalManager = () => {
    window.yaCounterXXXXX.reachGoal('some-goal-name');
}

$(() => {
    $(document).on('yacounterXXXXXinited', initGoalManager);
});

 

Особенности

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

 

 

Конечно, можно было бы воспользоваться фотошопом и наложить эти дуги на изображения, или сделать элемент с background из дуги с прозрачным вырезом, но мозг упорно требовал лучшего решения — как никак, 2017 на дворе! Тем более подобные решения невозможно будет переиспользовать в будущем.

 

В ходе исследований вопроса постепенно пришёл к слудующим способам реализации:

 

1. Вытянутый элемент (эллипс) с border-radius 100%

Это первое что выстрелило в моём мозгу при взгляде на первую дугу:

 

 

Ок, реализация не такая уж сложная, однако этот вариант пришлось отбросить по двум причинам:

 

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

 

 

*    *    *

Кстати, если применить к элементу css тени:


…то разрывы становятся менее заметными.

*    *    *

 

 

2. Элемент SVG

Мысль об использовании SVG пришла с ответом на вопрос — что может отрисовывать кривые без искажений? Ответ напрашивался сам собой — конечно же вектор!

 

Благо, в основе формата лежит пресловутый XML, так что можно программно отрисовать всё что угодно, без использования векторных графических редакторов (конкретно в моём случае там всего–то кубическая кривая Безье).

 

 

Разница на лицо — использование Inline SVG позволило избавиться от проблемы «дёрганных» переходов рамки. Таким образом реализовал все 4 возможных варианта дуги (с отрисовкой фона внутри и снаружи). Всё это сложил в отдельные nunjucks шаблоны и закинул в личную библиотечку njk сниппетов – авось пригодится когда–нибудь, а управление CSS свойствами реализовал в виде Sass миксина.

 

 

Вторая хитрость этого лендинга — адаптивные стрелки:

 

 

Тут тоже было два варианта. Первый вариант (использовал border-image и подготовленный спрайт) нормально работал только в Chrome и Firefox (на остальных либо палочки, либо пустота), поэтому пришлось отбросить его.

 

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

 

li
    &:after
        // какой-то код
        background-image: url("#{$rp-base-path}/img/arrow-sprite/triangle.png"), url("#{$rp-base-path}/img/arrow-sprite/pipe.png")
        background-position-y: 100%, 0
        background-repeat: no-repeat, repeat-y
        background-size: 1em, .4em
        background-position-x: 0, 0.31em

 

Всё остальное было реализовано поверх sass bootstrap, поэтому не вызывало особых сложностей. К примеру, для этого проекта сгенерировал набор колонок, работающих при определённой ориентации экрана:

 

// классы грида для стилизации в альбомном режиме
@media(max-width: $screen-xs-max) and (orientation: landscape)
	+loop-grid-columns($grid-columns, 'rp-landscape-xs', width)
	+loop-grid-columns($grid-columns, 'rp-landscape-xs', offset)