今天闲来无聊,重新来说说CSS3前缀的问题。在春节前和@一丝姐姐说起Sass中有关于gradient的mixins。姐姐说:

为什么还要用mixin呢?为什么不使用Autoprefixer?使用Autoprefixer,只需要输入一行代码,编译器帮你做了一切,还纠结个毛mixin。

姐姐的一句话让我汗颜,我还在思考着如何让Sass来写Gradient,或者类似这样需要带前缀的CSS3属性。也这样让我在思考,那么有了 Autoprefixer这样的后处理,Sass中有关于CSS3的mixins是不是已失去了他存在的意义。带着这样的为什么?我们一起来开启今天有关 于CSS3前缀的探讨。

CSS3的属性为什么要带前缀

使用过CSS3属性的同学都知道,CSS3属性都需要带各浏览器的前缀,甚至到现在,依然还有很多属性需要带前缀。这是为什么呢?

我的理解是,浏览器厂商以前就一直在实施CSS3,但它还未成为真正的标准。为此,当一些CSS3样式语法还存在波动时,它们提供针对浏览器的前缀。现在主要流行的浏览器内核主要有:

  • Trident内核:主要代表为IE浏览器
  • Gecko内核:主要代表为Firefox
  • Presto内核:主要代表为Opera
  • Webkit内核:产要代表为Chrome和Safari

而这些不同内核的浏览器,CSS3属性(部分需要添加前缀的属性)对应需要添加不同的前缀,也将其称之为浏览器的私有前缀,添加上私有前缀之后的CSS3属性可以说是对应浏览器的私有属性:

  • Trident内核:前缀为-ms
  • Gecko内核:前缀为-moz
  • Presto内核:前缀为-o
  • Webkit内核:前缀为-webkit

来看一个简单的示例,早期写一个圆角border-radius,需要这样写:

.box {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
}

这样编写代码,无形之中给前端人员增加了不少工作量,于是开始有人在讨论这个问题“如何在编写CSS时不需要添加浏览器的私有前缀,又能让浏览器识别?”

-prefix-free

为了解决手工书写前缀的问题,最早的一个解决方案是由Lea Verou提供的一个-prefix-free脚本。你只需要在你的.html文件中插入一个prefixfree.js文件(可以是文档任何地方),建议把这个脚本文件放在样式表之后。

添加这个脚本之后,使用CSS3的属性时,只需书写标准样式即可。但是这种做法将所有压力交给了客户端来处理。如此一来页面解析压力就大了,性能会打一定的折扣,并且一旦脚本加载失败,那么就会出现浏览器无法正常渲染CSS3的样式风格。

prefixfree脚本仅在IE9+、Opera10+、Firefox3.5+、Safari4+得到支持。

编辑器插件

除了prefixfree脚本之外,很多同学依赖于文本编辑器的插件来处理。这里来看看Sublime Text编辑器里是如何实现Autoprefixer功能的。

要在编辑器中安装Autoprefixer插件,首先需要你的环境中已经安装好了Node.js。你可以在命令终端执行:

node -v

来检测是否已安装,如果没有安装,请先安装。在这里假设你已具备Node.js环境。

现在开启你的Sublime Text编辑器,你可以同时按下command + Shift + p三个键,选择"Install Package"。然后搜索Autoprefixer

现在你在你的Sublime Text中使用Autoprefixer功能。假设你在样式文件中输入:

.box {
transform: rotate(45deg);
border-radius: 5px;
box-shadow: 1px 1px 0 rgba(0,0,0,.25);
transition: all .2s ease .1s;
}

这个时候你只需要同时按下Command + Shift + P三个键,选择“Autoprefix CSS”,并且回车,就能得到下面这样的代码:

.box {
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
border-radius: 5px;
box-shadow: 1px 1px 0 rgba(0,0,0,.25);
transition: all .2s ease .1s;
}

如下图所示:

注:不同的配置,执行的效果不一样。详细可以点击这里查阅。

