现代 CSS

图解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类型,因为没有为TrueTypeOpenTypeWOFF字体定义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规则中的描述符来指定,主要由systemsymbolsadditive-symbolsnegativeprefiexsuffixrange等组成。该规则的一般形式是:

@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。这也是我们这一章节中重点。那么接下来,我们详细的来聊聊这三个规则。

条件CSS之

剩余80%内容付费后可查看
返回顶部