company_banner

6 мощных возможностей CSS, которые позволяют обойтись без JavaScript

Автор оригинала: Diogo Rodrigues
  • Перевод
В последнее время часто сравнивают CSS и JavaScript, споря о применении этих технологий для решения определённых задач. Споры становятся жарче по мере появления новых замечательных возможностей CSS, которые позволяют упростить решение множества задач и отказаться при этом от JS.



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

  • CSS, по своей природе, является технологией, устойчивой к отказам. Это значит, что когда CSS-парсер встречает свойство, которое он не понимает, он просто игнорирует его и идёт дальше. Другими словами, используя CSS, программист применяет стили и ожидает, что они окажутся работоспособными.
  • JavaScript отказоустойчивой технологией не является. Единственная синтаксическая ошибка в JS-коде может нарушить работу целого приложения. То есть, управляя стилизацией сайтов с помощью JS, совершенно необходимо проверять работоспособность соответствующих конструкций.

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

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

В этом материале я расскажу о некоторых интереснейших возможностях CSS (некоторые из них — очень свежие), о которых вы, возможно, ещё не знаете. А именно, речь пойдёт о плавном скроллинге, о свойстве position: sticky, и о других возможностях, для реализации которых раньше требовалось написать немало строк хитроумного JS-кода.

1. Плавная прокрутка


Раньше, для оснащения страницы плавной прокруткой, требовалось задействовать несколько строк JS-кода. А теперь эта задача может быть решена исключительно средствами CSS. Ну не замечательно ли это? Теперь воспользоваться плавной прокруткой можно, прибегнув к CSS-свойству scroll-behavior.

Вот как это выглядит:

html {
  scroll-behavior: smooth;
}


Реализация плавной прокрутки

Вот пример на CodePen

Во время написания этого материала свойство scroll-behavior поддерживается лишь в Chrome и Firefox. Его пока не поддерживают Edge, IE и Safari (настольная и мобильная версии). Подробности о поддержке этого свойства можно узнать на Can I Use.

2. Закрепление элементов


Закрепление элементов — это одна из моих любимых возможностей CSS. Речь идёт о том, что соответствующие элементы не исчезают из области просмотра при прокрутке страниц. Теперь для закрепления элементов на страницах нет нужды прибегать к offsetTo и window.scrollY в JS. В наши дни можно просто воспользоваться CSS-свойством position: sticky:

header {
  position: sticky;
  top: 0;
}


Навигационный блок «упирается» в верхнюю границу области просмотра и не исчезает при прокрутке страницы

Вот проект на CodePen, в котором приведён пример использования свойства position: sticky

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

Взглянем на следующий HTML-код:

<main class="container">
  <nav class="nav">
    <ul>
      <li>Home</li>
      <li>About</li>
      <li>Contact</li>
    </ul>
  </nav>
  <div class="main-content">Main Content</div>
  <footer class="footer">Footer</footer>
</main>

Меню (элемент nav из этого примера) можно будет зафиксировать только в области, которую перекрывает его родительский элемент (main в нашем примере). В результате при использовании свойства position: sticky можно выделить два основных класса элементов:

  • Закрепляемый элемент: это тот элемент, к которому мы применяем свойство position: sticky (nav в нашем случае). Этот элемент будет перемещаться в пределах родительского элемента до тех пор, пока не дойдёт до заданной позиции. Например — это может быть top: 0px.
  • Контейнер закрепляемого элемента: это — HTML-элемент, в котором содержится закрепляемый элемент. Это — та область, в пределах которой может перемещаться закрепляемый элемент. Этот «контейнер» определяет границы, в которых может существовать закрепляемый элемент.

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

Данная возможность отличается практически 100% браузерной поддержкой.

3. Обрезка текста


CSS даёт в наше распоряжение два чудесных свойства: text-overflow и line-clamp. Они позволяют обрезать тексты, аккуратно обращаясь со словами, и при этом избавляют нас от необходимости использовать для решения подобных задач JavaScript или какие-то другие сложные методы. Оба свойства не новы, но крайне полезны.


Обрезка текстов

Вот пример на CodePen

Давайте подробнее поговорим о свойствах text-overflow и line-clamp.

▍Свойство text-overflow


Это свойство управляет тем, как текст выводится в ситуациях, когда он, если не помещается в одной строке, должен быть обрезан. Пример такой ситуации показан на вышеприведённом рисунке, в заголовке карточки. Тут можно воспользоваться конструкцией text-overflow: ellipsis, что приведёт к тому, что в конец обрезаемого текста будет добавлен Unicode-символ ().