预处理器中的混合宏

随着CSS预处理器越来越普及,部分同学开始采用预处理器中的混合宏来处理CSS3前缀的事项。比如说Compass,里面就是使用Sass的mixin为CSS3需要带前缀的属性定制了一些mixin。还有类似于Stylus中的nib等。预处理器中的混合宏确实可以解决很多问题,但也产生了新的问题,就是它所使用的语法是全新的,如果要使用就必须重新学习,另外这类工具的演进速度通常都会跟不上浏览器的发展速度,这样也会造成其产生的CSS有过时的问题,有时候为了解决一些问题,还需要自己去写mixins。比如:

正如前面所说的,如果要跟上浏览器的演进,就需要不断的更新你的CSS3 mixins,不然就会造成你的代码不是最新的。其中Compass就存在这样的问题:

@import "compass";

.box {
@include border-radius(5px);
}

编译出来的CSS:

.box {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}

而现实却不尽人意,因为到写这篇文章为止,我们写圆角属性只需要:

.box {
border-radius: 5px;
}

各主流浏览器就能正常的解析。造成这个原因的时,Compass中的CSS3的mixin没有跟上步子去更新定义好的mixins。

使用Autoprefixer

使用Sass、LESS、Stylus或者其他类似的工具都是属于CSS的前处理器(Preprocessor),而Autoprefixer则是 一种后处理器(Postprocessor)。它是直接针对CSS本身来进行处理,不需要任何额外的语法。因为它是在CSS代码产生之后才进行后续处理。

Autoprefixer是以Rework这种架构所发展的CSS后处理器,他是将CSS代码解析后转成JavaScript的资料结构,进行处理后再产生新的CSS代码。

Autoprefixer会分析CSS代码,并且根据Can I Use所提供的资料来决定要加上哪些浏览器前缀,而你要做的事情就是把他加入自己的自动化开发工具中(比如Grunt或者Gulp),然后就可以直接使用W3C的标准来写CSS,不需要加上任何浏览器的私有前缀。

接下来看看如何使用自动化工具实现Autoprefixer功能。

Grunt中配置Autoprefixer

假设你的环境中已具备了Grunt的运行环境,如果没有请先移步Grunt官网了解,这里不做过多阐述。

在Github中有一个grunt-autoprefixer的插件,按照其官方提示,我在命令行中执行了下面的语句:

npm install grunt-autoprefixer --save-dev

命令终端提示:

似乎没有成功(其实我也不太懂Grunt,只是临阵磨枪)。于是我改投@一丝姐姐说的postcss。在命令终端重新输入:

npm install grunt-postcss --save-dev

这下似乎有戏了:

不过我还跟着官网所说的执行了另外一个命令:

npm install grunt-postcss autoprefixer-core csswring

运行命令后可以看到下图的提示信息:

接下来需要在你项目的根目录中配置Gruntfile.js文件:

'use strict';
module.exports = function(grunt) { // Dynamically loads all required grunt tasks
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks); var autoprefixer = require('autoprefixer-core'); // Configures the tasks that can be run
grunt.initConfig({
postcss: {
options: {
processors: [
autoprefixer({ browsers: ['last 2 version'] }).postcss
]
},
// dist: {
// src: 'src/css/*.css',
// dest:'dest/css/*.css'
// }
multiple_files: {
expand: true,
flatten: true,
src: 'src/css/*.css', // -> src/css/file1.css, src/css/file2.css
dest: 'dest/css/' // -> dest/css/file1.css, dest/css/file2.css
},
},
}); grunt.loadNpmTasks('grunt-postcss'); grunt.registerTask('default', ['postcss']); };

为了验证这样做是否正确,我在项目中的src/css/中创建了一个main.css文件,然后输入代码:

a {
transition: all .2s ease .1s;
transform: rotate(45deg) translateY(200px);
}

在命令终端执行:

grunt

终端将运行:

