This question already has answers here:
How to have multiple CSS transitions on an element?
(9 answers)
CSS transition shorthand with multiple properties?
(7 answers)
Closed 4 years ago.
I was having some issues doing colour-based transitions...
I was working with the following CSS:
.embtn {
position:absolute;
top:0vh ;
left: 0vw;
border-radius: 5vw;
padding: 0.2vw;
color: red;
width: calc(2vw + 1vh);
height: calc(2vw + 1vh);
background-color: white;
-webkit-transition: background-color 2s ;
-webkit-transition: width 0.5s ease-out;
-o-transition: background-color 2s ;
-o-transition: width 0.5s ease-out;
-moz-transition: background-color 2s ;
-moz-transition: width 0.5s ease-out;
transition-delay: 2s;
transition: background-color 2s ;
transition-delay: 2s;
transition: width 0.5s ease-out;
transition-delay: 2s;
}
.embtn:hover {
-webkit-transition: background-color 2s ;
-webkit-transition: width 0.5s ease-out;
-o-transition: background-color 2s ;
-o-transition: width 0.5s ease-out;
-moz-transition: background-color 2s ;
-moz-transition: width 0.5s ease-out;
transition: background-color 2s ;
transition: width 0.5s ease-out;
background-color: black;
width: 30vw;
}
on the following code:
<div class='embtn'><div id="searchproduct" style="font-size:calc(1vw + 1vh);cursor:pointer; display: inline;" onClick="searchProducts()">🔍</div>
<input id="search" style=" color: white; position:absolute; top: calc(((2vw + 1vh)/2)-(1vw + 1vh); ); ; left: 3vw; display: inline; border-style: none; outline: none; background: transparent; width: 25vw; font-size: calc(1vw + 1vh); " type="text" placeholder=" Search..." name="search" required>
</div>
And was hoping to see the delayed transitions... The width transition worked fine with the intended delay but the colour transition wasn't delaying... i.e. It not only occured instantaneously but it did not wait the 2s before happening...
Any suggestions?
The problem is that you are overwriting one CSS property with another immediately after:
transition: background-color 2s;
transition: width 0.5s ease-out;
If you do this you will not see any transition effect for background-color, because you have overwritten it immediately afterwards to only apply to width.
The correct way to transition multiple CSS properties would be by comma separating each transition like so:
transition: background-color 2s ease-out 0.5s, width 2s ease-out 0.5s;
The shorthand syntax for setting one or more transition properties at once is as follows:
transition: <property> || <duration> || <timing-function> || <delay> [, ...];
Have a look at this Multiple animated properties example
And finally, here is your example simplified with a transition on both background-color and width properties.
.embtn {
border-radius: 5vw;
width: calc(2vw + 1vh);
height: calc(2vw + 1vh);
background-color: white;
transition: background-color 2s ease-out 0.5s, width 2s ease-out 0.5s;
}
.embtn:hover {
background-color: black;
width: 30vw;
}
<div class='embtn'>
<div id="searchproduct">🔍</div>
<input id="search" type="text" placeholder=" Search..." name="search" required>
</div>
First of all, If you need the same hover effect on mouseenter and mouseleave, just set properties on the element without a :hover selector
Secondly, you override background-color transition by setting width transition below. If you have to specify multiple properties (not using all property which is default), list them as comma-separated
.embtn {
...
transition: width 0.5s ease-out 2s, background 2s ease 2s;
}
.embtn:hover {
....
}
The syntax for a single property would be
transition: property duration timing-function delay|initial|inherit;
https://www.w3schools.com/cssref/css3_pr_transition.asp
To set transitions on more than one property, the correct syntax is to separate each property with commas, in the same transition shorthand declaration, like this:
{
...
transition: background-color 2s ease 2s, width .5s ease-out;
/* property ^ ^ ^ ^ ^ ^ ^ ^
duration ^ ^ ^ ^ ^ ^ ^
timing-function ^ ^ ^ ^ ^ ^
delay ^ ^ ^ ^ ^
property ^ ^ ^ ^
duration ^ ^ ^
timing-function ^ ^
implicit delay (0s) ^ */
}
This code you have, does the following:
{
...
transition: background-color 2s;
transition-delay: 2s;
transition: width 0.5s ease-out;
...
}
Does this:
Sets transition-property to background-color, transition-duration to 2s, transition-timing-function to ease (default), transition-delay to 0s
Overrides transition-delay to 2s
Sets transition-property to width, transition-duration to 0.5s, transition-timing-function to ease-out and transition-delay to 0s, which effectively overrides both 1. and 2.
For more in-depth info on how to use transition shorthand I recommend MDN or W3C spec.
How can I make transition delay from one css attribute to another on the same element , the example I want to make it to make transition for width first then for height of div element
<div class="rect"id="box2"></div>
and here's the CSS
.rect{
margin-top:50px;
width:10px;
height:80px;
background-color:black;
}
#box2{
transition:all 1s ease-in-out ;
-webkit-transition:all 1s ease-in-out ;
-moz-transition:all 1s ease-in-out ;
}
#box2:hover{
width:300px;
height:200px;
}
this code makes the height and width works together, and transition-delay in the #box2 makes delay for the whole transition! what should I do?
here's the sample http://jsfiddle.net/bBnQW/
#box2{
transition:width 1s ease-in-out, height 1s ease-in-out 1s ;
-webkit-transition:width 1s ease-in-out, height 1s ease-in-out 1s ;
-moz-transition:width 1s ease-in-out, height 1s ease-in-out 1s ;
}
if this is what you want...
As far as I know, you don't. You have the CSS3 transition-delay property, which I think you already have tried. My advice, in case you don't find a solution for this, is to use a jQuery solution to achieve that effect. You can do it with just a couple of lines of code (maybe even less than what you have in CSS).
I'm introducing LESS to a large web app project to simplify my CSS. I've got a few CSS rules which apply transitions to a varying number of properties, for example:
.movable {
transition-property: top, left;
transition-duration: 0.2s;
transition-timing-function: ease;
}
.fadeAndStretchable {
transition-property: opacity, width, height, margin;
transition-duration: 1.5s;
transition-timing-function: ease-out;
}
(Note: I've omitted -webkit, -moz and -o properties here for brevity: in reality each of these rules is 12 lines long rather than 3.)
Note that the values for transition-property are comma-separated. This is unusual in CSS: multiple values are usually space-separated (as in border: 1px solid #f00). LESS mixins can use the special #arguments value to produce a space-separated list of all the mixin arguments - but is it possible to define a LESS mixin that takes a variable number of parameters and turns them into a comma-separated value list, suitable for transition-property?
If necessary, I'm happy with a solution that requires two mixins: one for transition-property and another for transition-duration and transition-timing-function. Here's what I've tried so far:
Attempt 1: using #arguments with unnamed parameters
.transition-property() {
-webkit-transition-property: #arguments;
-moz-transition-property: #arguments;
-o-transition-property: #arguments;
transition-property: #arguments;
}
.movable {
.transition-property(top, left);
}
Result: LESS error ("No matching definition was found for '.transition-property(top, left)'")
Attempt 2: using #arguments with named parameters
.transition-property(#p1, #p2, #p3, #p4, #p5) {
-webkit-transition-property: #arguments;
-moz-transition-property: #arguments;
-o-transition-property: #arguments;
transition-property: #arguments;
}
.movable {
.transition-property(top, left);
}
Result: LESS error ("No matching definition was found for '.transition-property(top, left)'")
Attempt 3: using named parameters with dummy default values
.transition-property(#p1:p1, #p2:p2, #p3:p3, #p4:p4, #p5:p5) {
-webkit-transition-property: #p1, #p2, #p3, #p4, #p5;
-moz-transition-property: #p1, #p2, #p3, #p4, #p5;
-o-transition-property: #p1, #p2, #p3, #p4, #p5;
transition-property: #p1, #p2, #p3, #p4, #p5;
}
.movable {
.transition-property(top, left);
}
Result: No LESS error but it generates a CSS rule -webkit-transition-property: top, left, p3, p4, p5 that the browser ignores because of the unrecognised properties.
I've tried various other approaches (e.g. passing the property as a string 'top,left') but all result in the same thing: either a LESS error or invalid CSS.
Is there any way round this? Or do I have to bite the bullet and define a set of mixins overloaded on arity, e.g.
.transition-property(#p1) {...}
.transition-property(#p1, #p2) {...}
.transition-property(#p1, #p2, #p3) {...}
.transition-property(#p1, #p2, #p3, #p4) {...}
etc.
I've managed to figure it out thanks to Luke Page pointing me towards the ... syntax.
The solution was to use the following:
... to allow variable parameters
Backticks for JavaScript evaluation
Variable string interpolation
A ~ prefix to escape the resulting expression (i.e. stop LESS from enclosing it in a string)
Good old regular expressions
Phew. Here's the resulting mixin:
.transition-properties(...) {
-webkit-transition-property: ~`"#{arguments}".replace(/[\[\]]/g, '')`;
}
And here's the full version with a complete set of browser extensions:
.transition-properties(...) {
#props: ~`"#{arguments}".replace(/[\[\]]/g, '')`;
-webkit-transition-property: #props;
-moz-transition-property: #props;
-o-transition-property: #props;
transition-property: #props;
}
Perhaps I am misunderstanding your needs. Why can you not use an escaped string?
Like so:
.transition ( #property, #duration, #style: ease-in-out ) {
-webkit-transition-property: #property;
-webkit-transition-duration: #duration;
-webkit-transition-timing-function: #style;
-moz-transition-property: #property;
-moz-transition-duration: #duration;
-moz-transition-timing-function: #style;
-ms-transition-property: #property;
-ms-transition-duration: #duration;
-ms-transition-timing-function: #style;
-o-transition-property: #property;
-o-transition-duration: #duration;
-o-transition-timing-function: #style;
transition-property: #property;
transition-duration: #duration;
transition-timing-function: #style;
}
#my-id {
.transition( ~"background, border-color, color", 2s );
}
This is exactly what we use for multi-property transitions. Never had a problem with it.
Flexible (LESS 1.5.1+)
This solution does not use any inline javascript and it allows for:
Defaults to be set
Any number of properties, durations, delays, etc., to be passed
Output either in long form or compact form
A raw list input instead of groups of parameters being input if desired
If the number of properties are greater than the number of durations, delays, or timings, then if the compact output is set, the final value for duration/delay/timing becomes the value for that parameter for all additional properties beyond the number passed, but if compact is not set, then the long form is output and values are duplicated per browsers interpret ion of the css standards.
LESS Mixin
.transition (#props: all;
#duration:1s;
#delay: 0s;
#timing: ease;
#compact: true;
#raw-input: false) {
.output() when (#raw-input = false) and not (#compact = true) {
-webkit-transition-property:#props;
-moz-transition-property:#props;
-ms-transition-property:#props;
-o-transition-property:#props;
transition-property:#props;
-webkit-transition-duration:#duration;
-moz-transition-duration:#duration;
-ms-transition-duration:#duration;
-o-transition-duration:#duration;
transition-duration:#duration;
-webkit-transition-delay: #delay;
-moz-transition-delay: #delay;
-ms-transition-delay: #delay;
-o-transition-delay: #delay;
transition-delay: #delay;
-webkit-transition-timing-function:#timing;
-moz-transition-timing-function:#timing;
-ms-transition-timing-function:#timing;
-o-transition-timing-function:#timing;
transition-timing-function:#timing;
}
.output() when (#raw-input = false) and (#compact = true) {
#propsLength: length(#props);
#durationLength: length(#duration);
#delayLength: length(#delay);
#timingLength: length(#timing);
.buildString(#i, #s: ~'') when (#i <= #propsLength) {
#prop: extract(#props, #i);
.setDuration() when (#i <= #durationLength) {
#dur: extract(#duration, #i);
}
.setDuration() when (#i > #durationLength) {
#dur: extract(#duration, #durationLength);
}
.setDuration();
.setDelay() when (#i <= #delayLength) {
#del: extract(#delay, #i);
}
.setDelay() when (#i > #delayLength) {
#del: extract(#delay, #delayLength);
}
.setDelay();
.setTiming() when (#i <= #timingLength) {
#time: extract(#timing, #i);
}
.setTiming() when (#i > #timingLength) {
#time: extract(#timing, #timingLength);
}
.setTiming();
.setDivider() when (#i > 1) {
#divider: ~'#{s},';
}
.setDivider() when (#i = 1) {
#divider: ~'';
}
.setDivider();
#string: #divider #prop #dur #del #time;
.buildString((#i + 1), #string);
}
.buildString(1);
.buildString(#i, #s: ~'') when (#i > #propsLength) {
.compact(#s);
}
}
.output() when not (#raw-input = false) {
.compact(#raw-input);
}
.compact(#string) {
-webkit-transition:#string;
-moz-transition:#string;
-ms-transition:#string;
-o-transition:#string;
transition:#string;
}
.output();
}
LESS Use Examples
.test {
.transition();
}
.test-props {
.transition(width);
}
.test-duration {
.transition(#duration: 3s);
}
.test-delay {
.transition(#delay: 10s);
}
.test-timing {
.transition(#timing: linear);
}
.test-all {
.transition(height, 4s, 12s, ease-out);
}
.test-multitransitions {
.transition(width, height, top; 1s, 2s; 0s, 1s, 3s; ease-in, ease-out, ease);
}
.test-not-compact {
.transition(width, height, top; 1s, 2s; 0s, 1s, 3s; ease-in, ease-out, ease; false);
}
.test-raw-input {
.transition(#raw-input: top 1s, bottom 1s, color 3s 1s linear;);
}
In the above examples, note two things in particular: (1) how the multiple values need to be passed using commas to separate the lists, but semicolons to separate the parameter groups. So to visualize, it is this:
.transition(width, height, top; 1s, 2s; 0s, 1s, 3s; ease-in, ease-out, ease);
|---Properties----|-Dur.--|---Delay---|---------Timing--------|
| | |
semicolons divide groups of parameters
(2) how the raw-input example needs an ending semicolon to have it consider the commas as list items:
.transition(#raw-input: top 1s, bottom 1s, color 3s 1s linear;);
|
semicolon here needed
CSS Output of Examples
.test {
-webkit-transition: all 1s 0s ease;
-moz-transition: all 1s 0s ease;
-ms-transition: all 1s 0s ease;
-o-transition: all 1s 0s ease;
transition: all 1s 0s ease;
}
.test-props {
-webkit-transition: width 1s 0s ease;
-moz-transition: width 1s 0s ease;
-ms-transition: width 1s 0s ease;
-o-transition: width 1s 0s ease;
transition: width 1s 0s ease;
}
.test-duration {
-webkit-transition: all 3s 0s ease;
-moz-transition: all 3s 0s ease;
-ms-transition: all 3s 0s ease;
-o-transition: all 3s 0s ease;
transition: all 3s 0s ease;
}
.test-delay {
-webkit-transition: all 1s 10s ease;
-moz-transition: all 1s 10s ease;
-ms-transition: all 1s 10s ease;
-o-transition: all 1s 10s ease;
transition: all 1s 10s ease;
}
.test-timing {
-webkit-transition: all 1s 0s linear;
-moz-transition: all 1s 0s linear;
-ms-transition: all 1s 0s linear;
-o-transition: all 1s 0s linear;
transition: all 1s 0s linear;
}
.test-all {
-webkit-transition: height 4s 12s ease-out;
-moz-transition: height 4s 12s ease-out;
-ms-transition: height 4s 12s ease-out;
-o-transition: height 4s 12s ease-out;
transition: height 4s 12s ease-out;
}
.test-multitransitions {
-webkit-transition: width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
-moz-transition: width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
-ms-transition: width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
-o-transition: width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
transition: width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
}
.test-not-compact {
-webkit-transition-property: width, height, top;
-moz-transition-property: width, height, top;
-ms-transition-property: width, height, top;
-o-transition-property: width, height, top;
transition-property: width, height, top;
-webkit-transition-duration: 1s, 2s;
-moz-transition-duration: 1s, 2s;
-ms-transition-duration: 1s, 2s;
-o-transition-duration: 1s, 2s;
transition-duration: 1s, 2s;
-webkit-transition-delay: 0s, 1s, 3s;
-moz-transition-delay: 0s, 1s, 3s;
-ms-transition-delay: 0s, 1s, 3s;
-o-transition-delay: 0s, 1s, 3s;
transition-delay: 0s, 1s, 3s;
-webkit-transition-timing-function: ease-in, ease-out, ease;
-moz-transition-timing-function: ease-in, ease-out, ease;
-ms-transition-timing-function: ease-in, ease-out, ease;
-o-transition-timing-function: ease-in, ease-out, ease;
transition-timing-function: ease-in, ease-out, ease;
}
.test-raw-input {
-webkit-transition: top 1s, bottom 1s, color 3s 1s linear;
-moz-transition: top 1s, bottom 1s, color 3s 1s linear;
-ms-transition: top 1s, bottom 1s, color 3s 1s linear;
-o-transition: top 1s, bottom 1s, color 3s 1s linear;
transition: top 1s, bottom 1s, color 3s 1s linear;
}
If long form is never desired then the mixin code can reduce to this:
.transition (#props: all;
#duration:1s;
#delay: 0s;
#timing: ease;
#raw-input: false) {
.output() when (#raw-input = false) {
#propsLength: length(#props);
#durationLength: length(#duration);
#delayLength: length(#delay);
#timingLength: length(#timing);
.buildString(#i, #s: ~'') when (#i <= #propsLength) {
#prop: extract(#props, #i);
.setDuration() when (#i <= #durationLength) {
#dur: extract(#duration, #i);
}
.setDuration() when (#i > #durationLength) {
#dur: extract(#duration, #durationLength);
}
.setDuration();
.setDelay() when (#i <= #delayLength) {
#del: extract(#delay, #i);
}
.setDelay() when (#i > #delayLength) {
#del: extract(#delay, #delayLength);
}
.setDelay();
.setTiming() when (#i <= #timingLength) {
#time: extract(#timing, #i);
}
.setTiming() when (#i > #timingLength) {
#time: extract(#timing, #timingLength);
}
.setTiming();
.setDivider() when (#i > 1) {
#divider: ~'#{s},';
}
.setDivider() when (#i = 1) {
#divider: ~'';
}
.setDivider();
#string: #divider #prop #dur #del #time;
.buildString((#i + 1), #string);
}
.buildString(1);
.buildString(#i, #s: ~'') when (#i > #propsLength) {
.compact(#s);
}
}
.output() when not (#raw-input = false) {
.compact(#raw-input);
}
.compact(#string) {
-webkit-transition:#string;
-moz-transition:#string;
-ms-transition:#string;
-o-transition:#string;
transition:#string;
}
.output();
}
From less.js 1.3 onwards you have to specify ... in the argument list to signify that more arguments can be added. e.g.
.transition-property(...) {
foo: #arguments;
}