cssnextВот уже на протяжении четырёх лет, с сентября 2011 г. W3C занимается разработкой CSS4. Модули четвёртой версии каскадных таблиц стилей проектируются на базе CSS3 и дополняют их новыми свойствами и значениями. В этой статье я хотел бы рассказать о том, как использовать возможности CSS4 уже сегодня, о cssnext.

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

Возможности


Автоматическая расстановка вендорных префиксов

Вендорные префиксы автоматически добавляются (или же, в том случае если они являются устаревшими, удаляются) с помощью PostCSS плагина Autoprefixer.

Переменные в свойствах CSS

Благодаря возможностям cssnext в корневом селекторе :root мы можем задавать неограниченное число переменных и использовать их в наших CSS свойствах.

:root {
  --fontSize: 1rem;
  --mainColor: #ddd;
}

a {
  color: var(--mainColor);
  font-size: var(--fontSize);
}

Спецификация | Документация плагина

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

Позволяет использовать свойство calc(). Данное свойство можно использовать не только с простыми значениями, но и с переменными.

:root {
  --fontSize: 1rem;
}

h2 {
  font-size: calc(var(--fontSize)*2);
}

Документация плагина

Переменные для медиа-запросов


@custom-media --small-viewport (max-width: 30em);

@media (--small-viewport) {
  /* Стили для маленьких экранов */
}

Спецификация | Документация плагина

Улучшенный синтаксис медиа-запросов

Позволяет использовать выражения >= и <= вместо min-width и max-width в медиа-запросах.

@media (width >= 500px) and (width <= 1200px) {
  /* Ваши стили */
}

Спецификация | Документация плагина

Пользовательские селекторы

Позволяет создавать свои собственные селекторы.

@custom-selector :--heading h1, h2, h3, h4, h5, h6;

:--heading {
  margin-top: 0;
}

Спецификация | Документация плагина

Функции для модификации цвета

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

a {
  color: color(red alpha(-10%));
}

a:hover {
  color: color(red blackness(80%));
}

Спецификация | Документация плагина

Поддержка цветов hwb()

Позволяет использовать W3C CSS hwb() цвета, которые будут преобразованы в rgb() или rgba()

body {
  color: hwb(90, 0%, 0%, 0.5);
}

Спецификация | Документация плагина

Более чем 50 оттенков серого

Возможность использовать свойство gray(). В качестве первого аргумента вы можете использовать значение от 0 до 255 или от 0 до 100 процентов.

.foo {
  color: gray(85);
}

.bar {
  color: gray(10%, 50%);
}

Спецификация | Документация плагина

Цвета #rrggbbaa

Даёт возможность использования чётырёх или восьмизначных значений для обозначения цвета.

.boo {
  color: #9d9c;
}

Спецификация | Документация плагина

Цвет rebeccapurple

Новый цвет.

.foo {
  background: rebeccapurple;
}

Спецификация | Документация плагина

Свойство font-variant

Данный плагин позволяет трансформировать свойство font-variant в CSS более совместимый с наиболее популярными на сегодняшний день браузерами.

h2 {
  font-variant-caps: small-caps;
}

table {
  font-variant-numeric: lining-nums;
}

Спецификация | Документация плагина

Фильтры

Позволяет использовать 10 различных CSS фильтров:
  • grayscale
  • sepia
  • saturate
  • hue-rotate
  • invert
  • opacity
  • brightness
  • contrast
  • blur
  • drop-shadow


.blur {
    filter: blur(4px);
}

Спецификация | Документация плагина

Единицы rem

Единицы rem возвращаются в px.

h1 {
    font-size: 1.5rem;
}

Спецификация | Документация плагина

Псевдокласс :any-link

Позволяет использовать класс :any-link для ссылок.

/* Из: */

nav :any-link > span {
    background-color: yellow;
}

/* В: */

nav :link > span,
nav :visited > span {
    background-color: yellow;
}

Спецификация | Документация плагина

Псевдокласс :matches

Позволяет использовать класс :matches().

/* Из: */

p:matches(:first-child, .special) {
  color: red;
}

/* В: */

p:first-child, p.special {
  color: red;
}

Спецификация | Документация плагина

Псевдокласс :not

Что-то схожее с предыдущим псевдоклассом, но с обратным результатом.

p:not(:first-child, .special) {
  color: red;
}

Спецификация | Документация плагина

Альфа-цвета

Добавляет цветовые фолбэки для rgba цветов (для старых браузеров).

body {
  background: rgba(153, 221, 153, 0.8);
}