Running "postcss:multiple_files" (postcss) task
File dest/css/main.css created. Done, without errors.

查看项目中自动创建了一个dest/css/main.css文件,而里面的代码:

a {
transition: all .2s ease .1s;
-webkit-transform: rotate(45deg) translateY(200px);
transform: rotate(45deg) translateY(200px);
}

正是我需要的样式代码。这样尝试一回,觉得比使用Sass中的mixin爽多了。

Gulp中配置Autoprefixer

除了Grunt可以配置Autoprefixer之外,还可以使用Gulp来配置。这里也假设你的项目中已具备了Gulp的运行环境,如果没有,可以查阅Gulp官网相关资料。

根据gulp-autoprefixer官网提示,我在命令终端输入了:

npm install gulp-autoprefixer --save-dev

在终端中可以看到这样的提示信息:

在Grunt中需要在Gruntfile.js进行配置,而在Gulp中也有点类似,需要在gulpfile.js中进行配置:

// include gulp
var gulp = require('gulp'); // include plug-ins
var autoprefix = require('gulp-autoprefixer'); // JS hint task
gulp.task('styles', function() {
gulp.src(['./src/styles/*.css'])
.pipe(autoprefix('last 2 versions'))
.pipe(gulp.dest('./build/styles'));
});

看上去要比Gruntfile.js配置简单一些。为了验证操作是否正确,我在项目中创建了src/styles/style.css,并且在style.css文件中输入了:

a {
transform: translateY(20px) rotate(45deg);
}

接下来在命令终端执行:

gulp styles

看到如下提示信息:

[12:53:26] Using gulpfile ~/Sites/test/gulp-autoprefixer/gulpfile.js
[12:53:26] Starting 'styles'...
[12:53:26] Finished 'styles' after 7.26 ms

此时,在项目中会自动创建一个build/styles/style.css文件,打开这个文件查看代码:

a {
-webkit-transform: translateY(20px) rotate(45deg);
-ms-transform: translateY(20px) rotate(45deg);
transform: translateY(20px) rotate(45deg);
}

正是我们需要的。

其实在PostCSS也提供了有关于如何在Gulp中配置Autoprefixer的说明。感兴趣的同学可以看看

有了Autoprefixer这样的工具对于处理CSS3属性前缀来说就不再是头痛的事情了。当然,如果你正在使用CSS预处理器编写代码,那么也可以很完美的结合Autoprefixer去处理。

总结

经过几年的技术演进,CSS3属性前缀的问题已不再是一个问题。如今天你完全可以忽略我要不要加前缀,要加哪些前缀,而只需要专心去码你的代码。把这些烦人的事情交给Autoprefixer去处理。当然,越到后面,或许我们都不需要使用任何前缀。

