I've been lurking around for a mixin that would create prefixed keyframes declarations, but i couldn't find anything that actually work as it should without ugly fixes.
So far i've managed to create the following mixin:
.keyframes(#identifier, #animation) {
.frames { content: ~"'';} #-webkit-keyframes #{identifier} {#{animation}} #-moz-keyframes #{identifier} {#{animation}} #-ms-keyframes #{identifier} {#{animation}} #-o-keyframes #{identifier} {#{animation}} #keyframes #{identifier} {#{animation}"}
}
Where the usage would be:
.keyframes(fade-in, ~"0% { opacity: 0; }50% { opacity: 0; }100% { opacity: 1; }");
I feel like this is just plain wrong in matters of readability and also it creates a rule ( .frames { content: '' }; ) for each time the .keyframes() mixin is called.
Is there another way of doing this nicely?
Sidenote:
When i type npm info less --version it returns 1.4.28 if that's important.
#seven-phases-max had some really helpful comments regarding this. The fix ended up being to use a post compile processing for css (https://github.com/postcss/autoprefixer), which also helped me/the teams i am currently working with with other tasks as well.
For details, please refer to comments in the question.
Related
I have the code at the bottom of the page in my sass. In my html I am targeting it as follows
class=" transform rotate-5 zoom-2 ......"
the problem is that the transform properties are clashing and aren't applying scale and rotate to the same div tag, I'm either getting one or the other.
I thought I could change this by using the #extend property and something like,
&.rotate-#{$i}
{#extend &.skew-#{$i}, &.zoom-#{$i}, &.zoom--#{$i};
transform: rotate($rotate#{deg});
}
but so far I've had no luck, if anyone can help it'd be greatly appreciated.
.transform {
overflow:hidden;
#for $i from 1 through 360 {
$rotate: $i;
$skew: $i;
$zoom: $i;
&.rotate-#{$i} {
transform: rotate($rotate#{deg});
}
&.skew-#{$i} {
transform: skew($skew#{deg});
}
&.zoom-#{$i} {
transform: scale($zoom,0);
}
&.zoom--#{$i} {
transform: scale(-$zoom,0);
}
}
}
I'm a big fan of utility classes that I thought easier to debug and to build with. But here it doesn't seem to be a good idea:
1) You are creating 360 * 4 selectors, yet you will probably only use 10-20 of them. It is a bit overkill.
2) As you describe it, the transform property values do not "combine" well, at least for what you are looking for. Even atomic CSS, which pushes very far the utility classes approach, specificies that combining different values of filter (for instance) needs creating a custom value / class.
I understand that it is not really a good answer, at least not the answer you were looking for, but if you want to keep your CSS only approach, I suggest you adopt a more "object-oriented" method for this issue and set your transform property directly in the css of your object, for instance with this mixin:
#mixin transform($rotate, $skew, $zoom) {
transform: rotate($rotate#{deg}) skew($skew#{deg}) scale($zoom,0) scale(-$zoom,0);
}
I'm writing a questionnaire system in react and want to get the questions smoothly transitioning in and out.
Here's the render method for my component that displays the questions within.
render () {
const { loadingQuestion, question, userId, actions } = this.props;
const q = this.renderQuestion(question, (...args) => actions.answerQuestion(userId, ...args), (...args) => actions.skipQuestion(userId, ...args));
return (
<ul className="questions">
<ReactCSSTransitionGroup
transitionName="question"
transitionEnterTimeout={1000}
transitionLeaveTimeout={1000}
>
{q}
</ReactCSSTransitionGroup>
</ul>
);
}
And also the css I'm using at the moment to achieve the vertical transition:
.question-enter {
transform: translateY(100%);
}
.question-enter.question-enter-active {
transform: translateY(0%);
transition: transform 1000ms ease-in-out;
}
.question-leave {
transform: translateY(0%);
}
.question-leave.question-leave-active {
transform: translateY(-100%);
transition: transform 1000ms ease-in-out;
}
Here's a link to a page showing the current behaviour:
http://price-it.co:8080/frame
Does anyone know why this css doesn't cause the question to slide out and instead just causes it to disappear?
Thanks!
Your example is not working in my browser (I got app.js:12Redux DevTools could not render. Did you forget to include DevTools.instrument() in your store enhancer chain before using createStore()? error).
But I could say I have the same kind of experience with CSSTransitionGroup, so I decided to use <TransitionGroup> with Velocity instead - sure it's a little bit more jQuery-style, but it obviosely works better then css animation.
I've been using parameterless mixins for pure CSS animations so that my classes and my keyframes don't contain a bunch of repetitive styles, something similar to the following:
//css classes excluded for brevity, compile as expected
#mixin btn() {
color: black;
}
#mixin btn-hover() {
color: white;
}
#keyframes hover {
from {
#include btn();
}
to {
#include btn-hover();
}
}
Recently I converted those mixins to placeholder selectors like so:
//css classes excluded for brevity, compile as expected
%btn {
color: black;
}
%btn-hover {
color: white;
}
#keyframes hover {
from {
extend %btn;
}
to {
extend %btn-hover;
}
}
That didn't work, and in retrospect it's perfectly clear why not. What confuses me is why this compiles in the first place. The resulting CSS is valid #keyframes block that's completely empty:
#keyframes hover {
}
Assuming my understanding of how the extend concept works in Sass is correct and complete, using placeholder selectors in this manner makes no sense. Why is this valid syntax to begin with? Why don't I get a compile error?
It isn't considered valid and it should raise an error.
Error from Sass 3.3:
You may not #extend an outer selector from within #keyframes.
You may only #extend selectors within the same directive.
From "#extend %btn" on line 11.
Error from Sass 3.4:
Extend directives may only be used within rules.
If you are using Sass 3.2 or older, you should upgrade. If you're using LibSass, there's not much you can do about it other than report the issue on their bug tracker if it isn't already there.
I'm currently trying to find a way to generate prefixed keyframes with Less.
This is the loop that generates the prefixed versions, and it works. The only problem is when I add a from{} to{} declaration inside the dostuff animation it breaks it and causes Less to treat them like a mixin.
Is there any way to get this to work?
#key-prefix: ~"#-webkit-",~"#-o-",~"#-moz-",~"#";
.generate-keyframes(#i) when (#i > 0) {
.load1-keyframes((#i - 1));
#prefix: extract(#key-prefix,#i);
#{prefix}keyframes dostuff {
}
}
.generate-keyframes(4);
In short, no, an interpolation of the at-rule directive identifiers is not supported (and is not planned to be).
Well, you can get what you want with something like:
.vendorize-keyframes(dostuff, {
0% {color: tomato}
to {color: potato}
});
.vendorize-keyframes(#name, #frames) {
#-webkit-keyframes #name {#frames();}
#-moz-keyframes #name {#frames();}
#-o-keyframes #name {#frames();}
#keyframes #name {#frames();}
}
But in general the recommendation is to consider to use a tool like autoprefixer and stop polluting your Less and/or CSS code with these hardcoded vendor prefixes.
The site where I want my animation to work adds #user-space before any of my tags. So, my animation looks like this:
#user-space #-webkit-keyframes animation-name {
from {
style definition ["Before"-state]
}
to {
style definition ["After"-state]
}
And that #user-space declaration is breaking the css statement and animation is not working. Is there any way, to do that otherwise? For exaple put my keyframes insine -webkit-animation: animation-name 1.1s ease infinite; like
webkit-animation: from {
style definition ["Before"-state]
}
to {
style definition ["After"-state]
} 1.1s ease infinite; like
The solution I see is to get around your problem and do it with javascript.
Simply add a new style in your html file (in the header) and add the #-webkit-keyframes animation inside.
There is a thread which explains it well (see accepted solution): Set the webkit-keyframes from/to parameter with JavaScript