Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 589
Nazareno Lorenzo Avatar asked Dec 18 '14 05:12

Nazareno Lorenzo


People also ask

How do you make a smooth transition in CSS?

With CSS3 we can specify how an element changes by just describing its current and target states. CSS3 will create a smooth transition between these states by applying a cubic Bézier curve and gradually change the element appearance.

Which of the following is shorthand method to use transition?

The transition CSS property is a shorthand property for transition-property , transition-duration , transition-timing-function , and transition-delay .

How do you make different transitions in CSS?

Transitioning two or more properties You can transition two (or more) CSS properties by separating them with a comma in your transition or transition-property property. You can do the same with duration, timing-functions and delays as well. If the values are the same, you only need to specify one of them.

What is ease in transition CSS?

ease - specifies a transition effect with a slow start, then fast, then end slowly (this is default) linear - specifies a transition effect with the same speed from start to end.


2 Answers

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.

like image 180
BoltClock Avatar answered Nov 15 '22 10:11

BoltClock


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/

like image 24
AlexZ Avatar answered Nov 15 '22 09:11

AlexZ