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


Часть 1


Текст


Размер шрифта и интерлиньяж


Оптимальная высота строки (line-height) 1.4 — 1.8 от размера шрифта. Это значение лучше указывать множителями, а не конкретными значениями в пикселях. Так оно будет масштабироваться относительно любого размера шрифта.


Длина строки


Ограничение длины строки помогает легче перепрыгивать глазу со строки на строку. Текст удобно читать, если в него уменьшается минимально 6 слов, а максимально 12. Достаточно использовать min-width и max-width.


Длина строки влияет на интерлиньяж. На телефонах line-height должен быть меньше, чем на большом мониторе. Существует интересный адаптивный подход (css-шлюзы), который плавно подстраивает размер шрифта и интерлиньяж под экран.


Ограничение длинных слов


Текст в строке может оказаться непредвиденно большим, в этом случае его можно ограничить с помощью text-overflow.



Выравнивание по ширине


Многие знают, как плохо выглядит выравнивание по ширине (text-align: justify). Текст становится трудно читать из-за больших отступов между словами. В книгах и газетах нет таких больших пробелов из-за переносов в словах. Чтобы включить такой перенос нужно использовать свойство hypnens, оно автоматически проставляет мягкие переносы в словах. К сожалению, это работает далеко не везде, но можно использовать плагин и словарь к нему.





Типограф


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


  • Это правильные кавычки «», а это компьютерные ""
  • Это тире —, а это дефис -
  • В типографике также принято не разрывать предлог и слово к которому оно относится, даже если предлог оказывается в конце строки. Чтобы сделать правильный перенос, достаточно пробел между словом и предлогом заменить на неразрывный пробел  

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


Продвинутые методы работы с типографикой



Обратная связь (наведение, клик, скролл)


Блоки


Удобный интерфейс откликается на каждое действие, будь то наведение мыши или клик. Нестандартному кликабельному элементу в некоторых случаях можно добавить:


  • Курсор руки вместо стрелки cursor:pointer (если не получится сделать ссылкой)
  • Добавить ховер. Хотя бы просто opacity: 0.8.
  • Добавить аттрибут role со значениями button или link
  • Убрать случайное выделение текста (user-select: none). Подходит для дропдаунов и других элементов на которые можно кликнуть несколько раз подряд.
  • Добавить обработчик нажатия на enter
  • Предусмотреть фокуc
  • Предусмотреть спиннер, если состояние элемента зависит от асинхронного события




Область клика


Чем больше и ближе объект, тем легче на него кликнуть. Существует даже математическое правило, которое это описывает. Например, в поисковой выдаче Google ссылкой является не только номер страницы, но и часть логотипа. Это спасает от случайных промахов.



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



Не накладывайте поверх кликабельных элементов другие элементы, например, иконку лупы над инпутом. В крайнем случае добавьте иконке pointer-events или решите это более поддерживаемым способом (в случае с лупой, добавьте её через background-image).


Правильный формат ссылки


Если ссылка является почтовым адресом, укажите в ссылке mailto:. Тогда по клику на неё сразу откроется почтовый клиент. Тоже самое можно сделать для телефона префиксом tel:.


Скролл на айфоне


По умолчанию, горизонтальный скролл в айфоне обрывистый и неуклюжий. Включить привычный скролл с инерцией можно свойством -webkit-overflow-scrolling: touch.


Инпуты


Тег form


Чтобы форма работала в любых браузерах, даже без js, нужно использовать тег form по назначению. Форму можно улучшать очень долго, вплоть до отправки данных даже в офлайне.


Типы


Разные значения аттрибута type (email, number, password и другие) включают правильную клавиатуру на телефонах и помогают валидировать данные


Автофокус


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


Изображение


picture и srcset


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


Таблица


Адаптивность


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


  • Уменьшить размер шрифта
  • Обернуть таблицу в блок и сделать ему горизонтальный скролл
  • Перевернуть. Сделать таблицу вместо короткой и широкой узкой и длинной
  • Заменить таблицу на несколько списков