Спецификация | Документация плагина

Также cssnano, кроме всего вышеперечисленного, содержит в себе ряд бонусных возможностей, таких как импорт(@import) сторонних CSS файлов в ваш конечный CSS файл, идущий на продакшен и сжатие конечного выходного CSS с помощью CSSNano.

Использование


Вы можете использовать cssnext как плагин для вашей любимой системы сборки Grunt, Gulp, Broccoli, Webpack, Fly и т.д. или же в качестве плагина для PostCSS.

Мне больше по душе последний вариант. Собственно, его я и использую в своей стартовой сборке для разработки собственных проектов.

Надеюсь, вам было интересно познакомиться с возможностями cssnext.

На этом всё. Спасибо за внимание!

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


  1. alemiks
    18.09.2015 23:41
    +7

    В блоке «What is cssnext» на сайте есть ссылка, которая ведет на страницу с надписью

    THERE IS NO SUCH THING AS CSS4

    Так что невозможно написать статью «Используем возможности того, чего нет»


    1. SelenIT2
      19.09.2015 10:56

      Более того, многие самые «вкусные» новинки CSS сейчас относятся к 1 уровню, и по логике статьи придется считать, что трансформации, флексбоксы, CSS-переменные и варианты наложения цветов — это «CSS1»!:)


  1. SerafimArts
    18.09.2015 23:57
    +15

    Ну вот смотрю я на это, придумывают всякое, что зачастую никому не нужно (цвет rebeccapurple, hwb и прочее), а самой обычной вложенности, совершенно очевидной и самой нужной фичи, которая есть в каждом существующем препроцессоре, как не было, так и нет. Грустно.


    1. azat-io
      19.09.2015 00:39
      +1

      Да, тут не поспоришь.


    1. VitaLik_is_goodman
      19.09.2015 12:37

      Что значит нет? Cssnext — это лишь набор плагинов для PostCss, с таким же успехом вы можете подключить и вложенность и остальные фишки. Поглядите на сайте postcss, это будущее, которое возможно уже сегодня.


      1. SerafimArts
        19.09.2015 19:56

        postcss — это постпроцессор, а не оригинальный css. Точно так же как babel, в котором хоть декораторы можно включить, которые в ES7 есть, но это не значит что оно будет в стандарте. Лично я в драфте вложенности не видел, может ткнёте носом, пожалуйста?


        1. MTonly
          19.09.2015 20:58

          я в драфте вложенности не видел
          Было предложение от Вкладки Таба Аткинса в списке рассылки www-style и даже черновик (сейчас ссылка недействительна) спецификации CSS Hierarchies, которая, судя по всему, особого энтузиазма у CSSWG не вызвала и сейчас доступна как не имеющий никакой формальной силы черновик CSS Nesting Module Level 3 в личном гитхабе Таба.


          1. SerafimArts
            19.09.2015 21:33

            Ну черновик, прямо скажем, говнистый. Синтаксис мне откровенно не нравится. У less, у sass\scss, stylus почти идентичный синтаксис, не понимаю, почему нельзя было его взять? Но нет, у нас «свой путь»… (с)


            1. MTonly
              19.09.2015 21:59

              Насколько я понимаю, опасаются неоднозначностей, которые усложняли (и, соответственно, замедляли) бы механизм разбора CSS-кода, вынуждая его «заглядывать вперёд» (look ahead), чтобы отличить вложенное правило от обычного объявления:

              Preprocessors are okay with needing arbitrary lookahead to parse CSS. Browsers aren’t — they want fast, parallizable parsing, and that means fixed, small amounts of lookahead.
              В этом плане вложенные блоки мне импонируют больше (скорее всего, в собственном препроцессоре я бы сделал так же), чем необходимость предварять каждое вложенное правило амперсандом, как это было в изначальных предложении и соответствующем черновике.

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


              1. SerafimArts
                20.09.2015 02:29
                +1

                Ну так уже на многолетней практике с препроцессорами разработчики убедились, что никаких подводных камней в синтаксисе с амперсандами нету. Единственные проблемы есть (были) в less из-за конфликтов «собак» с какими-либо специфическими медиа-выражениями. По-моему sass хоть прямо сейчас бери и основывай на его синтаксисе новый стандарт, всё работает без каких-либо проблем. Единственное — синтаксис циклов, условий и прочего немного не нравится, но с этим можно свыкнуться.


                1. MTonly
                  20.09.2015 02:41

                  подводных камней в синтаксисе с амперсандами нету.
                  Подводных камней нет, просто неудобно и не оч. DRY каждое вложенное правило предварять амперсандом: проще добавить один вложенный блок ({…}), внутрь которого поместить произвольное количество правил без ведущего амперсанда.


                  1. SerafimArts
                    20.09.2015 18:02

                    Амперсанд — это конкатенация правил. С другой стороны смысл есть в скобочной вложенности, убедили, только амперсанд погибче будет.

                    Пример из scss
                    .blog {
                      ...
                     &-comment {
                        ..
                     }
                    
                     a { ... }
                    
                      @at-root .some {
                      }
                    }
                    


                    На выходе:
                    .blog {
                      ...
                    }
                    
                    .blog-comment {
                      ...
                    }
                    
                    .blog a { 
                      ...
                    }
                    
                    .some {
                      ...
                    }
                    


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


                    1. MTonly
                      20.09.2015 19:06

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

                      .example {
                          color: red;
                          {
                              .a {}
                              .b {}
                              .c {}
                          }
                      }
                      

                      чем так:

                      .example {
                          color: red;
                          & .a {}
                          & .b {}
                          & .c {}
                      }
                      


                      1. SerafimArts
                        20.09.2015 21:51

                        Зачем во втором примере нужны амперсанды? Это изврат по-моему.

                        .example {
                            color: red;
                            .a {}
                            .b {}
                            .c {}
                        }
                        

                        Будет всё тоже самое.


                        1. MTonly
                          20.09.2015 22:55

                          Из моего второго комментария:

                          опасаются неоднозначностей, которые усложняли (и, соответственно, замедляли) бы механизм разбора CSS-кода, вынуждая его «заглядывать вперёд» (look ahead), чтобы отличить вложенное правило от обычного объявления.


                          1. SerafimArts
                            20.09.2015 23:54

                            А т.е. боятся, что один и тот же символ (амперсанд) означает разное поведение. В одном случае вложенность html тегов (a > b), в другом — вложенность css деклараций (.a.b). Я понял.


                            1. MTonly
                              21.09.2015 00:14

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

                              .example {
                                  color {}
                              }
                              

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

                              А здесь:

                              .example {
                                  & color {}
                              }
                              

                              по амперсанду сразу понятно, что это не имя свойства, а селектор.


    1. Ai_boy
      22.09.2015 22:46

      Я с вами совершенно согласен, особенно по поводу вложенности, но вот по поводу цвета rebeccapurple не соглашусь. Почитайте причину по которой данный цвет был добавлен ( meyerweb.com/eric/thoughts/2014/06/19/rebeccapurple ) и если после этого вы считаете что это не нужно было делать то я уже и не знаю как вас назвать…


      1. SerafimArts
        22.09.2015 23:40

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


  1. expeerd
    18.09.2015 23:57
    +1

    И все-таки грустно, что для подобных вещей нужны sass, cssnext, postcss etc.


  1. Denai
    19.09.2015 04:49
    +3

    Я вот не очень понимаю как это работает. Допустим calc(). Он сейчас есть у 76% пользователей из тех что переписал caniuse. У части из них он без поддержки половины функционала. С вот этой штукой из статьи он у них как-то работать начнёт? Вот прям на opera mini и ie8? А можно пример? Не такой где calc( 1px + 2px), а хотя бы width: calc( 50% — 20px).


    1. extempl
      19.09.2015 08:51

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


      1. azat-io
        19.09.2015 10:58

        Могу в качестве примера привести грид-сетку.

        :root{
          --fullWidth: 100%;
        }
        
        .col-11 {
          width: calc(var(--fullWidth)/12*11);
         }
        
        .col-10 {
          width: calc(var(--fullWidth)/12*10);
         }
        
        .col-9 {
          width: calc(var(--fullWidth)/12*9);
         }
        ...
        


        1. extempl
          19.09.2015 12:34

          Вопрос комментатора выше скорее заключается в том, как плагин поможет тем у кого calc не поддерживается в принципе? Какие фолбэки используются в данном случае?


          1. Denai
            19.09.2015 13:01

            На вопрос, я так понимаю, уже ответили. Вся фишечка именно в переменных, в данном случае --fullWidth. Сам же calc() остаётся таким же как и был, но автоматически прописывается ещё и с префиксами для старых версий. Выходит что уже сейчас можно писать код, который когда-нибудь в далёком будущем будет работать без танцев с бубнами, но сейчас может дать не очень полезный результат. В том же примере azat-io использование calc() не имеет практического смысла, в конечном коде его не будет, он схлопнется сам.


    1. Antelle
      19.09.2015 09:50

      Тут, кажется, только о том, что в calc можно вставить переменную. Т.е. будет работать только у тех, у кого поддерживается calc.


  1. extempl
    19.09.2015 08:48
    +4

    Улучшенный синтаксис медиа-запросов

    Позволяет использовать выражения >= и <= вместо min-width и max-width в медиа-запросах.

    @media (width >= 500px) and (width <= 1200px) {
      /* Ваши стили */
    }
    
    По-моему, улучшенный синтаксис, это когда @media (500px <= width <= 1200px) , а так — один фиг, что min-width, что width <=.

    Цвет rebeccapurple
    Вот это вот вообще не следовало сюда включать.

    Псевдокласс :not
    Следует указать, что этот псевдокласс уже существует и успешно используется. В CSS4 только добавляется возможность указать список.

    Единицы rem
    У Вас даже линк ведёт на спецификацию CSS3. Так что оно делает здесь?


    1. azat-io
      19.09.2015 11:00

      Плагин автоматически создаёт фолбэки для старых браузеров.


      1. extempl
        19.09.2015 12:32

        Это Вы к чему?
        Мой комментарий преимущественно об этом:

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


  1. mr_T
    19.09.2015 13:13
    +2

    По мне так это все высосано из пальца. Практически все из этого или есть в существующих препроцессорах, или достигается миксинами, или просто поддерживается большинством браузеров (тот же rem). По сути из всего списка действительно полезная и новая вещь — это пользовательские селекторы (не уверен, но вроде в less, sass, stylus такого нет). Хотя только из-за этого я вряд ли пересяду со stylus'а.


    1. VitaLik_is_goodman
      19.09.2015 14:28

      Фишка cssnext, в том, что это набор простых плагинов для Postcss, то есть добавление других возможностей очень просто и быстро. Что-то дописать в stylus сложно и требует гораздно большего времени и экспретизы, так что если все пойдет хорошо, то postcss станет таким неким двигателем прогресса для css, как трансшпилеры для javascript. Ну и следующий бутстрап будет на postcss, так что если ничего нового не придумают, то уверен, что появится просто реализация stylus на postcss( кстати близкая реализация к scss уже есть на их сайте), и stylus как отдельный проект закроется


      1. mr_T
        19.09.2015 14:48
        +2

        Если рассматривать с точки зрения фронтенд разработчика, то вообще без разницы, использовать ли less/sass/stylus или postcss с плагинами. Но тут такая беда: css сам по себе — это не более, чем просто таблица стилей, что ярко показывает расшифровка аббревиатуры. Тут не нужны какие-то супер-пупер плагины, а достаточно того, что уже есть в препроцессорах, а именно переменных, автопрефиксов, в редких случая циклов, вложенности и замены некоторых свойств на их более совместимые со старичками конструкции (необходимость которых падает с каждым днем со скоростью, сравнимой со скоростью развития postcss).

        Итого лично я стал бы использовать postcss в том случае, если он ИЗ КОРОБКИ и БЕЗ ДОПОЛНИТЕЛЬНОЙ НАСТРОЙКИ ПЛАГИНОВ давал бы мне больше, чем stylus. Но stylus (с 1 модулем kouto-swiss) уже дает мне все, что нужно. Если углубляться, то stylus, к тому же, дает объективно больше, чем остальные препроцессоры.
        А зачем мне «язык программирования» для css? Я считаю, что оно того не стоит и роль postcss в будущем написания стилей сильно преувеличена.

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


      1. mr_T
        19.09.2015 15:00
        -2

        Да, и по поводу JavaScript: «трансшпилеры» (если имеются в виду всякие TypeScript и CoffeeScript) — это редкая кака, вызванная неспособностью людей после классических ООП языков понять концепцию прототипов. Ну нету в JS классов, смиритесь с этим, люди! Так нет, в JS зачем-то добавляют классы, хотя их там быть не должно… Нет, там, безусловно, есть удобные штуки вроде скобочной нотации анонимных функций, но зачем мне все это, если у меня есть IDE с автодополнением, а на выходе один хрен мы получаем JavaScript? Тоже, в общем, непонятно мне это.


        1. VitaLik_is_goodman
          19.09.2015 15:38

          Вброс, конечно, сильный :) Но думаю с тем, что тесты на том же coffescript смотрятся куда красивее, вы ведь спорить не будете?

          Ну и es6 смотрели? Вот ведь глупые, синтаксический сахар для классов то все-таки ввели, темный люди :(


          1. mr_T
            19.09.2015 17:15

            Да, лично я считаю, что это неверный шаг, так как он по-прежнему является именно «сахаром», даже на уровне языка в случае с ES6. Прототипы-то все равно никуда не делись, в итоге они и получаются! И это нужно понимать при программировании на JS, и как раз это то, в чем не все с ходу разбираются (и себя я тоже подразумеваю, я долго доходил до философии JS после Java и C#, да и не совсем уверен, до конца ли я дошел), а ключевое слово class в JS только ставит палки в колеса при понимании этого.
            Нет, я не могу спорить с очевидным — код с сахаром может (но может и нет) выглядеть более читаемым, но это не должно достигаться путем подмены понятий, так как ведет к фундаментальному непониманию.
            Да и, кстати, с выходом ES6 отпадет необходимость использовать «трансшпилеры», если, конечно, те не придумают какую-то убер-фичу.


        1. Finom
          19.09.2015 17:45

          Я вас расстрою, но классы давно поддерживаются Хромом из коробки.


          1. mr_T
            19.09.2015 17:49

            И это не есть хорошо. Так что я действительно расстроен)


        1. SerafimArts
          19.09.2015 21:40

          Я писал и на ES6 (плюс некоторые плюшки из ES7, декораторы, использовал в качестве экспериментов с контрактным программированием): https://github.com/SerafimArts/ES7-Sandbox и на Coffee, и на чистом JS, и на TypeScript.

          И знаете что скажу? CoffeeScript зачастую намного приятнее использовать. Просто наличием автоматического ретурна, постусловий (some if true, вместо if true then some) и самое главное — циклов for in + for of, вот без последнего реально очень тяжко жить. Безумно тяжко. А без классов обойтись вполне возможно, пара вложенных замыканий и вперёд.


          1. VitaLik_is_goodman
            19.09.2015 22:47
            -1

            рубисты плохо не придумают, у них в крови постусловия :)


    1. asave
      22.09.2015 11:00
      +1

      > По мне так это все высосано из пальца. Практически все из этого или есть в существующих препроцессорах
      Стандарт по-любому лучше зоопарка препроцессоров. Даже если этот стандарт в черновиках.
      Ну а если все это высосано из пальца, то зачем тогда нужны сегодняшние препроцессоры?


  1. Finom
    19.09.2015 17:43
    +4

    Сорри за эмоции, но. Кто, их мать, придумал такой страшный синтаксис для переменных? Функция var, в которую нужно передать имя переменной, которое начинается двойным дефисом? Какого… нужен этот var? Почему решили использовать двойной дефис вместо понятного всем доллара?

    $variable vs var(--variable)

    image

    Еще меня несколько расстраивает отсутствие вложенных правил, как в scss. Прийдется по-прежнему повторять колбасу из селекторов из раза в раз.


    1. MTonly
      19.09.2015 22:05
      +1

      Формально символ доллара не использован, т.?к. принцип работы CSS-переменных сильно отличается от того, как работают переменные в препроцессорах. Символ доллара зарезервирован для возможного использования в синтаксисе глобальных констант.

      CSS-переменные даже называются сейчас не переменными, а пользовательскими нестандартными свойствами (Custom Properties). Для нестандартных свойств, в свою очередь, всегда использовался префикс в виде дефиса, который для пользовательских свойств просто удвоен.


      1. Finom
        20.09.2015 14:18

        Спасибо за пояснение. Но меня часто посещает ощущение, что стандарты пишут люди, не написавшие и 100 тысяч строк кода в области, которую они стандартизируют.


        1. MTonly
          20.09.2015 19:10
          +1

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


      1. dim_s
        21.09.2015 00:56

        Тогда логичнее было бы назвать это property вместо var!


        1. MTonly
          21.09.2015 01:30

          У редакторов спецификаций порой своя, особенная логика. %)


  1. Rosscian
    19.09.2015 19:21

    А в чем прелесть этого пака? Например, перед PreCSS? Только в том, что он опирается на синтаксис, который, возможно, станет потом стандартным? Но ведь фича PostCSS именно в гибкости, а var(--variable) действительно ужасно. При этом есть postcss-media-minmax, позволяющий писать, как говорил выше extempl, @media (500px <= width <= 1200px), есть pixrem, есть тот же postcss-calc, которые возвращает уже вычисленное значение.

    Последний, кстати, включен в cssnano — один из немногих действительно интересных паков, потому что такие сборники все-в-одном, мне кажется, все же не самый лучший подход. Лучше подбирать действительно нужное под себя и конкретный проект…


    1. Finom
      20.09.2015 14:20

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