简体   繁体   中英

Most concise way to write a CSS transition

Is there a more concise way to write the following code?

element{
    transition: all 700ms linear,
        transform 700ms cubic-bezier(0.4, 0.25, 0.14, 1.5),
        background 700ms cubic-bezier(0.4, 0.25, 0.14, 1.5);
}

What I'm trying to do is to apply a diferent transition timing function to transform and background properties, while using a linear one for the rest of the properties. This is working right, but I'm trying to keep it as DRY as possible.

There's not much you can do here. You could specify the transition duration separately:

element{
    transition: all linear,
        transform cubic-bezier(0.4, 0.25, 0.14, 1.5),
        background cubic-bezier(0.4, 0.25, 0.14, 1.5);
    transition-duration: 700ms;
}

But that's about it. You can't specify your custom curve only once due to the way comma-separated transition values work. The entire list of values is repeated in the order they were specified, rather than having the last value be repeated infinitely.

That is to say, if you do this:

element{
    transition-property: all, transform, background;
    transition-duration: 700ms;
    transition-timing-function: linear, cubic-bezier(0.4, 0.25, 0.14, 1.5);
}

What happens is that the missing value for transition-timing-function is filled as linear , not your custom curve. The result will not match your intended transition for background .

And if you try to take advantage of that by changing the order of transition properties like so, such that the missing value for background takes on your custom curve instead:

element{
    transition-property: transform, all, background;
    transition-duration: 700ms;
    transition-timing-function: cubic-bezier(0.4, 0.25, 0.14, 1.5), linear;
}

What happens is that the all transition will override the transform transition, even though you specified it separately, because the all comes later and it includes any previously-listed properties.

Well, the most DRY way would be to use something like SASS and write a mixin, then use that instead of copy pasting that code everywhere. Another suggestion I'll make is to avoid using all , and instead enumerate the properties you'd like animated via the linear transition. While this might be more verbose, I'm willing to bet it'll be way more performant, especially if you ever put graphically demanding things like box-shadow into the element's style.

So, while your way would work, I feel like the more unique transitions you have, the more valuable this formulation becomes:

element {
    transition-duration: 2s;
    transition-property: all, background, transform;
    transition-timing-function: linear, cubic-bezier(0.4, 0.25, 0.14, 1.5), cubic-bezier(0.4, 0.25, 0.14, 1.5);
}

Of course, I recommended enumerating properties, to avoid costly and unsolicited animations. In that case, something like this makes more sense:

element {
    transition-duration: 2s;
    transition-property: height, background, transform, width;
    transition-timing-function: linear, cubic-bezier(0.4, 0.25, 0.14, 1.5), cubic-bezier(0.4, 0.25, 0.14,1.5), linear;
}

Edit: as mentioned by @BoltClock, I was wrong about everything below this bold text, so please disregard it. The comma separated arguments are applied again the order they were originally specified - neither the first nor the last repeats for additional transition-property values. I do still think what I said about not using all is important advice for performance and future proofed scoping though!

Take note of how I ordered the arguments: if there are more arguments for transition-property than transition-timing-function , the all of the extra properties will default to the first value listed for transition-property as their default. So, put a linear (default) value first, then enumerate all your unique timing functions to match the correct property, and then any properties you amend to the end (like width ) will automatically default to linear ! So, even if you add 5 more properties to the end of your property list, only background and transform will have their unique cubic-bezier timing functions. For example:

element {
    transition-duration: 2s;
    transition-property: height, background, transform, width, oneProp, twoProp, threeProp, etcProp;
    transition-timing-function: linear, cubic-bezier(0.4, 0.25, 0.14, 1.5), cubic-bezier(0.4, 0.25, 0.14,1.5);
}

Everything in the above uses the linear timing function except background and transform . I feel like this is a good compromise between performance and DRY CSS. I made a jsFiddle for you to check out the various options - comment out the different CSS to try each way:

http://jsfiddle.net/530cumas/4/

To the best of my CSS knowledge (after a quick google), your current method is the shortest (and, therefore, the most "DRY") way to do what you want. Granted, I'm not a CSS guru, so I could be totally wrong.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM