Проводы старого года – неплохой повод для обновления и смелых экспериментов. Если вы не впервые на CSS-live.ru, вы наверняка заметили, что у нас немножко поменялось оформление, и – надеюсь – что сайт стал чуть быстрее грузиться. Новая верстка – во многом эксперимент: в ней совсем нет оформительской графики, всё оформление сделано на CSS. Причем прямо в браузере, в live-режиме, т.е. вживую:)
Если хотите узнать, что толкнуло нас на этот эксперимент, как он помог нам добиться 100% в аудите Google Lighthouse по скорости, доступности, лучшим практикам и SEO, какие трудности преодолевали по пути и какие новые приемы использовали – добро пожаловать в эту статью!
Начало
Идея минималистичного, но оригинального дизайна для CSS-live преследовала меня уже давно. Были первые наброски еще в 2014-м. Кое-что оттуда пригодилось и позже, например, «переливчатое» подчеркивание ссылок и анимация логотипа в «заклинателя змей» при наведении. В последней версии сайта анимации вообще были «фишкой» (еще бы, львиную долю их сделал сам знаменитый Юрий Артюх!). Но всё-таки главное на нашем сайте – не спецэффекты, а контент. И хотелось по возможности обойтись без тяжелых JS-библиотек для сайта с названием CSS-live.
Много новых дизайнерских возможностей открыли CSS-гриды. Как-то раз, в ходе «игры» с расположением элементов, как-то сама собой сложилась надпись «CSS-live», составленная из пунктов меню. Максиму идея тоже понравилась…
Живой CSS в каждой букве
Оранжевая плашка в форме фигурных скобок — самой узнаваемой черты CSS, да и JS, и вообще фронтенда — уже давно часть «фирменного стиля» CSS-live.ru (фавиконка, аватарки в соцсетях), так что сделать из нее шапку сайта показалось логичным.
Да, один элемент, играющий роль и логотипа, и меню («2 в 1») выглядит непривычно, но мы решили — а почему бы нет? К тому же так уж исторически сложилось, что «главная навигация» у нас была не такой уж и главной — большинство хороших статей относилось к 2-3 рубрикам сразу, да и вообще грань между рубриками и тегами была довольно условной. Разбивка пунктов по трем группам-буквам даже помогла лучше структурировать навигацию: на букве «C» у нас собрались технологии, о которых мы рассказываем, на первой «S» — категории статей (теоретические, практические, ЧаВо, примеры…), а последняя «S» у нас как бы служебная — там текущие новости, информация о сайте и своего рода «музей» ценных материалов из прошлого (цикл статей о тайнах CSS2.1, написанный в 2012 г. и во многом еще актуальный, но всё же 7 лет для веба — приличный срок). Там же уместился список наших «представительств» в соцсетях и каналах (можете посмотреть в инспекторе, как удалось сделать это без подсеток:).
В дефисе и букве «l» от «live» тоже притаились функциональные элементы. Кстати, микроанимация всей конструкции при их активации — еще одна демонстрация гибкости современного CSS.
Ну и сейчас никуда без адаптивности. Широкую надпись в узкое мобильное окно не впишешь, пришлось ее перестраивать — к счастью, это оказалось не так сложно благодаря кастомным свойствам. Для читаемости крайние буквы пришлось чуть-чуть подвинуть CSS-трансформацией. Она же пригодилась при анимации свернутого меню в развернутое и обратно. Кстати, она тоже без JS, и срабатывает не только по клику (через скрытый чекбокс — трюк не всегда оправданный, но… почему бы нет?:), но и при активации ссылок и форм клавишей Tab (через новый псевдокласс :focus-within
).
CSS-переменные же помогли очень легко добавить для сайта темную тему оформления, без которой тоже трудно представить себе серьезный сайт в 2019-м. Лишь для пары сторонних виджетов, изначально сделанных для светлого фона, пришлось применить трюк с filter:invert(93%)
.
Текст по линеечке
В новой версии сайта хотелось уделить больше внимания контенту. Чтобы не было слишком длинных строк, неудобных для чтения, текст был достаточно контрастным и нормально вел себя при масштабировании. В прошлой версии также были проблемы с таблицами, точнее, их адаптацией. Для адаптации таблиц всё-таки требовалась небольшая помощь JS, чтобы навесить необходимые атрибуты. Почему бы заодно с этим не попробовать улучшить что-нибудь еще? Например, вертикальный ритм, для которого в CSS разрабатываются сразу два механизма — Line Grid и Rhythmic Sizing — но ни один из них пока не поддерживается в браузерах без флагов.
Если вы просматриваете сайт на большом экране, скорее всего вы заметили ненавязчивые горизонтальные линии, по которым выровнен текст. Их шаг строго равен line-height основного текста (1.5 кегля шрифта), и все отступы между блоками кратны ему. Чтобы ритм не сбивался на вставках блоков с непредсказуемым содержимым (картинок, iframe-ов и т.п.), общая высота таких элементов искусственно увеличивается до ближайшего кратного этому шагу — именно так со временем обещает работать Rhythmic Sizing. На большом экране отступы крупных заголовков увеличиваются еще на один шаг. В узких колонках некоторые элементы могут показаться слишком «прижатыми» друг к другу, но с целой строкой отступа они выглядели бы вообще «оторванными», а что-то промежуточное сломало бы вертикальный ритм. Похоже, с развитием CSS такой выбор будет вставать всё чаще.
Считается, что единый вертикальный ритм помогает чтению длинных текстов (а их у нас много). Проверим, так ли это! Ну и заодно оцените новую адаптивность таблиц (например, этой🙂
Не пытайтесь повторить это дома в продакшене
Эксперименты хороши тем, что в них можно попробовать и такое, что я сам не рискнул бы использовать где-то еще. Например, я не устоял перед соблазном поменять визуальный порядок блоков и на главной и архивных страницах вывести aside
, идущий в коде позже, перед main
, идущим раньше. Такой возможностью CSS-гридов восторгался сам Эрик Мейер, но в общем случае злоупотреблять ей не стоит.
Зато благодаря СSS Shapes, позволяющим обтекать текстом непрямоугольные контуры (о них на последних Web Standards Days в Минске хорошо рассказала Юлия Бухвалова), получился эффект, будто шапка сайта «плавает в гуще» текущей активности (новостей и комментариев) — по-моему, очень созвучный теме «CSS вживую». Может, ради такого всё-таки стоило чуть-чуть нарушить правила?.. 🙂
Еще более спорное решение, которое я всё же применил осознанно — display: contents
для main на этих же страницах, что позволило вписать основные статьи и вспомогательные блоки в одну и ту же сетку. Это полностью соответствует замыслу CSS Display 3 уровня (об чем даже добавили специальное примечание), но браузеры пока, увы, до его правильного понимания не доросли. Осталась загвоздка и в спецификации HTML, где элементы с display: contents
почему-то считаются… «не отрендеренными» (хотя у них есть видимое и интерактивное дерево потомков!). Может быть, появление реальных сайтов, использующих CSS как задумано, поможет убедить браузеры, что их текущее поведение — баг. А они, в свою очередь, докажут редакторам спецификации HTML, что можно убрать элемент из визуальной структуры отображения, не ломая его семантики и доступности.
А вот на страницах отдельных статей (вот прямо здесь внизу, например) удалось визуально «перетасовать» блоки из двух разных aside
-ов без display: contents
и его издержек (надеюсь, временных). Можете посмотреть в отладчике, как:). Но тоже не злоупотребляйте!
100% в Google Lighthouse
Если в старину верстальщики боролись за «зеленую галочку» в валидаторах W3C, то сейчас ее заменила встроенная в браузер Chrome проверка множества показателей сайта сразу — скорости, доступности, оптимизации для поисковиков и т.п. Мы тоже решили не отставать.
По идее, легкое (весь CSS, за вычетом стилей плагинов типа WYSIWYG-редактора для комментариев, после gzip-сжатия занимает всего 7.5 кБ!) и простое (выдумывать что-то сложное и навороченное просто не было времени:) оформление сайта должно помогать быстрой загрузке. Но «маяк» высветил немало слабых мест.
Подсказки Lighthouse помогли несколько оптимизировать загрузку шрифтов (основной шрифт, «обычная» Lora для кириллицы, подгружается с помощью <link rel="preload">
, так что 99% текста сразу отображается как надо — похоже, эта стратегия вполне дозрела!). Без document.write
загрузка тоже стала ощутимо быстрее. Для выполнения рекомендации об отложенной загрузке (lazy-loading) картинок оказалось достаточным добавить к ним новый атрибут loading="lazy"
(Chrome, где идет проверка, его уже поддерживает, надеюсь, что другие браузеры и стандарт вот-вот догонят). Правда, эта отложенная загрузка оказалась еще одним испытанием для вертикального ритма в случае, если пользователь переходит на новую страницу не к началу, а к какому-то месту в середине… но это дело поправимое. Был еще забавный момент, когда я сгоряча поставил этот атрибут и на картинку счетчика в подвале… и удивился внезапно упавшим показателям посещаемости: похоже, процентов 20 посетителей не прокручивали страницу до конца:). Но счетчик и так не слишком замедлял загрузку, особенно (тоже Lighthouse подсказал) при поддержке <link rel="preconnect">
.
Сильнее всего загрузку задерживали сторонние виджеты (предсказуемо). Но, как ни странно, «основной процесс» отрисовки поначалу тоже оказался долгим, даже дольше, чем в прошлой версии. Отчасти это, возможно, связано с выбранной схемой раскладки, в которой много элементов зависит от расположения друг друга (высота ячеек грида определяется автоматически, плюс содержимое еще выравнивается по нижней базовой линии заголовков, с помощью трюка с инлайн-блоками). Но оказалось, что на отрисовку влияют и совершенно неочевидные мелочи. В частности, в Safari простой hover-эффект на меню работал «рывками», а отладчик показывал непрерывную перерисовку чуть ли не всей страницы. Виновник нашелся быстро: им оказался… transition: all
для ссылок! После замены all
на явное перечисление меняющихся свойств и перерисовки, и «тормоза» сразу исчезли. На всякий случай, чтобы не нагружать браузер лишними перерисовками при анимации впридачу к и так непростой работе по начальной отрисовке страницы, я решил включить transition
только когда у body
появится класс ready
, который ставится скриптом в знак полной готовности «облагороженной» DOM.
Встречались и другие странные и нелогичные баги (?), не только в связи с оптимизацией. Например, Chrome на Маке (с «ретиной») почему-то странно обрабатывал em-ы в медиавыражениях: их границы срабатывали, как если бы дефолтный font-size
был равен не 16px, а 18px. Неожиданно помогла замена font-size: 50%
на font-size: calc(1rem / 2)
для html
.
Конечно, улучшать показатели еще есть куда, и впереди еще немало работы (полностью избавиться от jQuery, например). Но как минимум главная страница при быстром интернете уже набирает 100 баллов из 100 по 4 показателям из 5. Чем, наверное, уже можно похвастаться:)
Заключение
Это эксперимент. Поэтому нам очень важны ваши отзывы о том, что пока получается. Также заранее спасибо о любых найденных багах и проблемах. И… с наступающим 2020-м! 🙂
P.S. Это тоже может быть интересно: