最近因为项目缘故,勾搭上了Sass。
其实在折腾Sass之前,也有简单用过一下Less。但碍于Less提供的一些API实在让人觉得有点多余,用着就是不顺手,最后就不了了之啦。
Sass之所以用起来舒服和顺手,很大程度上是因为Compass的存在。Compass提供的足够丰富的API,简直让你觉得写CSS是一种享受。
不过...
Compass居然不支持animation!对,没错,就是CSS3那个做来做动画的animation!(至少我翻了好久的Compass文档也没找到...)
或许你会吐槽说:“啧,自己用Sass的@mixin封装一个animation的方法就搞定啦!”
恩,我一开始也是这么想的,然后我也这么做了...
———— 正文分割线————
作为一个Sass新手,我想要一个animation的@mixin时,必然是:
/* animation.scss */@mixin animation($duration, $name, $count, $function) { -webkit-animation-duration: $duration; -webkit-animation-name: $name; -webkit-animation-iteration-count: $count; -webkit-animation-timing-function: $function; -moz-animation-duration: $duration; -moz-animation-name: $name; -moz-animation-iteration-count: $count; -moz-animation-timing-function: $function; -ms-animation-duration: $duration; -ms-animation-name: $name; -ms-animation-iteration-count: $count; -ms-animation-timing-function: $function; -o-animation-duration: $duration; -o-animation-name: $name; -o-animation-iteration-count: $count; -o-animation-timing-function: $function; animation-duration: $duration; animation-name: $name; animation-iteration-count: $count; animation-timing-function: $function;}
恩,这样貌似就达到了用Sass实现了animation的目的啦。
然后我们再优化一下代码:
/* animation.scss */@mixin animation($name, $duration, $function: ease, $delay: 0s, $count: infinite) { -webkit-animation: $name $duration $function $delay $count; -moz-animation: $name $duration $function $delay $count; -ms-animation: $name $duration $function $delay $count; -o-animation: $name $duration $function $delay $count; animation: $name $duration $function $delay $count;}
这样看,代码优雅多了(自我感觉良好~)。
文章这样就结束了?坑爹吗?!
当然不是!想用animation做动画,自然还要把@keyframes也用上。按照上面的思路,继续用@mixin封装一下相关css代码:
/* keyframes.scss */@mixin keyframes($animationName) { @-webkit-keyframes $animationName { @content; } @-moz-keyframes $animationName { @content; } @-ms-keyframes $animationName { @content; } @-o-keyframes $animationName { @content; } @keyframes $animationName { @content; }}
看起来貌似一切都妥妥的。
配合上Compass愉快的投入生产:
/* demo1.scss */@import "compass";@import "animation.scss";@import "keyframes.scss";.circle { @include animation(circle, 1s, linear);}@include keyframes(circle) { 0% { opacity: 0; @include translate(100px, 0); } 100% { opacity: 1; @include translate(0, 0); }}
这样写Sass,真的很简洁很舒服。忍不住打开编译生成的css文件一看,差点哭了出来:
/* demo1.css */.circle { -webkit-animation: circle 1s linear 0s infinite; -moz-animation: circle 1s linear 0s infinite; -ms-animation: circle 1s linear 0s infinite; -o-animation: circle 1s linear 0s infinite; animation: circle 1s linear 0s infinite;}@-webkit-keyframes circle { 0% { opacity: 0; -webkit-transform: translate(100px, 0); -moz-transform: translate(100px, 0); -ms-transform: translate(100px, 0); -o-transform: translate(100px, 0); transform: translate(100px, 0); } 100% { opacity: 1; -webkit-transform: translate(0, 0); -moz-transform: translate(0, 0); -ms-transform: translate(0, 0); -o-transform: translate(0, 0); transform: translate(0, 0); }}@-moz-keyframes circle { 0% { opacity: 0; -webkit-transform: translate(100px, 0); -moz-transform: translate(100px, 0); -ms-transform: translate(100px, 0); -o-transform: translate(100px, 0); transform: translate(100px, 0); } 100% { opacity: 1; -webkit-transform: translate(0, 0); -moz-transform: translate(0, 0); -ms-transform: translate(0, 0); -o-transform: translate(0, 0); transform: translate(0, 0); }}@-ms-keyframes circle { 0% { opacity: 0; -webkit-transform: translate(100px, 0); -moz-transform: translate(100px, 0); -ms-transform: translate(100px, 0); -o-transform: translate(100px, 0); transform: translate(100px, 0); } 100% { opacity: 1; -webkit-transform: translate(0, 0); -moz-transform: translate(0, 0); -ms-transform: translate(0, 0); -o-transform: translate(0, 0); transform: translate(0, 0); }}@-o-keyframes circle { 0% { opacity: 0; -webkit-transform: translate(100px, 0); -moz-transform: translate(100px, 0); -ms-transform: translate(100px, 0); -o-transform: translate(100px, 0); transform: translate(100px, 0); } 100% { opacity: 1; -webkit-transform: translate(0, 0); -moz-transform: translate(0, 0); -ms-transform: translate(0, 0); -o-transform: translate(0, 0); transform: translate(0, 0); }}@keyframes circle { 0% { opacity: 0; -webkit-transform: translate(100px, 0); -moz-transform: translate(100px, 0); -ms-transform: translate(100px, 0); -o-transform: translate(100px, 0); transform: translate(100px, 0); } 100% { opacity: 1; -webkit-transform: translate(0, 0); -moz-transform: translate(0, 0); -ms-transform: translate(0, 0); -o-transform: translate(0, 0); transform: translate(0, 0); }}
可以看到,每一个@keyframes里面,都重复输出了一套完整兼容的transform。虽然这样的代码不会出现任何异常,但作为一个稍稍有点洁癖的程序员,估计都无法忍受这样的效果。
随后想了几个解决方法,都不能很好的解决。主要被以下几个问题困扰着:
Google了一下相关信息,也没找到现成的animation for sass的方法。
幸亏最后在stackoverflow上发现了一个有趣的问题→_→传送门。
提问人和我遇到了类似的情况,也是卡在了@keyframes的私有属性输出的问题。十分幸运的是,在问题下面的回答中,发现了Bourbon这个Sass的库。
Bourbon所封装的@keyframes方法,就很好的解决了我上面遇到的问题。
忍不住看了一下它的源码,实现思路很妙。还帮助我更好的弄清了Compass中experimental的实现思路。
考虑到Compass和Bourbon没有相互依赖的关系,同时使用会出现变量污染的问题。最后根据Bourbon的实现思路,重构了这么一个叫做easy-animation的动画工具集。
/* easy-animation.scss */// easy-animation// Author: Maple Jan// Date: 2014-04-11// Support browser's private prefix.$ea-prefix-for-webkit: true !default;$ea-prefix-for-mozilla: true !default;$ea-prefix-for-microsoft: true !default;$ea-prefix-for-Opera: true !default;$ea-prefix-for-spec: true !default; // required for keyframe mixin// Disable all browser's private prefix.@mixin ea-disable-prefix-for-all() { $ea-prefix-for-webkit: false; $ea-prefix-for-mozilla: false; $ea-prefix-for-microsoft: false; $ea-prefix-for-opera: false; $ea-prefix-for-spec: false;}// Example usage:// @include ea-transition(all 2s ease 0s);@mixin ea-transition($value, $prefixs: webkit moz ms o spec) { @each $prefix in $prefixs { @if $prefix == webkit { @if $ea-prefix-for-webkit { -webkit-transition: $value; } } @else if $prefix == moz { @if $ea-prefix-for-mozilla { -moz-transition: $value; } } @else if $prefix == ms { @if $ea-prefix-for-microsoft { -ms-transition: $value; } } @else if $prefix == o { @if $ea-prefix-for-opera { -o-transition: $value; } } @else if $prefix == spec { @if $ea-prefix-for-spec { transition: $value; } } @else { @warn "Unrecognized prefix: #{$prefix}"; } }}// Example usage:// @include ea-transform(scale(1));@mixin ea-transform($value, $prefixs: webkit moz ms o spec) { @each $prefix in $prefixs { @if $prefix == webkit { @if $ea-prefix-for-webkit { -webkit-transform: $value; } } @else if $prefix == moz { @if $ea-prefix-for-mozilla { -moz-transform: $value; } } @else if $prefix == ms { @if $ea-prefix-for-microsoft { -ms-transform: $value; } } @else if $prefix == o { @if $ea-prefix-for-opera { -o-transform: $value; } } @else if $prefix == spec { @if $ea-prefix-for-spec { transform: $value; } } @else { @warn "Unrecognized prefix: #{$prefix}"; } }}// Example usage:// @include ea-animation(wrap_s0_p1, 2s, ease, 0s, infinite);@mixin ea-animation($name, $duration, $function: eas
新闻热点
疑难解答