如何处理CSS3属性前缀的更多相关文章

  1. 如何处理CSS3属性前缀(转载)总结

    今天闲来无聊,重新来说说CSS3前缀的问题.在春节前和@一丝姐姐说起Sass中有关于gradient的mixins.姐姐说: 为什么还要用mixin呢?为什么不使用Autoprefixer?使用Aut ...

  2. (13/24) css进阶:自动处理css3属性前缀

    什么是属性前缀 为了浏览器的兼容性,有时候我们必须加入-webkit,-ms,-o,-moz这些前缀.目的就是让我们写的页面在每个浏览器中都可以顺利运行. 例如: transition: width ...

  3. 详解CSS3属性前缀(转)

    原文地址 CSS3的属性为什么要带前缀 使用过CSS3属性的同学都知道,CSS3属性都需要带各浏览器的前缀,甚至到现在,依然还有很多属性需要带前缀.这是为什么呢? 我的理解是,浏览器厂商以前就一直在实 ...

  4. Autoprefixer处理CSS3属性前缀

    http://www.w3cplus.com/css3/autoprefixer-css-vender-prefixes.html

  5. CSS选择器,属性前缀,长度单位,变形效果,过渡效果,动画效果

    CSS3选择器 ·*通配选择器 ·E标签选择器 ·E#id ID选择器 ·E.class类选择器 ·E F包含选择器,后代选择器 ·E>F子包含选择器 ·E+F相邻兄弟选择器 ·E[foo]属性 ...

  6. 使用css3属性,大部分浏览器要识别前缀

    例如以下代码的解析 -ms-transform:rotate(7deg); -moz-transform:rotate(7deg); -webkit-transform:rotate(7deg); - ...

  7. css3浏览器私有属性前缀使用详解

    什么是浏览器私有属性前缀 CSS3的浏览器私有属性前缀是一个浏览器生产商经常使用的一种方式.它暗示该CSS属性或规则尚未成为W3C标准的一部分. 以下是几种常用前缀 -webkit- -moz- -m ...

  8. css3属性书写的时候带的一些前缀的意思

    使用css3属性时,大部分都要带这些识别前缀,早期点的浏览器才能识别.现在最新版的浏览器基本都支持css3 基本都不用写前缀 ,写前缀是为了向前兼容老版本的浏览器而已. -ms-transform: ...

  9. 用Emmet写CSS3属性会自动添加前缀

    CSS3的很多属性都包含浏览器厂商前缀,用Emmet写CSS3属性会自动添加前缀,比如输入trs 会展开为: -webkit-transition: prop time; -moz-transitio ...

随机推荐

  1. HTML 事件(三) 事件流与事件委托

    本篇主要介绍HTML DOM中的事件流和事件委托. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4 ...

  2. 冒泡,setinterval,背景图的div绑定事件,匿名函数问题

    1.会冒泡到兄弟元素么? $(function(){ $("#a").click(function(){alert("a")}) $("#b" ...

  3. CSS垂直居中的11种实现方式

    今天是邓呆呆球衣退役的日子,在这个颇具纪念意义的日子里我写下自己的第一篇博客,还望前辈们多多提携,多多指教! 接下来,就进入正文,来说说关于垂直居中的事.(以下这11种垂直居中的实现方式均为笔者在日常 ...

  4. 简约之美Jodd-http--深入源码理解http协议

    Jodd 是一个开源的 Java 工具集, 包含一些实用的工具类和小型框架.简单,却很强大! jodd-http是一个轻巧的HTTP客户端.现在我们以一个简单的示例从源码层看看是如何实现的? Http ...

  5. 【Reading Note】算法读书杂记

    1 排序 排序基本信息 稳定性:排序前大的数在排序后,大的数依然保持不变就是稳定排序,反之不稳定 内外排序:根据待排序的记录是否放在内存里面区分的.诸如:插入排序(直接插入&希尔).交换排序( ...

  6. 企业做数据缓存是使用Memcached还是选Redis?

    企业是使用Memcached还是选Redis? 在构建一款现代且由数据库驱动的Web应用程序并希望使其拥有更为出色的性能表现时,这个问题总会时不时出现.并给每一位开发人员带来困扰.在考虑对应用程序的性 ...

  7. Android—基于微信开放平台v3SDK,开发微信支付填坑。

    接触微信支付之前听说过这是一个坑,,,心里已经有了准备...我以为我没准跳坑出不来了,没有想到我填上了,调用成功之后我感觉公司所有的同事都是漂亮的,隔着北京的大雾霾我仿佛看见了太阳~~~好了,装逼结束 ...

  8. Android手机相册的布局

    实现类似下面的这种布局的方法

  9. 【代码笔记】iOS-获得当前的月的天数

    一,代码. #import "ViewController.h" @interface ViewController () @end @implementation ViewCon ...

  10. [AlwaysOn Availability Groups]健康模型 Part 1——概述

    健康模型概述 在成功部署AG之后,跟踪和维护健康状况是很重要的. 1.AG健康模型概述 AG的健康模型是基于策略管理(Policy Based Management PBM)的.如果不熟悉这个特性,可 ...