Сделать таблицу удобной не просто. Советую почитать статьи про отображение больших таблиц и переверстку.


Компоненты


Теория близости


Объекты, расположенные близко друг к другу, воспринимаются связанно. Если поставить заголовок посредине нескольких статей, будет сложно разобраться, к какому из текстов относится заголовок. Кстати, на Хабре именно такая ошибка. Заголовок параграфа должен быть ближе к своему параграфу, а не быть равноудален от всех. Существует масса других примеров с ошибкой в теории близости.



Пустой блок


Бывает, что баннерная реклама не приходит в баннерную позицию, тогда остается большой непонятный пробел. Чтобы его убрать, достаточно использовать псевдокласс :empty:


.banner:empty {
    display: none;
}

Почти, но не совсем


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


Часть 2


Маштабируемость


Поддерживаемость


Несколько простых практик:


  • Использовать меньше фиксированных размеров. Это даст возможность легко встроить одни компоненты в другие
  • Использовать inherit и currentColor. Они поддерживаются в любом браузере и позволяют наследовать стили


  • Не использовать краткого написания свойств. Например, background: red изменяет не один, а сразу 10 стилей, включая background-color, background-size, background-repeat и другие
  • Не использовать много сторонних библиотек и хитрых возможностей препроцессоров. Они мешают другим разработчикам быстро вникнуть в суть кода

Архитектура


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


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


Типовая страница


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



Производительность


Селекторы


Браузер обрабатывает свойства справа налево. Селектор .section a div вначале найдет все элементы div на странице, затем все ссылки a и только потом определит, какие именно a входят в элемент .section. Гораздо оптимальнее селектор по классу, например, .section__link. Он проще, менее специфичен и немного быстрее работает. Не стоит переживать, что имена классов могут получится очень большими, это ни на что не влияет.


Вторая проблема селекторов — неиспользуемые селекторы. Селектор для поиска неиспользованного элемента обходит все дерево и ничего не находит. Время тратится впустую.


Анимации


Тяжелые анимации сильно тормозят страницу. Самые лучшие свойства для анимирования — transform и opacity. Они меньше других влияют на производительность.


Существует способ оптимизировать сложные вычисления за счет переноса части сложных вычислений c центрального процессора на графический. Такое аппаратное ускорение можно включить свойством transform: translate3d(0, 0, 0). Оно создаст отдельный слой компоновки с которым будет работать графический процессор. Существует еще один похожий подход — заранее предупредить браузер о будущих изменениях элемента с помощью will-change.


Не стоит злоупотреблять translate3d и свойством will-change, большинство оптимизации браузер сделает за вас сам. Почитайте также подробный разбор анимаций на GPU.


Тяжелые свойства


Не стоит использовать большие радиусы, лишний ресайзинг картинок (background-size) и сложные тени. Браузеру придется делать огромное количество перерасчетов. Например, Airbnb увеличила производительность скролла просто убрав размытие теней.


Скорость загрузки


Сжать стили


Конкатенируйте, минифицируйте и кешируйте файлы стилей.


Критичные стили


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


  • Критичные стили не получится кэшировать в браузере
  • Не получится кешировать HTML файлы, если страницы сайта генерируются динамически

Префетчинг


Браузер можно предупредить об использовании на странице ресурсов с другого адреса. Тогда браузер заранее преобразует URL этих ресурсов в IP и не будет тратить время на поиск DNS.


<link rel="dns-prefetch" href="//example.com">

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


<link rel="prefetch" href="image.png">

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


Безопасность


Target


Страница, открытая через target="_blank", получает частичный контроль над открывшей её страницей через js свойство window.opener. Эту уловку можно использовать, чтобы перевести пользователя на фишинговую страницу. Чтобы избежать уязвимости, добавляйте к ссылкам с target="_blank" атрибут rel="noopener noreferrer".


Семантика


Верстка


Нативные элементы HTML5 содержат правильные семантичные аттрибуты. Важно верстать таблицу с помощью <table>, формы c помощью form, кнопки с помощью <button> и т.д. Не забудьте поставить аттрибут alt в каждой картинке.


