图解CSS:条件 CSS
特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)
在CSS的世界中,总是有很多实验性的属性先行,正因为这些先行者在不断的探索新的特性,才让CSS越来越强大。而这些实验性的特性并没有立马得到众多浏览器的支持,为了能让这些实验性特性能在部分支持的浏览器上运行,同时又能让不支持的浏览器做相应的降级处理。那么我们就会需要根据相关的条件进行判断。这也就是条件CSS的由来。
条件CSS的简介
条件CSS(Conditional CSS)现在被纳入到 CSS Conditional Rules Module Level 3 模块中。事实上,条件CSS的开发源于在多数浏览器上修正CSS渲染bug的需求,以确保尽量多的用户看到正确的网站设计。核心思想是建立在IE条件注释方法,并扩展到包含其他的浏览器,而且将条件声明内联到CSS定义里面。
但随着技术不断的革新,条件CSS现在很少使用条件注释这样的方式来做条件判断,而是提供一些CSS特性(比如,CSS的@
规则)及其相关的JavaScript API允许我们在满足特定条件时应用样式或行为。
需要注意的是,如果所有浏览器都能正确地执行W3C发布的CSS标准,那么条件CSS就没有需求了。但是,CSS在不同浏览器渲染总是会有或多或少的bug存在,而且往往都及其让人沮丧。条件CSS给我们提供了一个简单的方法来解决这些问题。加上文章开头也提到过了,在CSS的社区中总是有很多先驱者在不断的探索和创造一些实验性CSS特性。我们也可以通过条件CSS在一些已得到的浏览器上先用起来。
条件CSS分类
到目前为止,条件CSS主要有三个@
规则:
@media
@supports
@viewport
其中@media
和@supports
两个规则是我们常见的规则,也是真正的条件CSS,而@viewport
并不常见,但也不是真正的条件。
CSS中的@
规则
既然条件CSS运用到的也是CSS的@
规则,那么我们很有必要先简单的了解一下CSS的@
规则。
CSS的
@
规则(at-rule
)是一条语句,它为CSS提供了执行或如何执行的指令。
@
规则的每个语句都是以@
开头,后面直接跟着相应的关键词,这些关键词充当CSS应该做什么的标识符。尽管每个@
规则都有它的变体,但这也是最常见的语法规则。
CSS的@
规则主要分为常规规则和嵌套规则两大类。
常规规则
常规规则的语法较为简单,类似下面这样:
@[关键词](规则)
常规规则常见的主要:
@charset
大家不知道有没有印象,早期在创建.scss
或.less
文件时都会要求在第一行中使用@charset
来声明字符集,比如:
@charset 'utf-8'
在某些CSS属性(比如content
)中使用非ASCII
字符或样式表包含UTF-8
等非ASCII
字符时,@charset
规则非常有用。另外,@charset
规则必须是样式表中的第一个元素,并且前面不能有任何字符。用户代理必须忽略样式表开头之外的任何@charset
规则。如果定义了几个@charset
规则,则只使用第一个。
@import
@import
允许用户从其他样式表导入样式规则。比如:
@import url("https://fonts.googleapis.com/css?family=Libre+Baskerville");
@import url("print.css") print;
@import url("tv.css") projection, tv;
@import 'custom.css';
@import "common.css" screen, projection;
@import url('landscape.css') screen and (orientation:landscape);
导入样式规则时,就好像文件的内容就在规则所在的位置一样。这些规则必须先于所有其他类型的规则,@charset
规则除外,否则@import
规则会不生效。
在实际项目中不建议使用
@import
来引用其他CSS样式文件。这样做不但请求多,还会造成阻塞。
@namespace
@namespace
规则对于很多同学而言会感到陌生。从词面上来了解,它是用来声明一个命名空间前缀,并将其与给定的命名空间关联起来。然后可以在命名空间限定的名称中使用此命名空间前缀。该规则对于将CSS应用到XHTML中特别有用,这样一来,XHTML元素就可以用作CSS中的选择器。可以使用定义的命名空间来限制泛型、类型和属性选择器,只选择该命名空间中的元素。@namespace
规则通常只在处理包含多个命名空间的文档时有用,比如包含内联SVG或MathML的HTML,或者包含多个词汇表的XML。
@namespace url(http://www.w3.org/1999/xhtml);
@namespace svg url(http://www.w3.org/2000/svg);
/* 和所有XHTML中的a元素匹配,因为XHTML是默认的命名空间 */
a {
color: red;
}
/* 和所有SVG中的a元素匹配 */
svg|a {
color: blue;
}
/* 同时匹配XHTML和SVG中的a元素 */
*|a {
color: orange;
}
使用@namespace
规则有几点要注意:
- 任何
@namespace
规则都必须遵循所有@charset
和@import
规则,并位于样式表中所有其他@
规则和样式声明之前 @namespace
规则可以用于定义样式表的默认命名空间。定义默认命名空间时,所有通用选择器和类型选择器(不包含属性选择器)仅应用于该命名空间中的元素@namespace
规则还可以用于定义命名空间的前缀。如果泛型、类型和属性选择器的前缀是命名空间的前缀,那么该选择器只在元素或属性的命名空间和名称匹配时才匹配
嵌套规则
嵌套规则和常规规则不同的是,在规则后面会带一个花括号{}
,括号中会嵌套一些样式规则:
@[关键词] {
/* 样式规则 */
}
CSS的嵌套规则主要有:
@font-face
CSS的@font-face
规则允许我们引用自定义的字体,该规则消除了依赖于计算机上安装的有限字体数量的需求。在使用自定义定体时,需要先使用该规则来声明:
@font-face {
[ font-family: <family-name>; ] ||
[ src: [ <url> [ format(<string>#) ]? | <font-face-name> ]#; ] ||
[ unicode-range: <urange>#; ] ||
[ font-variant: <font-variant>; ] ||
[ font-feature-settings: normal | <feature-tag-value>#; ] ||
[ font-stretch: <font-stretch>; ] ||
[ font-weight: <weight>; ] ||
[ font-style: <style>; ]
}
每个@font-face
规则为每个字体描述符(隐式或显式)指定一个值。规则中没有给出显式值的部分使用每个描述符列出的初始值。这些描述符仅适用于定义它们的@font-face
规则的上下文中,而不适用于文档语言元素。没有关于描述符应用于哪些元素或这些值是否由子元素继承的概念。当给定的描述符在给定的@font-face
规则中多次出现时,只使用最后一个描述符声明,并忽略该描述符所有先前声明。
另外,该规则允许选择与设计目标密切匹配的字体,而不是将字体选择限制为给定平台上可用的字体。一组字体描述符定义字体资源的位置,包括本地或外部的位置,以及单个外观的样式特征。多个@font-face
规则可用于构造具有多种字体的字体族。使用CSS字体匹配规则,用户代理可以选择性地只下载所需的字体。
在使用@font-face
时也有些细节需要注意:
- 作用域的限制。Web字体受到作用域的限制,因此
@font-face
规则中引用的字体资源必须与使用它们的页面位于相同的作用域,除非使用HTTP
访问控制来放宽这一限制 - 不考虑指定文件的
MIME
类型,因为没有为TrueType
、OpenType
和WOFF
字体定义MIME
类型 @font-face
不能在CSS选择器中声明
在项目中使用
@font-face
引用自定义定体涉及很多细节,有关于这方面的细节,后续我们将会花费一个章节来专门介绍。
@keyframes
@keyframes
规则主要用来声明一个动画,在嵌套的规则中指定了动画各个节点(帧)的样式规则。
@keyframes <keyframes-name> {
<keyframe-block-list>
}
@keyframes
只是声明了一个动画,如果没有被animation-name
属性调用的话,那么该规则中的样式并不会起任何的作用。另外要使用关键帧列表有效,它必须包含动画开始和结束状态的规则,即0%
(from
)和100%
(to
)。如果没有指定这两个时间偏移量,那么@keyframes
声明就会无效,解析器将会忽略它,并且不能用于animation
中。
如果我们通过JavaScript来操作@keyframes
中的规则,可以使用CSSOM中的CSSKeyframesRule
。
特别注意:在
@keyframes
规则中声明的样式规则会覆盖元素中的样式规则,哪怕是带有!important
加强权重的样式规则。
有关于@keyframes
更深入的介绍,我们将会放到CSS动画相关的章节来阐述。
@media
@media
规则是条件CSS中的一种,其条件是一个媒体查询。它由一个媒体查询列表(可以是空的)和一组规则组成。规则的条件是媒体查询的结果。
@media <media-query-list> {
<group-rule-body>
}
@supports
@supports
规则是条件CSS中的另一种,也是一条件组规则,其条件测试用户代理是否支持CSS属性/值对。它可以用于编写样式表,这些样式表在可用时使用新特性,但在不支持这些特性时将可以优雅地降级。
@supports <supports-condition> {
<group-rule-body>
}
@viewport
@viewport
规则事实上不是条件CSS中的一种。该规则在CSS中定义了一组嵌套的描述符,这些描述符主要用来控制移动设备上的viewport
设置。
@viewport {
<group-rule-body>
}
比如:
@viewport {
min-width: 640px;
max-width: 800px;
}
@page
@page
规则主要用于打印文档时候修改一些CSS属性。使用@page
我们只能改变部分CSS属性,例如间距属性margin
, 打印相关的orphans
, widows
, 以及page-break-*
, 其他CSS属性会被忽略。
@page <page-selector-list> {
<page-body>
}
@document
@document
规则指定应用于特定页面的样式的条件。该规则可以指定一个或多个匹配函数,如果其中任何一个函数应用于URL
,则该规则将对具有该URL
的文档生效。比如说,这个CSS文件被子站A
调用,和被子站C
调用,我们可以通过域名匹配来执行不同的CSS样式。这样,我们可以有效避免冲突,或者防止外链之类。
@document
/* 页面URL需要是 */
url(https://www.w3cplus.com/),
/* 页面URL的开头必须是... */
url-prefix(www.w3cplus.com/blog/),
/* 该域上的所有页面 */
domain(w3cplus.com),
/* 所有https协议页面 */
regexp("https:.*")
{
/* 开始样式 */
body {
color: #444;
}
}
@font-feature-values
@font-feature-values
规则主要用于给定字体家族的替代符号的索引定义命名值。它允许在font-variant-alternates
中使用一个公共名称来替换OpenType
中不可激活的特性,从而在使用多种字体时简化CSS。
@font-feature-values <family-name># {
<feature-value-block-list>
}
来看一个小示例:
/* 在Font One中激活 cool-style 风格的字体 */
@font-feature-values Font One {
@styleset {
cool-style: 12;
}
}
/* 在Font Two中激活 cool-style 风格的字体 */
@font-feature-values Font Two {
@styleset {
cool-style: 4;
}
}
/* 与字体无关 */
.cool-look {
font-variant-alternates: styleset(cool-style);
}
@counter-style
@counter-style
规则可以允许我们定义自定义的计数器的样式。计数器样式由@counter-style
规则中的描述符来指定,主要由system
、symbols
、additive-symbols
、negative
、prefiex
、suffix
和range
等组成。该规则的一般形式是:
@counter-style <counter-style-name> {
[ system: <counter-system>; ] ||
[ symbols: <counter-symbols>; ] ||
[ additive-symbols: <additive-symbols>; ] ||
[ negative: <negative-symbol>; ] ||
[ prefix: <prefix>; ] ||
[ suffix: <suffix>; ] ||
[ range: <range>; ] ||
[ pad: <padding>; ] ||
[ speak-as: <speak-as>; ] ||
[ fallback: <counter-style-name>; ]
}
具体使用的时候可以像下面这样:
@counter-style circled-alpha {
system: fixed;
symbols: Ⓐ Ⓑ Ⓒ;
suffix: " ";
}
li {
list-style: circled-alpha;
}
上面列出了CSS的@
规则,其中@charset
、@import
、@font-face
、@keyframes
、@media
、@supports
是我们常见或已在项目中有见过的@
规则;而@namespace
、@viewport
、@page
、@document
、@font-feature-values
和@counter-style
等规则是我们不怎么常见。
在众多CSS的@
规则中,@media
、@supports
和@viewport
又被称为是条件CSS。这也是我们这一章节中重点。那么接下来,我们详细的来聊聊这三个规则。