Креативные анимации загрузки на CSS » Techno-Co — Всё для вебмастера, для создание сайтов с нуля. {title}

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

Подготовка к началу:

* Здесь вы не увидите браузерные приставки во фрагментах CSS-кода, но в файлах они, конечно же, присутствуют.* Цель данного руководства заключается в том, чтобы продемонстрировать потенциал CSS, особенно CSS3 (кстати, поэтому рендер в IE9 и ниже может отличаться). Если вы планируете организовать устаревшие версии браузеров, то вам нужно будет самостоятельно позаботиться о запасных вариантах.* Лично мы используем box-model, где используется уравнение [ширина] = [ширина элемента] + [отступы] + [границы]. И применяется данная модель при помощи следующего кода:

*,
*:before,
*:after {
    box-sizing: border-box;
}

CSS: преимущества и недостатки

Какие преимущества и недостатки следует учитывать при использовании загрузчиков на чистом коде CSS? Почему бы не использовать JS-решение, или даже анимированное GIF-изображение? В ответе на этот вопрос нет никакого подвоха, — здесь все зависит от ситуации. Но позвольте раскрыть вам некоторую суть:

Преимущества

* CSS довольно просто редактировать: вы можете без труда изменить продолжительность, скорость, цвет и все, что связано с вашей анимацией.* CSS похож на «вектор»: вы можете масштабировать элементы при помощи CSS без потери качества.* CSS-анимации гораздо быстрее, нежели анимации, основанные на JS (которые даже по сути не являются анимациями), так как они используют родной движок браузера.* CSS-анимации используют аппаратное ускорение: если у вас мощное устройство, то вы сможете наблюдать очень быстрые и плавные анимации.* CSS-анимации можно без труда приостановить при помощи свойства animation-play-state.

Недостатки

* CSS-анимации не имеют полноценной браузерной поддержки: IE9 и ниже, а также Opera Mini не понимают синтаксис.

* CSS-загрузчики (или pre-загрузчики) требуют много верстки, которая не всегда стоит усилий.* CSS-анимации без javascript нельзя запустить посредством pointer-events (за исключением наведения курсора на элемент).Кроме того, рекомендуем вам сначала определить способности браузера при помощи Modernizr, а уже потом предлагать CSS-анимации тем пользователям, чьи браузеры поддерживают нужные свойства, и запасные варианты тем, чьи браузеры устарели. Двойная выгода.

Пример 1

Как всегда, начнем с чего-то простенького. Наша небольшая сфера бесконечно вращается слева направо. Движение очень важно, — оно позволяет пользователю понять, что на самом деле в приложение/на сайте в данный момент идет какая-то загрузка.

Верстка



Довольно минималистично, не правда ли? Мы даже можем сделать это посредством одного элемента, но тогда наш CSS-код окажется никудышным. Учтите, что мы можем получить и то, и другое – и опрятную верстку и привлекательный код CSS с возможностью анимировать псевдо-элементы.

CSS-код

Сначала мы создаем контейнер для сферы – панель (bar). Чтобы сохранить пропорции и сделать pre-загрузчики масштабируемыми, мы сделали единицу измерения em. Просто поменяйте значение font-size в оболочке, чтобы изменить все, что вам нужно. Довольно удобно, не правда ли?

.demo-1 .bar {
    /* Size and position */
    font-size: 20px; /* 1em */
    width: 10em;
    height: 1em;
    position: relative;
    margin: 100px auto;

    /* Styles */
    border-radius: .5em; /* Height/2 */
    background: white; /* Fallback */
    background: rgba(255,255,255,0.6);
    box-shadow:
        0 0 0 .05em rgba(100,100,100,0.075), /* Subtle border */
        0 0 0 .25em rgba(0,0,0,0.1),           /* Outter border */
        inset 0 .1em .05em rgba(0,0,0,0.1),   /* Inset shadow */
        0 .05em rgba(255,255,255,0.7);     /* Slight reflection */
}

Давайте сразу же разберемся с надписью «Please wait». Вы наверное заметили, что в разметке этого нет. Это так потому, что это генерируемый контент. На самом деле эта надпись должна быть в разметке, так как это важный контент, а не просто графическое наполнение. Но мы решили, что для демо сойдет и генерируемый вид.

