Related
I'm using a bunch of elements to compose a background image and they all absolutely position around, rotating freely.
Problem is, I would like to transition only the rotation of those objects, not the top nor left properties. And apparently transition: transform 30s; isn't allowed. I had the brilliant idea of doing
transition:all 30s ease-out;
transition: left 0s;
transition: top 0s;
But that also doesn't work. How can I solve this?
Transform is a vendor prefix
Instead of
transition:all 30s ease-out;
transition: left 0s;
transition: top 0s;
do
-webkit-transition: -webkit-transform $amount-of-time ease-out;
-moz-transition: -moz-transform $amount-of-time ease-out;
-o-transition: -o-transform $amount-of-time ease-out;
-ms-transition: -ms-transform $amount-of-time ease-out;
transition: transform $amount-of-time ease-out;
To animate only the rotate property, I found this works in at least Chrome:
transition: transform 2.0s;
You can set different animation times for different properties inside the one transition property:
transition: transform 2.0s, color 5.0s, font-size 1.0s;
The trick with the rotate property specifically is that you have use the transform property instead. Intuitively, this should work but does NOT work:
transition: rotate 2.0s; /* DOES NOT WORK */
Instead you have to use transform in place of rotate:
transition: transform 2.0s;
This is probably because rotate: 90deg is shorthand for transform: rotate(90deg)
Note
transition is now supported in the latest versions of all major browsers. I assume if you want more compatibility with older browsers, you might do something like:
-webkit-transition: -webkit-transform 2.0s, color 5.0s, font-size 1.0s;
-moz-transition: -moz-transform 2.0s, color 5.0s, font-size 1.0s;
-ms-transition: -ms-transform 2.0s, color 5.0s, font-size 1.0s;
-o-transition: -o-transform 2.0s, color 5.0s, font-size 1.0s;
transition: transform 2.0s, color 5.0s, font-size 1.0s;
Two questions please, as I'm new to CSS3:
1) I understand that -XXX-transtion: opacity .4s below says to Webkit and Firefox browsers: change opacity to zero over the course of 400ms. But what does the comma right afterwards mean?
opacity: 0;
-webkit-transition: opacity .4s, -webkit-transform .4s;
-moz-transition: opacity .4s, -moz-transform .4s;
2) Given the mixins.less file below, how to rewrite the above statements?
.transform(#transform) {
-webkit-transform: #transform;
-moz-transform: #transform;
-ms-transform: #transform;
-o-transform: #transform;
transform: #transform;
}
.transition(#transition) {
-webkit-transition: #transition;
-moz-transition: #transition;
-ms-transition: #transition;
-o-transition: #transition;
transition: #transition;
}
The answer to your 1st question:
You can use commas in transitions to specify multiple styles for which transition has to be applied.For eg: the line -webkit-transition: opacity .4s, -webkit-transform .4s would tell to apply the transition when opacity is being changed and when a transform is being done(can be a shape change,position change or size change depending on the type of transform)
I'd like to apply a CSS transition to all properties apart from background-position.
I tried to do it this way:
.csstransitions a {
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
-ms-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.csstransitions a {
-webkit-transition: background-position 0s ease 0s;
-moz-transition: background-position 0s ease 0s;
-o-transition: background-position 0s ease 0s;
-ms-transition: background-position 0s ease 0s;
transition: background-position 0s ease 0s;
}
First I set all properties to transition and then I tried to overwrite solely the transition for the background-position property.
However this seems to also reset all other properties - so basically none of the transitions seem to happen any more.
Is there a way to do this without listing all properties?
Here's a solution that also works on Firefox:
transition: all 0.3s ease, background-position 1ms;
I made a small demo: http://jsfiddle.net/aWzwh/
Hope not to be late. It is accomplished using only one line!
-webkit-transition: all 0.2s ease-in-out, width 0, height 0, top 0, left 0;
-moz-transition: all 0.2s ease-in-out, width 0, height 0, top 0, left 0;
-o-transition: all 0.2s ease-in-out, width 0, height 0, top 0, left 0;
transition: all 0.2s ease-in-out, width 0, height 0, top 0, left 0;
That works on Chrome. You have to separate the CSS properties with a comma.
Here is a working example: http://jsfiddle.net/H2jet/
You can try using the standard W3C way:
.transition { transition: all 0.2s, top 0s, left 0s, width 0s, height 0s; }
http://jsfiddle.net/H2jet/60/
Try this...
* {
transition: all .2s linear;
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-o-transition: all .2s linear;
}
a {
-webkit-transition: background-position 1ms linear;
-moz-transition: background-position 1ms linear;
-o-transition: background-position 1ms linear;
transition: background-position 1ms linear;
}
For anyone looks for a shorthand way, to add transition for all properties except for one specific property with delay, be aware of there're differences among even modern browsers.
A simple demo below shows the difference. Check out full code
div:hover {
width: 500px;
height: 500px;
border-radius: 0;
transition: all 2s, border-radius 2s 4s;
}
Chrome will "combine" the two animation (which is like I expect), like below:
While Safari "separates" it (which may not be expected):
A more compatible way is that you assign the specific transition for specific property, if you have a delay for one of them.
Try:
-webkit-transition: all .2s linear, background-position 0;
This worked for me on something similar..
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;
}
I can't seem to find the correct syntax for the CSS transition shorthand with multiple properties. This doesn't do anything:
.element {
-webkit-transition: height .5s, opacity .5s .5s;
-moz-transition: height .5s, opacity .5s .5s;
-ms-transition: height .5s, opacity .5s .5s;
transition: height .5s, opacity .5s .5s;
height: 0;
opacity: 0;
overflow: 0;
}
.element.show {
height: 200px;
opacity: 1;
}
I add the show class with javascript. The element becomes higher and visible, it just doesn't transition. Testing in latest Chrome, FF and Safari.
What am I doing wrong?
EDIT: Just to be clear, I'm looking for the shorthand version to scale my CSS down. It's bloated enough with all the vendor prefixes. Also expanded the example code.
Syntax:
transition: <property> || <duration> || <timing-function> || <delay> [, ...];
Note that the duration must come before the delay, if the latter is specified.
Individual transitions combined in shorthand declarations:
-webkit-transition: height 0.3s ease-out, opacity 0.3s ease 0.5s;
-moz-transition: height 0.3s ease-out, opacity 0.3s ease 0.5s;
-o-transition: height 0.3s ease-out, opacity 0.3s ease 0.5s;
transition: height 0.3s ease-out, opacity 0.3s ease 0.5s;
Or just transition them all:
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
Here is a straightforward example. Here is another one with the delay property.
Edit: previously listed here were the compatibilities and known issues regarding transition. Removed for readability.
Bottom-line: just use it. The nature of this property is non-breaking for all applications and compatibility is now well above 94% globally.
If you still want to be sure, refer to http://caniuse.com/css-transitions
If you have several specific properties that you want to transition in the same way (because you also have some properties you specifically don't want to transition, say opacity), another option is to do something like this (prefixes omitted for brevity):
.myclass {
transition: all 200ms ease;
transition-property: box-shadow, height, width, background, font-size;
}
The second declaration overrides the all in the shorthand declaration above it and makes for (occasionally) more concise code.
/* prefixes omitted for brevity */
.box {
height: 100px;
width: 100px;
background: red;
box-shadow: red 0 0 5px 1px;
transition: all 500ms ease;
/*note: not transitioning width */
transition-property: height, background, box-shadow;
}
.box:hover {
height: 50px;
width: 50px;
box-shadow: blue 0 0 10px 3px;
background: blue;
}
<p>Hover box for demo</p>
<div class="box"></div>
Demo
I made it work with this:
.element {
transition: height 3s ease-out, width 5s ease-in;
}
One important thing to note is that the CSS transition property itself is a shorthand - as mentioned in the MDN Web Docs :
The transition CSS property is a shorthand property for transition-property, transition-duration, transition-timing-function, and transition-delay.
The ideal use of this shorthand is to combine the various Constituent properties of a single transition. If this is used to combine multiple transitions, it will start to get clunky.
So when you have more than 2 transitions on the same element which different constituent properties, it becomes easier to write them individually instead of using the transition shorthand. For example:
This is the shorthand version(Option 1) of multiple transitions on one element:
transition: transform 0.5s ease-in-out, box-shadow 0.2s ease-out, filter 0.1s ease-out, color 0.25s ease-in 0.2s;
As you can see, this gets clunky and a little bit harder to visualize.
The same CSS can be applied like this(Option 2):
transition-property: transform, box-shadow, filter, color;
transition-duration: 0.5s, 0.2s, 0.2s, 0.25s;
transition-timing-function: ease-in-out, ease-out, ease-out, ease-in;
transition-delay: 0s, 0s, 0s, 0.2s
Of course, ultimately it all just comes down to your preference of typing and maintaining your source code. But I personally prefer the 2nd option.
TIP:
Additional benefit of using this is, if one of the Constituent properties is same for all transitions, you don't need to mention it multiple times. For example, in the above example, if the transition-duration was the same(0.5s) for all, you write it like this:
transition-property: transform, box-shadow, filter, color;
transition-duration: 0.5s;
transition-timing-function: ease-in-out, ease-out, ease-out, ease-in;
transition-delay: 0s, 0s, 0s, 0.2s
By having the .5s delay on transitioning the opacity property, the element will be completely transparent (and thus invisible) the whole time its height is transitioning. So the only thing you will actually see is the opacity changing. So you will get the same effect as leaving the height property out of the transition :
"transition: opacity .5s .5s;"
Is that what you're wanting? If not, and you're wanting to see the height transition, you can't have an opacity of zero during the whole time that it's transitioning.
This helped me understand / streamline, only what I needed to animate:
// SCSS - Multiple Animation: Properties | durations | etc.
// on hover, animate div (width/opacity) - from: {0px, 0} to: {100vw, 1}
.base {
max-width: 0vw;
opacity: 0;
transition-property: max-width, opacity; // relative order
transition-duration: 2s, 4s; // effects relatively ordered animation properties
transition-delay: 6s; // effects delay of all animation properties
animation-timing-function: ease;
&:hover {
max-width: 100vw;
opacity: 1;
transition-duration: 5s; // effects duration of all aniomation properties
transition-delay: 2s, 7s; // effects relatively ordered animation properties
}
}
~ This applies for all transition properties (duration, transition-timing-function, etc.) within the '.base' class
I think that this should work:
.element {
-webkit-transition: all .3s;
-moz-transition: all .3s;
-o-transition: all .3s;
transition: all .3s;
}