今日は退屈なので、CSS3 プレフィックスの問題についてもう一度話しましょう。春節の前に、@一丝姉さんと Sass のグラデーション ミックスインについて話しました。私の妹は言いました:
なぜまだ mixin を使用する必要があるのですか? Autoprefixer を使用しないのはなぜですか? Autoprefixer を使用すると、コード行を入力するだけで、コンパイラーがすべてを実行して、ミックスインが残ります。
妹の言葉を聞いて恥ずかしくなりました。私は、接頭辞を必要とする Gradient や同様の CSS3 プロパティを Sass に記述させる方法をまだ考えています。 Autoprefixer のような後処理を使うと、Sass の CSS3 ミックスインは存在意味を失ってしまったのではないかとも考えさせられます。そんな理由で?今日は CSS3 プレフィックスについての議論を始めましょう。
CSS3 属性を使用したことのある学生は、CSS3 属性に接頭辞を付ける必要があることをブラウザごとに知っていますが、今でも接頭辞を付ける必要がある属性がたくさんあります。どうしてこれなの?
私の理解では、ブラウザ ベンダーは以前から CSS3 を実装していましたが、まだ真の標準にはなっていませんでした。このため、一部の CSS3 スタイル構文では、ブラウザー固有のプレフィックスが存在するままに提供されます。現在人気のある主なブラウザ カーネルは次のとおりです。
異なるコアを備えたブラウザの場合、CSS3 属性 (プレフィックスを付ける必要がある一部の属性) に異なるプレフィックスを追加する必要があります。これは、ブラウザのプライベート プレフィックスとも呼ばれます。プライベート プレフィックスの後に CSS3 プロパティを追加します。プレフィックスは、対応するブラウザのプライベート プロパティであると言えます:
初期段階で丸みを帯びた境界半径を記述するには、次のように記述する必要があります:
.box { -moz-border-radius: 5px; -webkit-border-radius: 5px; -o-border-radius: 5px; border-radius: 5px;}
この方法でコードを書くと、フロントエンドのスタッフの負担が大きくなるため、「ブラウザのプライベート プレフィックスを追加せずに CSS を記述し、ブラウザに認識させるにはどうすればよいか?」という問題について議論する人もいました。
-prefix-free手書きの接頭辞の問題を解決するための最も初期の解決策の 1 つは、Lea Verou によって提供された -prefix-free スクリプトでした。 prefixfree.js ファイルを .html ファイルに挿入するだけです (文書内のどこにでも構いません)。このスクリプト ファイルはスタイル シートの後に配置することをお勧めします。
このスクリプトを追加した後、CSS3 プロパティを使用する場合は、標準スタイルを記述するだけで済みます。しかし、このアプローチでは、クライアントに対処しなければならないあらゆるプレッシャーがかかります。その結果、ページ解析の負荷が大きくなり、スクリプトの読み込みに失敗すると、ブラウザは CSS3 スタイルを正常にレンダリングできなくなります。
prefixfree スクリプトは、IE9 以降、Opera10 以降、Firefox3.5 以降、Safari4 以降でのみサポートされています。
エディター プラグイン
エディターに Autoprefixer プラグインをインストールするには、まず環境に Node.js をインストールする必要があります。コマンドターミナルで
rrree
を実行して、インストールされているかどうかを確認できます。インストールされていない場合は、最初にインストールしてください。ここでは、Node.js 環境がすでにあることを前提としています。Sublime Text エディターを開き、command + Shift + p キーを同時に押して、「パッケージのインストール」を選択します。次に、オートプレフィクサーを検索します。
今度は、Sublime Text で Autoprefixer 機能を使用します。次のように入力するとします。
node -v
.box { transform: rotate(45deg); border-radius: 5px; box-shadow: 1px 1px 0 rgba(0,0,0,.25); transition: all .2s ease .1s;}
注: 構成が異なると、実行効果も異なります。詳細はこちらでご覧いただけます。
プリプロセッサでの混合マクロ
正如前面所说的,如果要跟上浏览器的演进,就需要不断的更新你的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。
使用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的运行环境,如果没有请先移步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) taskFile 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爽多了。
除了Grunt可以配置Autoprefixer之外,还可以使用Gulp来配置。这里也假设你的项目中已具备了Gulp的运行环境,如果没有,可以查阅Gulp官网相关资料。
根据gulp-autoprefixer官网提示,我在命令终端输入了:
npm install gulp-autoprefixer --save-dev
在终端中可以看到这样的提示信息:
在Grunt中需要在Gruntfile.js进行配置,而在Gulp中也有点类似,需要在gulpfile.js中进行配置:
// include gulpvar gulp = require('gulp');// include plug-insvar autoprefix = require('gulp-autoprefixer');// JS hint taskgulp.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去处理。当然,越到后面,或许我们都不需要使用任何前缀。