.demo-1 .bar:after {
    /* Content and position */
    content: "Please wait.";
    position: absolute;
    left: 25%;
    top: 150%;

    /* Font styles */
    font-family: 'Carrois Gothic', sans-serif;
    font-size: 1em;
    color: #555;
    text-shadow: 0 .05em rgba(255,255,255,0.7);
}

На случай, если вы хотите создать настоящий элемент, просто создайте span или что-нибудь вроде этого, задайте следующие стили, и все готово! Теперь, давайте взглянем на сферу.

.demo-1 .sphere {
    /* Size */
    display: block;
    width: 1em;
    height: 100%;

    /* Styles */
    border-radius: 50%;
    background: linear-gradient(#eee, #ddd);
    box-shadow:
        inset 0 .15em .1em rgba(255,255,255,0.3), /* Top light */
        inset 0 -.1em .15em rgba(0,0,0,0.15),      /* Bottom shadow */
        0 0 .25em rgba(0,0,0,0.3);             /* Outter shadow */

    /* Animation */
    animation: move 1.75s ease-in-out infinite alternate;
}

Последнее, но не менее важное, это ключевые кадры, присутствующие в анимации:

@keyframes move {
    to { margin-left: 90%; }
}

Что может быть проще, не правда ли? Так что, элемент sphere запускает анимацию move на 1.75 секунде вместо самого начала.Примечание: вы можете с легкостью преобразовать этот pre-загрузчик в индикатор прогресса, если уберете параметр alternate в объявлении анимации, и выставите соответствующее время анимации на основе того времени, которое пользователь должен выждать.Если вы хотите динамически обновлять позицию элемента на основе прогресса загрузки, вам придется подкрепить этот код небольшим фрагментом javascript.

Пример 2

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

Верстка

Итак, этот пример полностью основан на псевдо-элементе. Полностью. И вам не потребуется дополнительная разметка.

CSS-код

Здесь все будет очень быстро, поверьте. Для начала, сам элемент. Мы использовали красный и бежевый цвета, но вы можете использовать любые цвета по желанию. То же касается и количества цветов: мы воспользовались двумя, но вы можете, к примеру, использовать 4. Или только один.

.demo-2 .spinner {
    /* Size and position */
    font-size: 100px; /* 1em */
    width: 1em;
    height: 1em;
    position: relative;
    margin: 100px auto;

    /* Styles */
    border-radius: 50%;
    background: #FF4F72; /* Fallback */
    background:
        linear-gradient(#ea2d0e 50%, #fcd883 50%), /* First column */
        linear-gradient(#fcd883 50%, #ea2d0e 50%); /* Second column */
    background-position:
        0 0,    /* Position of 1st column */
        100% 0; /* Position of 2nd column */
    background-size: 50% 100%; /* Contraction of "50% 100%, 50% 100%" */
    background-repeat: no-repeat;
    box-shadow:
        inset 0 0 0 .12em rgba(0,0,0,0.2), /* Inner border */
        0 0 0 .12em rgba(255,255,255,0.1); /* Outter border */
    opacity: 0.7;
    animation: rota 3s infinite alternate;
}

Теперь перейдем к псевдо-элементу к внутреннему прозрачному белому кругу.

.demo-2 .spinner:after {
    /* Size */
    content: "";
    width: 50%;
    height: 50%;

    /* Perfect centering */
    position: absolute;
    top: 25%;
    left: 25%;

    /* Styles */
    border: .12em solid rgba(255,255,255,0.3);
    border-radius: inherit;
}

И анимация.

@keyframes rota {
    25%  { transform: rotate(270deg); }
    50%  { transform: rotate( 90deg); }
    75%  { transform: rotate(360deg); }
    100% { transform: rotate(180deg); }
}

Пример 3

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

Верстка

HTML-код здесь будет не таким уж и привлекательным. Так как мы не можем анимировать псевдо-элементы, нам нужно будет использовать несколько элементов для того, чтобы реализовать это. Мы воспользовались списком (даже несмотря на то, что он не так уж и семантичен), но вы можете воспользоваться чем угодно.

    CSS-код

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

    .demo-3 .spinner {
        /* Size and position */
        font-size: 100px; /* 1em */
        width: 1em;
        height: 1em;
        margin: 100px auto;
        position: relative;
    
        /* Styles */
        list-style: none;
        border-radius: 50%;
        border: .01em solid rgba(150,150,150,0.1); /* Subtle white line circling the dots */
    }

    И общие свойства для всех элементов списка.

    .demo-3 .spinner li {
        width: .2em;
        height: .2em;
        position: absolute;
        border-radius: 50%;
    }

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

    .demo-3 .spinner li:nth-child(1) {
        background: #00C176; /* Blue */
        top: 0;
        left: 50%;
        margin-left: -.1em; /* Width/2 */
        transform-origin: 50% 250%;
        animation:
            rota 1.13s linear infinite,
            opa 3.67s ease-in-out infinite alternate;
    }
    
    .demo-3 .spinner li:nth-child(2) {
        background: #FF003C; /* Red */
        top: 50%;
        right: 0;
        margin-top: -.1em; /* Height/2 */
        transform-origin: -150% 50%;
        animation:
            rota 1.86s linear infinite,
            opa 4.29s ease-in-out infinite alternate;
    }
    
    .demo-3 .spinner li:nth-child(3) {
        background: #FABE28; /* Yellow */
        bottom: 0;
        left: 50%;
        margin-left: -.1em; /* Width/2 */
        transform-origin: 50% -150%;
        animation:
            rota 1.45s linear infinite,
            opa 5.12s ease-in-out infinite alternate;
    }
    
    .demo-3 .spinner li:nth-child(4) {
        background: #88C100; /* Green */
        top: 50%;
        left 0;
        margin-top -.1em; /* Height/2 */
        transform-origin: 250% 50%;
        animation:
            rota 1.72s linear infinite,
            opa 5.25s ease-in-out infinite alternate;
    }

    Наконец, две анимации. Одна для вращения, и вторая – для уровня непрозрачности. Да-да, уровень непрозрачности также изменяется!

    @keyframes rota {
        to { transform: rotate(360deg); }
    }
    
    @keyframes opa {
        12.0% { opacity: 0.80; }
        19.5% { opacity: 0.88; }
        37.2% { opacity: 0.64; }
        40.5% { opacity: 0.52; }
        52.7% { opacity: 0.69; }
        60.2% { opacity: 0.60; }
        66.6% { opacity: 0.52; }
        70.0% { opacity: 0.63; }
        79.9% { opacity: 0.60; }
        84.2% { opacity: 0.75; }
        91.0% { opacity: 0.87; }
    }

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

    Что не так с вами и числами?

    Как мы уже говорили, мы попробовали сделать так, чтобы все появлялось в случайном порядке, насколько это возможно. Мы могли бы создать небольшой JS-скрипт, который бы выдавал случайные числа, и вставлять их потом в CSS, но эта идея нам не понравилась.Лучшее, что здесь можно сделать, это сгенерировать случайные числа в голове таким образом, чтобы они лишь выглядели как случайные. Именно поэтому вы можете видеть, что продолжительность анимации составляет 1.72s, 4.29s или 1.13s. То же самое происходит и с ключевыми кадрами значений opa и opacity. Странные интервалы, странные значения, — все довольно «псевдо случайное».

    Что насчет transform-origin?

    Мы использовали возможность предложить вам небольшой трюк для поиска подходящего значения transform-origin, когда вам нужно будет, чтобы вращение происходило не вокруг центра вращения по умолчанию.Основная проблема, с которой мы столкнулись при работе с transform-origin, заключается в недостаточном понимании значения. Мы не совсем поняли (а иногда и совсем не поняли) способ, по которому происходят вычисления.В любом случае, идея заключается в том, чтобы отобразить transform-origin на псевдо-элемент. Взгляните:

    .my-element {
        transform-origin: 12% 34%;
    }
    
    .my-element:after {
        content: "";
        width: 4px;
        height: 4px;
        position: absolute;
        left: 12%; /* First value of transform-origin */
        top: 34%; /* Second value of transform-origin */
        margin: -2px 0 0 -2px;
        border-radius: 50%;
        background: red;
    }

    Пример 4

    Давайте перейдем к более простому демо, немного напоминающему стим-панк: колеса, шестеренки и прочее. Нам понравился этот пример. Итак, приступим.

    Верстка

    Здесь верстка получилась довольно громоздкой, так как нам нужно обернуть каждый символ в span. И нам потребуется оболочка, которая предотвращала бы вращение основного элемента. Об этом мы поговорим чуть позже.

    
    
            L
            o
            a
            d
            i
            n
            g
    
    

    CSS-код

    Сначала нам нужно применить несколько вещей к основному элементу: size, position, font-styles, animation и так далее.

    .demo-4 .wrapper {
        /* Size and position */
        font-size: 25px; /* 1em */
        width: 8em;
        height: 8em;
        margin: 100px auto;
        position: relative;
    
        /* Styles */
        border-radius: 50%;
        background: rgba(255,255,255,0.1);
        border: 1em dashed rgba(138,189,195,0.5);
        box-shadow:
            inset 0 0 2em rgba(255,255,255,0.3),
            0 0 0 0.7em rgba(255,255,255,0.3);
        animation: rota 3.5s linear infinite;
    
        /* Font styles */
        font-family: 'Racing Sans One', sans-serif;
    
        color: #444;
        text-align: center;
        text-transform: uppercase;
        text-shadow: 0 .04em rgba(255,255,255,0.9);
        line-height: 6em;
    }

    Ух, довольно громоздко, не правда ли? И нам все еще нужно создать внутренние колеса при помощи псевдо-элементов.

    .demo-4 .wrapper:before,
    .demo-4 .wrapper:after {
        content: "";
        position: absolute;
        z-index: -1;
        border-radius: inherit;
        box-shadow: inset 0 0 2em rgba(255,255,255,0.3);
        border: 1em dashed;
    }
    
    .demo-4 .wrapper:before {
        border-color: rgba(138,189,195,0.2);
        top: 0; right: 0; bottom: 0; left: 0;
    }
    
    .demo-4 .wrapper:after {
        border-color: rgba(138,189,195,0.4);
        top: 1em; right: 1em; bottom: 1em; left: 1em;
    }

    Теперь, что касается внутренней оболочки и span-элементов. Учтите, что мы можем использовать обратный параметр во внутреннем контейнере для того, чтобы предотвратить вращение основного элемента. .demo-4 .wrapper .inner { width: 100%; height: 100%; animation: rota 3.5s linear reverse infinite;} .demo-4 .wrapper span { display: inline-block; animation: placeholder 1.5s ease-out infinite;} .demo-4 .wrapper span:nth-child(1) { animation-name: loading-1; }.demo-4 .wrapper span:nth-child(2) { animation-name: loading-2; }.demo-4 .wrapper span:nth-child(3) { animation-name: loading-3; }.demo-4 .wrapper span:nth-child(4) { animation-name: loading-4; }.demo-4 .wrapper span:nth-child(5) { animation-name: loading-5; }.demo-4 .wrapper span:nth-child(6) { animation-name: loading-6; }

    .demo-4 .wrapper span:nth-child(7) { animation-name: loading-7; }

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

    @keyframes rota {
        to { transform: rotate(360deg); }
    }
    
    @keyframes loading-1 {
        14.28% { opacity: 0.3; }
    }
    
    @keyframes loading-2 {
        28.57% { opacity: 0.3; }
    }
    
    @keyframes loading-3 {
        42.86% { opacity: 0.3; }
    }
    
    @keyframes loading-4 {
        57.14% { opacity: 0.3; }
    }
    
    @keyframes loading-5 {
        71.43% { opacity: 0.3; }
    }
    
    @keyframes loading-6 {
        85.71% { opacity: 0.3; }
    }
    
    @keyframes loading-7 {
        100% { opacity: 0.3; }
    }

    Такие анимации бывает довольно сложно понять, поэтому позвольте пояснить вам. К каждой букве нужно применить:* Уменьшение уровня непрозрачности* Возврат к полному отображению* Подождать, пока каждая буква претерпит те же самые изменения* Вернуться к 1 шагу и повторить процесс

    Как же это сделать?

    * Вы подсчитываете количество букв в вашем элементе. В нашем демо используется 7 букв.* Разделяете 100 (число ключевых кадров, выраженное в %) на это число. В данном случае, мы получили ~14.28.* Каждые 14.28 ключевых кадров буква начинает действовать.* Готово.

    Пример 5

    Давайте закончим чем-нибудь более концептуальным. Мы знаем, что людям обычно не нравится перебор с анимацией, но здесь все зависит от требований к вашему сайту/приложению.

    Верстка

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

    CSS-код

    На самом деле, наш элемент – это лишь одна из наших маленьких сфер (та, которая сверху). Остальные 7 сделаны при помощи box-shadow.

    .demo-5 .pre-loader {
        /* Size and position */
        font-size: 30px; /* 1em */
        width: 1em;
        height: 1em;
        position: relative;
        margin: 100px auto;
    
        /* Styles */
        border-radius: 50%;
        background: #123456;
        transform-origin: 50% 250%;
        animation:
            blink 1s steps(1, start) infinite, /* Blink */
            counter-clock 8s linear infinite;  /* Rotation */
    
        /* Dots, clockwise */
        box-shadow:
           1em 1em #123456,
           2em 2em #123456,
           1em 3em #123456,
           0em 4em #123456,
          -1em 3em #123456,
          -2em 2em #123456,
          -1em 1em #123456;
    }

    Эффект прозрачного квадрата реализован при помощи… эм, прозрачного квадрата. Это перевернутый псевдо-элемент, помещенный поверх всего остального. Довольно просто.

    .demo-5 .pre-loader:after {
        /* Size and position */
        content: "";
        width: 3em;
        height: 3em;
        position: absolute;
        left: -1em;
        top: 1em;
    
        /* Styles */
        transform: rotate(45deg);
        background: white; /* Fallback */
        background: rgba(255,255,255,0.6);
    
    }

    А теперь перейдем к анимациям. Позвольте немного разъяснить вам по поводу второго (‘blink’):* У нас есть 8 точек, поэтому мы делим 100 ключевых кадров на 8, и получаем 12.5.* Каждые 12.5 кадров точка теряет немного плотности. rgb(18,52,86) – это RGB-код для цвета #123456.* В первом ключевом кадре (12.5%) сам элемент теряет плотность.

    @keyframes counter-clock {
        to { transform: rotate(-360deg); }
    }
    
    @keyframes blink {
        12.5% {
        background: rgba(18,52,86,0.6);
        box-shadow:
           1em 1em #123456,
           2em 2em #123456,
           1em 3em #123456,
           0em 4em #123456,
          -1em 3em #123456,
          -2em 2em #123456,
          -1em 1em #123456;
        }
    
        25% {
        background: #123456;
        box-shadow:
           1em 1em rgba(18,52,86,0.6),
           2em 2em #123456,
           1em 3em #123456,
           0em 4em #123456,
          -1em 3em #123456,
          -2em 2em #123456,
          -1em 1em #123456;
        }
    
        37.5% {
        background: #123456;
        box-shadow:
           1em 1em #123456,
           2em 2em rgba(18,52,86,0.6),
           1em 3em #123456,
           0em 4em #123456,
          -1em 3em #123456,
          -2em 2em #123456,
          -1em 1em #123456;
        }
    
        50% {
        background: #123456;
        box-shadow:
          1em 1em #123456,
          2em 2em #123456,
          1em 3em rgba(18,52,86,0.6),
          0em 4em #123456,
          -1em 3em #123456,
          -2em 2em #123456,
          -1em 1em #123456;
        }
    
        62.5% {
        background: #123456;
        box-shadow:
           1em 1em #123456,
           2em 2em #123456,
           1em 3em #123456,
           0em 4em rgba(18,52,86,0.6),
          -1em 3em #123456,
          -2em 2em #123456,
          -1em 1em #123456;
        }
    
        75% {
        background: #123456;
          box-shadow:
           1em 1em #123456,
           2em 2em #123456,
           1em 3em #123456,
           0em 4em #123456,
          -1em 3em rgba(18,52,86,0.6),
          -2em 2em #123456,
          -1em 1em #123456;
        }
    
        87.5% {
        background: #123456;
        box-shadow:
           1em 1em #123456,
           2em 2em #123456,
           1em 3em #123456,
           0em 4em #123456,
          -1em 3em #123456,
          -2em 2em rgba(18,52,86,0.6),
          -1em 1em #123456;
        }
    
        100% {
        background: #123456;
        box-shadow:
           1em 1em #123456,
           2em 2em #123456,
           1em 3em #123456,
           0em 4em #123456,
          -1em 3em #123456,
          -2em 2em #123456,
          -1em 1em rgba(18,52,86,0.6);
        }
    }

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

    Упрощаем процесс при помощи сторонних инструментов

    Как вы уже возможно видели в других демо, иногда нам нужно повторять некоторые фрагменты кода с разными значениями, и иногда это может показаться очень нудным занятием.К счастью, мы можем в значительной степени облегчить процесс соответствующими инструментами. Нам кажется, вы уже догадались, что сейчас речь идет о CSS-препроцессорах. На самом деле, это так, но здесь пригодны не только препроцессоры.Так как 4-е демо было самым «повторяющимся», давайте попробуем упростить реализацию этого примера. Автоматизируем процесс изменения числа букв в элементе.

    Lettering.js

    Lettering.js делает довольно простую вещь: оборачивает каждую букву в таргетированный элемент тегом span.

    Так что, теперь нам не придется вручную оборачивать наши буквы span-элементами, потому что за нас это сделает Lettering.js. Довольно просто? Но мы хотим уделить больше внимания CSS.

    CSS-препроцессоры

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

    Понимаете, Sass здесь делает все правильно: поддерживает цикл for. Тем не менее, LESS не поддерживает циклы. Вместо этого, вам нужно будет создать рекурсивную функцию, которая понижает переменную. Это не очень приятное решение, но оно работает.

    /* SCSS */
    
    for $i from 1 through 10 {
        /* Do stuff */
    }
    
    /* LESS */
    
    .loop(@index) when (@index > 0) {
        /* Do stuff */
        .loop(@index - 1);
    }
    
    .loop(0) { }
    .loop(10);

    Видите? В какой вселенной рекурсивная функция может быть проще, чем цикл? В любом случае, давайте попробуем воспроизвести 4-е демо при помощи «циклов».

    /* SCSS */
    
    $iterations : 7; //Number of letters
    
    @for $i from 1 through $iterations {
        $val : 100%/$iterations*$i;
    
        @keyframes loading-#{$i} {
            #{$val} {
                opacity: 0.3;
            }
        }
    
        .wrapper span:nth-child(#{$i}) {
            animation-name: loading-#{$i};
        }
    }
    
    /* LESS */
    
    @iterations: 7; //Number of letters
    @newline: `"n"`; //Fix hack
    
    .loop (@index) when (@index > 0) {
        @val: 100/@iterations*@index;
    
        (~"@keyframes loading-@{index} {@{newline}@{val}%") {
            opacity: 0.3;
        }
    
        (~"} .wrapper span:nth-child(@{index}) @{newline}") {
            animation-name: "loading-@{index}";
        }
    
        .loop(@index - 1);
    }
    
    .loop (0) {}
    .loop (@iterations);

    Результат будет абсолютно таким же, который вы видели в 4-м примере. Конечно же, если у вас будет всего 7 букв как здесь, то возможно это не стоит того, но если предстоит работа с 40-50 символами, то можно реально сэкономить время.

    Примечание: добавлять приставки в SCSS-версию довольно просто: скопируйте строку animation-line, и блок @keyframes и добавьте приставки. Тем не менее, этот процесс может вызывать сложности при работе с LESS, но мы попытаемся сэкономить ваше время, показав вам конечный результат.

    Если вы хотите понять, как работает связь в LESS, а также то, как можно работать с такими вещами как например @media или @keyframes в миксине, пожалуйста, обратитесь за помощью к следующим статьям на Stack Overflow:

    * Chaining keyframes attributes with LESS (Связываем атрибуты ключевых кадров при помощи LESS)

    * LESS Pass mixin as a parameter to another mixin (Миксин LESS Pass в качестве параметра другого миксина)
    * @ sign and variables in keyframes using LESS (Знак @ и переменные в ключевых кадрах при помощи LESS)

    В завершение

    И на этом мы завершаем наше руководство! Спасибо за чтение, и пожалуйста, не забудьте поделиться материалом со своими друзьями!

    Исходники в архиве.