Есть ли способ сгруппировать специфичные для браузера анимации css3?

Я хочу сделать CSS3-анимацию, в которой div получает тень от мыши и теряет ее при выводе мыши. Это то, что я до сих пор:

HTML:

<div id="page">
    <div id="container" onmouseover="mouseOverContainer()" onmouseout="mouseOutContainer()" class="">

    </div>
</div>

JS:

var container = undefined;
function assignContainer() {
    if(container===undefined) {
        container = document.getElementById("container");
    }
}
function mouseOverContainer() {
    assignContainer();
    container.className="container-in";
}
function mouseOutContainer() {
    assignContainer();
    container.className="container-out";
}

CSS:

@keyframes box-shadow-anim-in{
    from {
        box-shadow: 0 0 0 rgba(0,0,0,0.0);
        background-color: #ccc;
        margin-top: 20px;
        margin-top: 20px;
    }
    to {
        box-shadow: 0 0 250px rgba(127,127,127,1.0);
        background-color: #efefef;
        margin-top: 18px;
        margin-top: 18px;
    }
}
@-o-keyframes box-shadow-anim-in{
    from {
        -o-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        background-color: #ccc;
        margin-top: 20px;
    }
    to {
        -o-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        background-color: #efefef;
        margin-top: 18px;
    }
} 
@-webkit-keyframes box-shadow-anim-in{
    from {
        -webkit-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        background-color: #ccc;
        margin-top: 20px;
    }
    to {
        -webkit-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        background-color: #efefef;
        margin-top: 18px;
    }
} 
@-ms-keyframes box-shadow-anim-in{
    from {
        -ms-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        background-color: #ccc;
        margin-top: 20px;
    }
    to {
        -ms-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        background-color: #efefef;
        margin-top: 18px;
    }
} 
@-moz-keyframes box-shadow-anim-in  {
    from {
        -moz-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        background-color: #ccc;
        margin-top: 20px;
    }
    to {
        -moz-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        background-color: #efefef;
        margin-top: 18px;
    }
}

@keyframes box-shadow-anim-out{
    from {
        box-shadow: 0 0 250px rgba(127,127,127,1.0);
        background-color: #efefef;
        margin-top: 18px;
    }
    to {
        box-shadow: 0 0 0 rgba(0,0,0,0.0);
        background-color: #ccc;
        margin-top: 20px;
    }
}
@-moz-keyframes box-shadow-anim-out{
    from {
        -moz-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        background-color: #efefef;
        margin-top: 18px;
    }
    to {
        -moz-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        background-color: #ccc;
        margin-top: 20px;
    }
} 
@-o-keyframes box-shadow-anim-out{
    from {
        -o-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        background-color: #efefef;
        margin-top: 18px;
    }
    to {
        -o-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        background-color: #ccc;
        margin-top: 20px;
    }
}
@-webkit-keyframes box-shadow-anim-out {
    from {
        -webkit-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        background-color: #efefef;
        margin-top: 18px;
    }
    to {
        -webkit-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        background-color: #ccc;
        margin-top: 20px;
    }
}
@-ms-keyframes box-shadow-anim-out{
    from {
        -ms-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        background-color: #efefef;
        margin-top: 18px;
    }
    to {
        -ms-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        background-color: #ccc;
        margin-top: 20px;
    }
} 

#page {
    width: 900px;
    margin: 0 auto;
}

#container {
    width: 60%;
    height: 250px;
    background-color: #ccc;
    margin-top: 20px;
    border: 1px solid #999;
}
.container-out {
    animation: box-shadow-anim-out 0.3s;
    -moz-animation: box-shadow-anim-out 0.3s;
    -webkit-animation: box-shadow-anim-out 0.3s;
    -o-animation: box-shadow-anim-out 0.3s;
    -ms-animation: box-shadow-anim-out 0.3s;

    animation-fill-mode: forwards;
    -moz-animation-fill-mode: forwards;
    -o-animation-fill-mode: forwards;
    -ms-animation-fill-mode: forwards;
    -webkit-animation-fill-mode: forwards;
}

