Shade: длинные тени трендового плоского дизайна на CSS

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

    lessshade
    Пример работает на LESS 1.5.0, поэтому нет возможности разместить его на codepen или jsfiddle.

     .shade(@type, @color, @depth, @angle, @long, @fade);
    

    • type: значения box/text — box-shadow/text-shadow
    • color: цвет тени
    • depth:длина тени
    • angle: угол наклона
    • long: boolean, по умолчанию true — длинные Flat тени
    • fade: boolean, по умолчания false — затухание


    #facebook {
        .shade(box, #1B2733, 20, 135deg, true, false);
        .shade(text, #253960, 50, 135deg, true, false);
        background: #4161A2;
        &:before {
          content: "\e000";  
        }
    }
    
    ...
    
    #dribble {
        .shade(box, #1B2733, 20, 135deg, true, false);
        .shade(text, #9B2E58, 15, 135deg, false, false);
        background: #C23B6F;
        &:before {
          content: "\e00f";  
        }
    }
    


    LESS 1.5.0


    Shade.less написан на «чистом» LESS только благодаря этой версии.
    В другом случае пришлось бы использовать JavaScript подобным образом:
        @shade: ~`(function (depth,x,y, ... thislightness) {
            var shadow = "";
            for(var i=1; i<depth; i++) {
                if (i != depth) {
                    shadow += i*x+"px "+i*y+"px 0 hsla("+thishue+", "+thissaturation+", "+thislightness - (i*darken)+", "+1 - (i * opacify)+"), ";
                } else {
                    shadow += i*x+"px "+i*y+"px 0 hsla("+thishue+", "+thissaturation+", "+thislightness - (i*darken)+", "+1 - (i * opacify)+");"; 
                }
            }
            return shadow;
        })("@{depth}", "@{x}", "@{y}", ... "@{thislightness}")`;
    


    Новые возможности в 1.5.0 Beta 1 (2013-09-01)

    • Поддержка source map (хороший пост на Хабре про это здесь)
    • Возможность прописывать дополнительные опции при подключении файлов @import (inline) "file.css";
    • Поддержка Guard для множества селекторов
    • Добавлены функции min/max
    • Новый «объединяющий» синтаксис для свойств — property+: (как раз то, что используется в shade.less, эквивалентно операнду += в JS):

      text-shadow+: (@i * @x) (@i * @y) 0 hsla(@hue, @sat, (@lightness - (@i * @darken)), (1 - (@i * @opacify)));
              

    • Функция svg-gradient
    • Множество полезных фиксов


    shade.less



    .shade(@type, @color: #3498db, @depth: 20, @angle: 135deg, @long: true, @fade: false) {
        @ang: (@angle - 90deg);
        @x: 1.5px * cos(@ang);
        @y: 1.5px * sin(@ang);
    
        .shade(@type, @color, @depth, @x, @y, @long, @fade, (lightness(@color)/@depth)/2, (alpha(@color)/@depth));
    }
    
    /* Если тень"длиная", то она одного цвета */
    .shade(@type, @color, @depth, @x, @y, @long, @fade, @darken, @opacify) when (@long = true) { 
        .shade(@type, @color, @depth, @x, @y, @fade, 0, @opacify);
    }
    /* В другом случае осветляем тень от конца к началу */
    .shade(@type, @color, @depth, @x, @y, @long, @fade, @darken, @opacify) when (@long = false) { 
        .shade(@type, @color, @depth, @x, @y, @fade, @darken, @opacify); // 
    }
    
    .shade(@type, @color, @depth, @x, @y, @long, @darken, @opacify) when (@fade = true) {
        .shade(@type, @color, @depth, @x, @y, @darken, @opacify);
    }
    /* Если тень "длиная" она должна выглядеть монотонно без затухания */
    .shade(@type, @color, @depth, @x, @y, @long, @darken, @opacify) when (@fade = false) { 
        .shade(@type, @color, @depth, @x, @y, @darken, 0);
    }
    
    /* Разбиваем цвет на HSLA для дальнейшей работы. Недавно я задавал вопрос на эту тему http://habrahabr.ru/qa/46440/ */
    .shade(@type, @color, @depth, @x, @y, @darken, @opacify) { 
        @hue: hue(@color);
        @sat: saturation(@color);
        @lightness: lightness(@color);
        .shade-recursive(@type, 1, @depth, @x, @y, @darken, @opacify, @hue, @sat, @lightness);  
    }
    
    .shade-recursive(@type, @i, @depth, @x, @y, @darken, @opacify, @hue, @sat, @lightness) when (@i < @depth) and (@type = text) {
       text-shadow+: (@i * @x) (@i * @y) 0 hsla(@hue, @sat, (@lightness - (@i * @darken)), (1 - (@i * @opacify)));
       .shade-recursive(@type, @i + 1, @depth, @x, @y, @darken, @opacify, @hue, @sat, @lightness);
    } 
    .shade-recursive(@type, @i, @depth, @x, @y, @darken, @opacify, @hue, @sat, @lightness) when (@i < @depth) and (@type = box) {
       box-shadow+: (@i * @x) (@i * @y) 0 hsla(@hue, @sat, (@lightness - (@i * @darken)), (1 - (@i * @opacify)));
       .shade-recursive(@type, @i + 1, @depth, @x, @y, @darken, @opacify, @hue, @sat, @lightness);
    } 
            


    Github.

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

    Похожие публикации

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

      +2
      Спасибо за прекрасную статью.

      Код на SCSS гораздо более читаем. :) Не хотите выпустить Compass Extension?
        0
        Спасибо, рад быть полезным. То, что на SCSS более читаем — не спорю. Про Compass — врядли.
      +1
      Если ограничиться однородной тенью, уходящей в правый-нижний угол, можно выкинуть всю математику. Код сводится к нескольким понятным строчкам (пример на SASS):

      @mixin long-shade($color: red, $length: 100)            
        $shadow: () 
        
        @for $i from 1 through $length
          $shadow: $shadow, $i*1px $i*1px 0 $color
          
        text-shadow: $shadow

      Наклепал демо: sassbin.com/gist/6522344/
        0
        Тоже недавно эксперементировал с тенями, пробовал сделать мягкую тень (sass) codepen.io/ssh/pen/FgeCx
          +1
          Небольшой оффтоп:

          Я раньше тоже любил Less, почему? Ну просто «потому» — это почти аналогично «да я люблю Less больше». А потом одним вечерним днём меня под пытками заставили мне захотелось изучить что-то другое. Честно говоря — не жалею. Есть множество подобных примеров — Scss vs Less, Less vs Css, Coffee vs JS и даже «процедурное программирование» vs. ООП. Что бы понять что лучше — надо использовать и то, и другое, хотя бы в соотношении 2 (то, что новое) к 3 (то, что любимое).

          Всё это я веду к тому, что попробуйте всё же Scss чуть более чем «просто посмотреть», пусть в нём дикий синтаксис импорта примесей (безусловно в Less он лучше), но по моему личному мнению, да и думаю по мнению большинства участников, всё же Scss зачастую более элегантный и мощный в данном подспорье. Взять хотя бы Compass, на Less такого фреймворка не реализуешь.
            0
            Взять хотя бы Compass, на Less такого фреймворка не реализуешь.
            — я готов поспорить… Весомый аргумент через несколько месяцев будет в ленте хабра… В LESS круть это JavaScript.
              +1
              ну вот пример:
              @include transition(transform .3s ease);

              конвертируется в:
              -webkit-transition:-webkit-transform 0.3s ease; -moz-transition:-moz-transform 0.3s ease; -o-transition:-o-transform 0.3s ease; transition:background 0.3s ease

              в заначке у меня ещё функция преобразования градусов в «то-что-понимает-ИЕ» в его filter: progid:DXImageTransform.Microsoft.Matrix
                0
                А на счёт JS — это очень плохо. Подобный DSL, критичный для всего ресурса, стоит обрабатывать на сервере, а никак не на клиенте.
                  +1
                  LESS, как и все его аналоги, для продакшна прекомпилируется в статичный CSS. На клиенте LESS используется только в девелопменте.
                    0
                    Да я вкурсе… Знаю про Compass, а про JS на клиенте и речи не было…
                      0
                      Одна строка на html, вставляющий JS скрипт, против одной строки на PHP\Ruby\etc, делающей всё то же самое на сервере. В чём тогда «круть»? Ну разве что можно не писать rails c -s 8080 или php -S localhost:8080 дабы запустить сервер =) Тут да — несомненный плюс.

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

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