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.
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.
The transition CSS property is a shorthand property for transition-property , transition-duration , transition-timing-function , and transition-delay .
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.
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.
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/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With