.container-in {
    animation: box-shadow-anim-in 0.3s;
    -moz-animation: box-shadow-anim-in 0.3s;
    -webkit-animation: box-shadow-anim-in 0.3s;
    -o-animation: box-shadow-anim-in 0.3s;
    -ms-animation: box-shadow-anim-in 0.3s;

    animation-fill-mode: forwards;
    -moz-animation-fill-mode: forwards;
    -o-animation-fill-mode: forwards;
    -ms-animation-fill-mode: forwards;
    -webkit-animation-fill-mode: forwards;
}

Все работает нормально, как вы можете видеть в этом JSFiddle.

Но, как вы можете видеть, мы должны определить браузер keyframes чтобы он работал во всех браузерах.

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

Я думал, что мог бы использовать только один блок, вставляя все ключевые кадры, разделенные запятой, например так:

@keyframes box-shadow-anim-in,
@-o-keyframes box-shadow-anim-in,
@-webkit-keyframes box-shadow-anim-in,
@-ms-keyframes box-shadow-anim-in,
@-moz-keyframes box-shadow-anim-in  {
    from {
        box-shadow: 0 0 0 rgba(0,0,0,0.0);
        -o-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        -webkit-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        -ms-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        -moz-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        background-color: #ccc;
        margin-top: 20px;
    }
    to {
        box-shadow: 0 0 250px rgba(127,127,127,1.0);
        -o-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        -webkit-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        -ms-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        -moz-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        background-color: #efefef;
        margin-top: 18px;
    }
}

@keyframes box-shadow-anim-out,
@-o-keyframes box-shadow-anim-out,
@-webkit-keyframes box-shadow-anim-out,
@-ms-keyframes box-shadow-anim-out,
@-moz-keyframes box-shadow-anim-out {
    from {
        box-shadow: 0 0 250px rgba(127,127,127,1.0);
        -o-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        -webkit-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        -ms-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        -moz-box-shadow: 0 0 250px rgba(127,127,127,1.0);
        background-color: #efefef;
        margin-top: 18px;
    }
    to {
        box-shadow: 0 0 0 rgba(0,0,0,0.0);
        -o-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        -webkit-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        -ms-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        -moz-box-shadow: 0 0 0 rgba(0,0,0,0.0);
        background-color: #ccc;
        margin-top: 20px;
    }
}

Но это, похоже, не работает ( JSFiddle здесь), так что, возможно, я делаю что-то не так или просто не могу сделать это так.

Можно ли сделать что-то подобное? Если да, то как?

2 ответа

Решение

Нет, это невозможно с CSS. Вы не можете сгруппировать разные at-правила вместе, так же, как вы не можете сгруппировать селекторы с префиксом поставщика.

Вы можете прибегнуть к использованию миксина Sass/LESS, но это при условии, что вы уже работаете с препроцессором, и это все равно выводит отдельные повторяющиеся правила CSS.

Для чего бы это ни стоило, есть несколько префиксов, которые можно удалить, чтобы уменьшить часть раздувания в вашем CSS:

  • @-ms-keyframes а также -ms-animation не используются ни одной стабильной версией IE; IE10 поддерживает их без префиксов прямо из коробки

  • Firefox также поддерживает без префикса @keyframes/animationначиная с версии 16

  • -ms-box-shadow а также -o-box-shadow никогда не существовало, поэтому они должны быть удалены / без префикса

  • -moz-box-shadow требуется только в Firefox 3.5 и 3.6, ни одна из которых не поддерживает анимацию CSS (даже через @-moz-keyframes - это было добавлено в версии 5), поэтому оно должно быть без префикса

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

Это невозможно без препроцессора, такого как SASS или LESS.

Но есть и другой вариант использования JS. Посмотрите здесь: http://leaverou.github.io/prefixfree/

Я бы лично предложил вам переключиться на препроцессор CSS, так как это, несомненно, пригодится в будущем.

Другие вопросы по тегам