ARIA и роли


Роли и атрибуты ARIA помогают пользоваться сайтом со скрин-ридера и других нестандартных технологий. На доступном сайте не должно быть недоступных с клавиатуры элементов управления. Каждый такой элемент должен иметь свое описание. Это описание может быть невидимым и указано через аттрибут aria-label.


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





Порядок фокусировки можно подредактировать аттрибутом tabindex. Совсем отменить семантику элемента можно с помощью role="presentation" (например, чтобы используемая для вёрстки таблица не воспринималась как таблица с данными). Большое количество других рекомендаций можно почитать в этой статье про доступность.


Печать


Попробуйте распечатать ваш интерфейс.


Микроразметка


Существуют различные словари и синтаксисы микроразметки. Они помогают различным роботам легче работать с вашей страницей. Сущности Schema.org могут быть полезны для поисковиков, а с помощью Open Graph можно настроить красивое отображение ссылки на ваш сайт в публикациях в соцсетях.

Поделиться с друзьями
-->

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


  1. swpo
    16.01.2017 16:26
    +1

    Привет!

    Это отличная статья, спасибо огромное.
    Я бы может еще проверял, всякие мета-теги. Для тех же самых шарингов в соц сетях.

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


    1. psFitz
      16.01.2017 17:50

      Эмуляторы, browser stack, но обычно достаточно chrome DevTools.


    1. MikeKosulin
      16.01.2017 21:03

      Что-нибудь специфичное можно и в supports обернуть, особенно всякие блюры и шейпы.


      1. anton_gcor
        17.01.2017 10:59

        Хороший совет на будущее, но пока поддержка supports не особо лучше свойств, с которыми она будет полезна. Есть хорошая статья про supports


        1. MikeKosulin
          17.01.2017 11:53

          Ну, судя по Can I Use, проблема в основном только с IE и UC.
          IE 10,11 в CSS можно определять хаком.


  1. Radiocity
    16.01.2017 17:23
    -9

    За спиннеры надо ставить к стенке


    1. tuxx
      16.01.2017 17:50
      +2

      Вы аргументы в пользу своих слов привести забыли


    1. anton_gcor
      16.01.2017 17:54
      +3

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


      1. Envek
        16.01.2017 20:04
        +1

        +1. Уж лучше спиннер (и обязательно на заблокированной после клика кнопке!!!), чем получить десять одинаковых запросов на бэкенд от особо нетерпеливого пользователя на особо медленном EDGE.


      1. Radiocity
        16.01.2017 22:27
        -6

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


        1. demimurych
          17.01.2017 02:44
          +6

          Вы это интернету расскажите в моем селе.


        1. s-kozlov
          17.01.2017 06:23
          +4

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


        1. SPAHI4
          17.01.2017 16:13

          Думаю, тут имелось в виду то, что если время выполнения запроса мало, то отсутствие спиннера создает у пользователя ощущение, что запрос выполнился быстрее.


          1. s-kozlov
            18.01.2017 07:41

            А если у кого-то вдруг большое, ощущения просто незабываемые.


      1. Dreyk
        17.01.2017 17:37

        Такой спиннер всем понравится :D


        Заголовок спойлера

        image


  1. mortimoro
    16.01.2017 17:40
    +7

    Отличная статья в целом, только вот это:

    Убрать случаное выделение текста по двойному клику (user-select: none)

    пожалуйста, не надо делать!

    Я привык выделять текст двойным и тройным кликом, и когда кто-то меняет привычное поведение на своем сайте, во мне умирает одна нервная клетка, несущая добро людям.


    1. MiXei4
      16.01.2017 17:46

      Имеются в виду только кликабельные элементы.


    1. anton_gcor
      16.01.2017 17:49

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


      1. mortimoro
        16.01.2017 18:05

        Я не внимательно прочитал. Виноват. Статья отличная, почерпнул для себя несколько интересных фич.


      1. Balek
        16.01.2017 18:42

        Отличная идея, спасибо. Я тоже сразу её не понял. Хорошо было бы раскрыть эту тему в статье.


  1. Extremum
    16.01.2017 23:27
    +1

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

    Для кого-то и сами препроцессоры — хитрая возможность, так может вообще от них тогда нужно отказаться, лишь бы другим разработчикам комфортно было? Я видел верстальщиков которых даже each в saas-е в тупик ставил, но это не повод отказываться от него.


    1. kirillaristov
      17.01.2017 00:35

      Некоторые студии используют столько библиотек, что страница делает 300+ запросов и подгружается полностью за 3-4 минуты на среднем компе.


      1. Extremum
        17.01.2017 16:20

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


  1. MikeKosulin
    17.01.2017 06:41

    Касательно микроразметки, гугл сейчас всё же больше любит JSON-LD


  1. cbone
    17.01.2017 08:34
    +2

    Я бы добавил ещё один пункт: подготовить favicon для всех поддерживаемых устройств. Для этого есть очень удобный инструмент: http://realfavicongenerator.net/
    Тут же можно и проверить как будет отображаться на разных устройствах: Тыц


  1. Realetive
    17.01.2017 10:39
    +1

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


  1. Binjo
    17.01.2017 11:07

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

    Клавиши-то есть, а вот раскладка(раскладка Бирмана, например), обычно, отсутствует. Более того типограф ещё добавляет неразрывные пробелы, например.


    А так да, прогонять через типограф — обязательное дело :)


  1. MaximusWork
    17.01.2017 11:22

    Отличная статья. Очень даже во время.


  1. rznELVIS
    17.01.2017 12:52
    -1

    Блистательно! Видно, что в верстке автор большой профи. :epmty для меня в новинку. Полезная вещь для больших систем, где контролы отображаются/скрываются через CMS


    1. SPAHI4
      17.01.2017 16:15
      +1

      Учтите, что :empty не сработает, если, скажем, внутри элемента будет пробел или перенос строки


      1. anton_gcor
        17.01.2017 16:55

        Ждем псевдокласс :blank)


  1. AlexKeller
    17.01.2017 16:03

    Статья в целом годная. Но автор сам же нарушает правило «Теория близости» ))


    1. anton_gcor
      17.01.2017 16:52

      Это правда) Но тут зависит от верстки Хабра. Будет отлично, если они добавят отступ сверху у заголовков.


      Кстати, после модерации поста, НЛО добавило отступы между подзаголовками и параграфами. Я вначале их специально делал ближе к тексту:)


  1. Skit25
    17.01.2017 16:38

    Ай спасибо! Просто шик!
    Особенно для таких бакендеров как я, на которых просто берут и фронт вешают.
    Завтра всем верстальщикам нос утру!


  1. Opaspap
    17.01.2017 17:18

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


  1. Firefoxic
    18.01.2017 09:05
    -1

    Добавить привычный курсор руки вместо стрелки (cursor:pointer)

    Очень плохая практика пихать везде этот «палец». Он предназначен для ссылок и исключительно для них.
    Все любят про спецификации говорить, но одно маленькое предложение в ней для всех видимо совсем маленькое, чтобы его замечать: https://www.w3.org/TR/css-ui-3/#cursor
    pointer
    The cursor is a pointer that indicates a link.


    Хватит тащить в веб эту блаж от дизайнеров не знающих спецификаций веба. Если особо упоротые и требуют — тыкните их носом в эту ссылку. В спеке это не спроста, это нативное поведение, в ОСях (всех, кстати) этот поинтер используется исключительно для ссылок.


    1. anton_gcor
      18.01.2017 09:52

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


      Эта часть спеки не менялась очень давно и я бы обратил внимание на опыт компаний. Я походил по сайтам и обнаружил, что большинство из них используют pointer на дропдаунах. Часть использует pointer на всех кнопках (например, хабр). Интересно, что 3 бутстрап использовал везде pointer на кнопках, а в 4 версии уже нет.


      Мне попалась подробная статья про этот вопрос. Там в том числе приведены и другие аргументы за и против pointer.


      1. Firefoxic
        18.01.2017 11:56

        Существуют не только текстовые ссылки, но и ссылки блоки.

        А причём тут это? Если у элемента есть атрибут href, то курсор автоматом будет pointer. И делать ничего не надо. А если его нет — то pointer там абсолютно лишний, ибо никуда клик по этому элементу не переводит.

        Эта часть спеки не менялась очень давно

        И это очень хорошо!

        Я походил по сайтам и обнаружил, что большинство из них используют pointer на дропдаунах. Часть использует pointer на всех кнопках (например, хабр).

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

        Мне попалась подробная статья про этот вопрос.

        У Романа все статьи хорошие, кроме этой. По поводу её появления было бурное негодование в слаке Веб-стандартов. Даже не припомню, был ли на его стороне ещё кто-то.


        1. s-kozlov
          18.01.2017 12:31
          +1

          Если у элемента есть атрибут href, то курсор автоматом будет pointer. И делать ничего не надо. А если его нет — то pointer там абсолютно лишний, ибо никуда клик по этому элементу не переводит.


          Давайте не будем забывать, что дизайн делается в первую очередь для пользователей. cursor: pointer — исключительно для пользователей. Пользователям пофиг на ваши хрефы, дивы и стандарты.


        1. bromzh
          18.01.2017 13:17
          +3

          В спеке это не спроста, это нативное поведение, в ОСях (всех, кстати) этот поинтер используется исключительно для ссылок.
          Часть использует pointer на всех кнопках (например, хабр).
          Потому что спеку не читали


          Microsoft, Apple, Google тоже не читали спеков (и пофиг что по-сути они сами их сейчас и создают и развивают). Потому что у них на сайтах все элементы, на которые можно кликнуть и которые при клике запустят какое-то действие — поинтеры. Это и кнопки (как текстовые, типа "войти", так и иконочные, типа лайков), и ссылки, и дропдауны, и таббары. Причём, на главной у МС, например, у меня на слайдере с картинкой поинтер (потому что при нажатии на слайд из этого слайдера открывается другая страница), а внизу на самом слайде 2 кнопки (play/pause). Так вот, одна из них — поинтер, а вторая — стрелка. Мне сразу стало ясно, что та, которая стрелка в данный момент неактивна, эта кнопка не выполнит действия. И да, на практике так и оказалось. Если бы МС следовала вашим советам, то мне было бы совершенно непонятно, произойдёт ли что-то до нажатия на элемент.
          С поинтером же всё чётко: если я его вижу при ховере, то я ожидаю какого-то действия при нажатии. Если поинтера нет, то при нажатии на такой элемент ничего не должно случаться. И при этом, в ОС от вышеупомянутых компаний поведение курсора и элемента при ховере отличается от веба.


        1. anton_gcor
          18.01.2017 13:18
          +1

          Вопрос спорный, но вы правы больше, за вас спецификация) Действительно, если убрать pointer у всего кроме ссылок и сделать понятный hover, то этого хватит.


          Однако, присутствие pointer не так катастрофично и спека не запрещает его использование. Пользователи уже совсем перестали отличать ссылки от кнопок, особенно после отказа от подчеркиваний. Интересен сам факт, что в очень большом количестве проектов не ленятся ставить cursor: pointer. Ведь его нужно не забыть еще поставить. Значит спрос есть на это)


          Было бы интересно посмотреть различные статистики про курсоры. Может какой-нибудь амазон тестировал, что на ссылку с рукой ждут на 10% больше. Или Google.


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


          1. noodles
            19.01.2017 00:10
            +1

            Зато ленятся или забывают поставить cursor:default если элемент задизейблен. А это оказывается дополнительно неплохо снимает когнитивную нагрузку, чтоб понять что элемент не активен (как написал выше bromzh)


  1. Firefoxic
    18.01.2017 11:55

    Коммент не в том месте, простите :)


  1. IT_Hound
    25.01.2017 00:19

    Как вариант можно еще добавить кастомизацию страниц отвечающих за вывод ошибок 4xx,5xx и тд.