Для того чтобы свойство text-overflow: ellipsis сделало бы своё дело, необходимо использовать так же свойства white-space: nowrap и overflow: hidden.

.card-title {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

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

▍Свойство line-clamp


Это свойство приходит нам на помощь в тех случаях, когда надо работать не с однострочным, а с многострочным текстом (пример такого текста — это содержимое карточки с вышеприведённого рисунка). Хотя это — часть стандарта CSS Overflow Module Level 3, который сейчас имеет статус «рабочего черновика («Working Draft»), данное свойство уже поддерживают порядка 95% браузеров, правда, с префиксом -webkit-. Перед его использованием важно учитывать то, что оно не даёт возможности управления количеством выводимых символов. Но оно, в любом случае, невероятно полезно.

Нам, чтобы им пользоваться, надо прибегнуть к старой реализации flexbox, применив свойства display: -webkit-box и -webkit-box-orient: vertical. Вот как это выглядит:

.card-description {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
}

4. Пользовательские CSS-свойства: CSS-переменные


В JavaScript-мире препроцессоры CSS (вроде Sass, Less и Stylus) — это очень полезные и популярные технологии. Препроцессоры расширяют возможности CSS, позволяя пользоваться, например, переменными и функциями. Но современным веб-дизайнерам доступны мощные стандартные возможности CSS, известные как пользовательские CSS-свойства или CSS-переменные.

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

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

Создавать CSS-переменные очень просто. А именно, для объявления переменной достаточно поставить два тире (--) перед её именем. После этого, там, где нужно значение переменной, вызывают функцию var(), передавая ей созданную ранее переменную в качестве аргумента. Как видите, всё очень просто.

:root {
  --base: #ffc600;
  --spacing: 10px;
  --blur: 10px;
}

img {
  padding: var(--spacing);
  background: var(--base);
  -webkit-filter: blur(var(--blur));
  filter: blur(var(--blur));
}

.hl {
  color: var(--base);
}

CSS-переменными можно управлять из JavaScript.


Использование CSS-переменных

Вот пример на CodePen, где показано использование CSS-переменных и управление ими из JS-кода

5. Обеспечение поддержки тёмной темы


С тех пор, как компания Apple представила в прошлом году тёмную тему для macOS, и благодаря тому, что CSS дал нам возможность обнаруживать применение этой темы с использованием медиазапроса, многие крупные веб-проекты (например, вроде Twitter и Google Maps) такой темой обзавелись (вот список проектов, которые поддерживают тёмную тему).

Тёмная тема — это не просто способ украшения веб-страниц. Она способна реально помочь некоторым людям работать в интернете.

Вот несколько цитат.

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

Томас Штайнер, Customer Solutions Engineer, Google, Германия.

У Молли — синдром Ушера. Из-за этого она ничего не слышит, а поле зрения одного из её глаз ограничено 5 градусами. (…) Просмотр страниц в тёмном режиме будет ей по силам. Этот режим может пригодиться и другим людям, расширяя возможности по работе в интернете для тех, у кого болит голова, или для тех, кому приходится сидеть за компьютером в плохо освещённой комнате. Если при разработке чего-либо ориентироваться лишь на некоторых особенных пользователей, это окажется полезным далеко не только им.

Чарльз Рейнольдс, дизайнер, правительство Великобритании.

Кроме того, из материала Томаса Штайнера можно узнать о том, что использование тёмной темы способствует экономии энергии: «(…) как известно, использование тёмного режима на AMOLED-дисплеях позволяет сэкономить немало энергии. Исследования в сфере Android-устройств, направленные на популярные приложения Google, вроде YouTube, показали, что в некоторых случаях экономия энергии может достигать 60%».

Новая возможность CSS, которая позволяет нам узнавать о том, включена ли у пользователя тёмная тема, представлена медиа-функцией prefers-color-scheme. Она уже совместима с Chrome, Firefox, Safari и Opera.

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

:root {
  --color: #222;
  --background: #eee;
  --text: 'default';
}

body {
  color: var(--color);
  background: var(--background);
}

body:after {
  content: var(--text);
  display: block;
  text-align: center;
  font-size: 3rem;
}

@media (prefers-color-scheme: light) {
  :root {
    --color: #222;
    --background: #eee;
    --text: 'light';
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    --color: #eee;
    --background: #222;
    --text: 'dark';
  }
}


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

→ В данном CodePen-проекте оформление страницы зависит от того, какую тему использует тот, кто просматривает этот пример

6. Директива supports


Долгое время веб-разработчикам приходилось прибегать к сторонним решениям (вроде JS-инструмента Modernizr) для выяснения того, поддерживаются ли некие возможности CSS текущим браузером. Например, настраивая свойство элемента -webkit-line-clamp, можно проверить, поддерживается ли это свойство в браузере, и, если это не так, можно воспользоваться каким-то запасным вариантом.

После того, как в CSS появилась директива @supports, проверять возможности браузеров стало можно прямо из CSS-кода.

Директива @supports очень похожа на медиазапросы. Она поддерживает различные комбинации выражений, построенные с помощью условных операторов AND, OR и NOT:

@supports (-webkit-line-clamp: 2) {
    .el {
        ...
    }
}

Здесь проверяется, поддерживает ли браузер свойство -webkit-line-clamp. Если это так, то есть, если условие оказывается истинным, будет применён стиль, объявленный внутри директивы @supports.

Эту возможность поддерживают все современные браузеры.

Итоги


В этом материале я рассказал о некоторых полезных возможностях CSS. Если вы можете сделать что-то без использования JS, а лишь применяя CSS, то так и поступите.

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

А вам известны какие-нибудь свежие возможности CSS, которые позволяют решать те же задачи, которые раньше решали только с использованием JavaScript?

RUVDS.com
VDS/VPS-хостинг. Скидка 10% по коду HABR

Комментарии 58

    +5
    А теперь всё тоже самое только с результатами caniuse.com
      +2
      Я не знаю почему, но всякий раз, когда я встречаю «заменим JS на CSS», оказывается, что вариант CSS жрет больше ресурсов и сильнее тормозит…
        +1
        И совместим не со всеми браузерами
          0

          В такой ситуации у меня обычно тормозят шрифты и картинки, запрос до которых почему-то в статусе stalled повисает секунд на 10-15.

            0

            Даже анимация?

            +1

            К сожалению, text-overflow: ellipsis, насколько я помню, работает только на однострочном тексте. Бывает, что нужно так обрезать многострочный текст и тут приходится выкручиваться другими способами.

              0

              Например line-clamp указанный в статье…
              Хотя я о нем тоже первый раз услышал )

              +1
              Раньше, для оснащения страницы плавной прокруткой, требовалось задействовать несколько строк JS-кода
              Раньше для этого нужно было поставить галочку в настройках браузера. Или убрать. А как быть с этим если я не хочу плавную?
              2. Закрепление элементов
              Всё отлично. Только закрепление ломает прокрутку и приходится юзать скрипты уже для правки этого. Попробуйте почитать хабр без скриптов. Клавиши Pgup/PgDn работают со всем окном и без скриптов получается систематический перелёт, т.к. панелька сверху отжирает часть окна.
                0
                А как быть с этим если я не хочу плавную?

                Я проверил, слава Богам, на Firefox никакой плавной прокрутки.
                  0
                  Проверил в файрфоксе, всё работает
                  developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior
                    0
                    Я к тому, что отключив плавную прокрутку в браузере, у меня прокручивает нормально (резко) во всех примерах. То есть поведение абсолютно корректное, поддерживаю использование этого свойства вместо костылей на JS, которые не учитывают мои настройки и делают кисельную прокрутку.
                      0
                      Но ведь и у меня smooth scrolling в настройках выключен, но прокручивает плавно с этим свойством.
                        0
                        А, теперь понял. Я думал оно на прокрутку мышью тоже будет работать. А оно работает на клики по буквам. Ну да ладно, не сильно страшно.
                  0
                  Попробуйте почитать хабр без скриптов. Клавиши Pgup/PgDn работают со всем окном и без скриптов получается систематический перелёт, т.к. панелька сверху отжирает часть окна.

                  Не смог воспроизвести ни в Chrome, ни в Firefox

                    +1
                    Waterfox. В обычной фоксе тоже работало так. Скрипты точно отключены? Со скриптами работает нормально
                      0

                      Да, отключены.

                        0
                        Magic.
                  0
                  После того, как в CSS появилась директива supports, проверять возможности браузеров стало можно прямо из CSS-кода.

                  Правильно ли я понимаю, что новая директива проверки накладываемых ограничений для старых браузеров поддерживается только на современных? Было бы уместно указать поддержку в данном случае как это работает. Логично было бы, если свойство только устанавливало выполнение включенного блока, а на устаревших браузерах он пропускался, но
                  Она поддерживает различные комбинации выражений, построенные с помощью условных операторов AND, OR и NOT

                  из этого можно вывести, что свойство выявляет различия только в современных браузерах между собой, в тех, где оно поддерживается. Это так?
                    0
                    Safari эту директиву не понимает. Итого пишем прогрессивный css с даунгрейдом по умолчанию, что сводит любые телодвижения к нулю ибо профитней чисто даунгрейженый css оставить (с навеской js по желанию) и не заморачиваться.
                    Я когда-то именно supports для position: sticky использовал (ну и так по мелочи), а потом нарвался на геморрой в поведении Safari, после чего решил ну его в пень.
                    0

                    text-overflow: ellipsis — почти полная поддержка всех браузеров — это не так!

                      +1
                      Зачем вставлять «скриншот» codepen, а ниже ссылку? ruvds со своими переводами всего и вся, мне кажется, начали сходит с ума
                        –1
                        спасибо было интересно, возможно когда нибудь в далеком будущем, можно будет все делать на одном css, без жаба-скрипта, это будет афигенски
                          0
                          Ссылка на caniuse говорит, что edge поддерживаект прокрутку с января этого года.
                            +1
                            Эджа больше нет, как не стало оперы.
                              0
                              А что в опере было важнее, функции или движок?
                                0
                                Существование альтернативного движка, как по мне, с точки зрения разработчика. Теперь остался только один конкурент, да и тот меньше 10%.
                                  0
                                  Есть ещё как бы мобильный рынок.
                                    0
                                    Где есть ещё сафари, который тот же вебкит, просто устаревший? Ну такое себе.
                                      0
                                      Ну Blink в 2013 в сторонку отошел, так что WebKit не устаревший, а параллельно развивающийся.
                                      Эт раз.
                                      Второе, море народа сидит на браузерах которые сжимают трафик (аналоги OperaMini) и ещё куча шлака всякого. Пока ты сайтом не продаёшь тебе то и насрать, а как узнаешь процентаж трафика со странных устройств и процентаж отказов, так сразу и айайай.
                                        0
                                        Ну Blink в 2013 в сторонку отошел, так что WebKit не устаревший, а параллельно развивающийся.

                                        При этом со стороны разработчиков вечный вой о том, что в сафари чего-то не хватает и что-то ломается.
                                        Второе, море народа сидит на браузерах которые сжимают трафик (аналоги OperaMini)

                                        В основном внутри всё тот же хром, а жмутся картинки и видео. Время настоящей OperaMini, которая полностью переписывала HTML, уже прошло.
                                        и процентаж отказов

                                        Благо у меня всё это заблокировано ))
                            0
                            Да, всё это конечно круто, но я уже год локти кусаю по поводу проксей из JavaScript и проблем с customElements с IE11. А тут такая же ситуация, supports, grid-Ы, прокрутка через CSS, это всё не сегодня. Через пару лет надеюсь, в лучшем случае. Пока IE11 всё ещё жив, обычный работяга всё ещё в пролете мимо новшеств мира сайтостроения))
                              0
                              неясно зачем они к такой нужной фишки как ограничение колво строк текста засунули какой то display -webkit-box
                                0

                                Пару раз пробовал использовать плавную прокрутку на css и всеравно возвращался к js. А все потому, что если header на позиции fixed, то элемент к которому скролим — частично прячется под этим header и еще были какие-то нестыковки, но уже не помню какие.

                                  0
                                  Поэтому не нужно прикреплять шапку. Пожалейте пользователей, у них и так вертикального пространства не хватает.
                                  И это я создателям Хабра.
                                    0

                                    Так не от меня же зависит, прикреплять шапку или нет, желание заказчика

                                      0
                                      Ну так это вы специалист, и вполне можете объяснить заказчику минусы такого решения. А то закажут сайт с градиентным сине-бирюзово-красным фоном в тонкую полосочку и жёлтыми буквами, вы тоже делать будете, да ещё и оптимизировать через градиенты постараетесь, или всё же объясните, что это дичь и от этого вытекают глаза?
                                        0

                                        Ну и при чем тут дизайн градиента к реализации скролла? Если дизайн заказчику нравится, то мне абсолютно всеравно какие там вырвиглазные цвета или кривые отступы у похожих блоков, тут в теме было, что реализация некоторой логики на css — лучше чем на js. Но в итоге из-за разного рода багов, всеравно лучше использовать js. А по поводу дизайнов, так о них не спорят, посмотрите, что студия Лебедева толкала за бешеные бабки. Что для нас не очень, то кому-то всеравно понравится

                                    0
                                    Я делаю элемент нулевой высоты, смещённый вверх на высоту шапки, и скролю к нему.
                                      0
                                      Полнится земля прикреплённой шапки костылями.
                                        0
                                        Ну а как же пользователю давать доступ к меню? Свайп сбоку делать? Придётся делать обучалку для сайта, потому что это не очевидно. А у некоторых браузеров это вообще системное поведеление для «назад».
                                          0
                                          У Хабра есть прокрутка наверх, хорошая, запоминает место. Есть сайты, которые показывают шапку при прокрутке назад, тоже не ломает естественное поведение.
                                          Свайп сбоку делать?

                                          Какой блин свайп? Я же не об ограниченных устройствах говорю.
                                            0
                                            А я о телефонах.
                                            У хабра есть всплывашка в низу страницы, но чтобы её увидеть, нужно отмотать достаточно далеко вниз, чтобы был запас для возврата наверх, а то она просто так не появляется.
                                              0
                                              А я о телефонах.

                                              Так там тем более места на экране нет, зачем его красть в пользу шапки?
                                                0
                                                А как быть с навигацией? Её можно спрятать за экран, как я выше писал, но как научить пользователя? Тем более, что многие места за экраном уже заняты.
                                                  0
                                                  но как научить пользователя?

                                                  Сам увидит, когда прокрутит. И да, шапка вполне себе может быть в шапке.
                                                    0
                                                    Я имею в виду спрятать, скажем, за правый край экрана
                                                      0
                                                      Ну так не нужно это делать. Шапка, появляющаяся при обратной прокрутке, с гамбургером, открывающим меню с левой или правой части экрана. Почему бы и нет.
                                    0
                                    Противопоставление этих двух технологий — что-то новое в разработке. Но лучше использовать CSS там, где нужен CSS. И javascript там, где он нужен.
                                      0
                                      position: sticky; хорошая тема, но плохо дружит с overflow:hidden. Я сталкивался с таким вариантом.
                                        0

                                        Это все очень весело, но я бы выделил две явных проблемы:
                                        1) трудноуловимый источник странных проблем. Хорошо, если разработчик — я, и я примерно в теме того, где я понавертел всяких модных CSS-штук, а если нет — тушите свет! То, что раньше надо было выкапывать в 3-4 подключённых JS файлах, теперь надо будет искать ещё и в груде CSS, и дай бог, чтоб это не было "костылем", и не оказалось реализоваео в виде стиля прописанного прямо к элементу, прямо где-нибудь в PHP-коде!


                                        З.Ы. Только не говорите про отладчик… На всяких айфонах — это отдельные боль и страдания.


                                        2) Удвоение работы по разработке таким способом: сначала делаем для современных браузеров, а потом берём IE9 и проделываем все заново! Блеск!

                                          0
                                          а потом берём IE9

                                          И выкидываем его в окно.
                                          Ну или разработка за двойной ценник, почему бы и не переделать.
                                            0

                                            Нельзя в окно! Это засорение окружающей среды токсичными отходами!


                                            А если серьёзно — то все было бы очень круто, если бы в целевой аудитории многих компаний не сидели государственники с win XP и дефолтным браузером IE9, а за пультом этих шайтан-машин не сидели бабульки, которые при виде поехавшей вёрстки (или не дай боже ошибки какой) неистово крестятся и жмут на крестик.

                                              0
                                              win XP и дефолтным браузером IE9

                                              Эм, вы точно разработчик? XP дефолтно идёт с IE6, и абгрейдится до IE8. Девятой версии там никогда не было.
                                                0

                                                посыпал голову пеплом
                                                Блин, точно! В хрюшке ж IE8…
                                                Ну обосрался, ну бывает… IE8 судя по метрикам всё-таки почти вымер, а вот IE9 вижу стабильно.

                                          0
                                          Не ясно как работает темная тема(для меня).
                                          Она зависит от того какая тема стоит в браузере? да?
                                            0
                                            В системе.
                                              0
                                              Я пока не тестировал эту штуку, и мне интересно, оно способно узнать, что я в XFCE выбрал тему с тёмными элементами? Или оно только для винды и макоси?
                                                0
                                                Зависит от того, что там наворотили в XFCE. Linux дело такое, везде всё разное.

                                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                          Самое читаемое