zoukankan      html  css  js  c++  java
  • 如何使用:before和:after伪元素?

    如果你有一直密切关注各个关于网页设计的博客,你大概会注意到,:before和:after伪元素已经在前端开发界得到越来越多的关注,并且是有很好的理由。特别是,有个博主(位于伦敦的一位开发者Nicolas Gallagher ),他对伪元素的应用尝试,给伪元素带来震撼的曝光机会。

    这84个GUI图标是用伪元素和语义化的HTML创建的。查看demo

    为了补充和加强本次的曝光(并利用发展趋势带来的好处),我整理了一份自认为比较完整的关于伪元素的“前世今生”。本文针对那些见识过伪元素一些应用的酷炫效果,想自己尝试做,但是要先了解这门CSS技术的读者。

    虽然CSS规则包括其它的伪元素,但是在本文,当我提到伪元素的时候,我特别指的是:before和:after这两个。

    伪元素是做什么的?

    伪元素所做的就像它的字面意思一样,它创造一个虚假的元素,并把它插到目标元素里面内容的之前和之后。

    基本语法

    :before和:after伪元素的代码很容易编写,这是个例子:

    1
    2
    3
    4
    5
    6
    7
    #example:before {
    content: "#";
    }

    #example:after {
    content: ".";
    }

    关于这个例子,要注意两点。

    第一,我们同时用:before和:after对同样的目标元素起作用。如它们都作用于id为example的元素上。

    第二,如果没有content属性(它是生成内容模型所定义的一部分),伪元素是无效的。也就是,如果要使用伪元素选择器来定义,那么就需要有content属性,否则你加任何其它的样式属性都是无意义的。

    在这个例子里,将会有伪内容,显示于id为example的元素的内容之前或/和之后。

    关于这个语法,要强调几点。

    可以给content属性留空,创建一个“零内容”的盒子。如下:

    1
    2
    3
    4
    5
    6
    #example:before {
       content: "";
       display: block;
       width: 100px;
       height: 100px;
    }

    但是,content这个标签是不能被移除的,否则,伪元素就不起作用了。这个“零内容”,需要给content属性一个空内容的双引号。

    你也许会注意到,:before和:after也可以写为::before和::after,其实这两者没有什么区别,只是用在CSS3中来区分伪类(单冒号)和伪元素(双冒号)。

    最后一点要说明的是,你可以应用一个伪元素,没有作用于任何的目标元素。如下:

    1
    2
    3
    :before {
       content: "#";
    }

    这个是有效的写法,但是一点用处也没有。

    插入内容有什么特性?

    如上描述,插入的内容在页面的源代码是看不到的。它只在CSS里面可见。

    同样,插入的内容默认的是一个内联(inline)元素。所以,要给插入元素一个height\padding\Margin等,需要先给元素定义为块状(block级)的元素。

    以下就开始简单描述如何定义伪元素。

    styles-pseudo-elements

    styles-pseudo-elements

    在这个例子里面,我对应用到插入元素的样式进行了高亮。伪元素就是这样的独特,即是可以在同样的声明块中同时定义插入内容和样式。

    另外,要知道的一点是,CSS的继承规则同样适用于插入元素。比如应用在body里面的字体、字体大小等这些样式,插入元素和其它元素一样,会继承这样的样式。

    同样,和其他元素一样,伪元素不继承父级如padding\margin这样的属性。

    插入在什么之前和之后?

    你或许会迷惑,插入元素是插入到哪里?你一看到:before和:after或许会认为就是在其所作用的目标元素的之前或之后。然而,事实并不是这样。

    要插入的内容,会被放置于目标元素的里面,作为它的一个子元素,并且它会显示在目标元素里面内容的之前或之后。

    要理解这点,看看这个代码:

    1
    2
    <p class=box>Other content.
    </p>

    样式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    p.box {
       width: 300px;
       border: solid 1px white;
       padding: 20px;
    }
    p.box:before {
       content: "#";
       border: solid 1px white;
       padding: 2px;
       margin: 0 10px 0 0;
    }

    在HTML里面,你所看到的是个段落(p),这个p有个class为box,其里面的内容是“other content”(就像你会在html的源代码里面所看到的)。在CSS里面,这个p被定义样式有width\padding\border。

    然后,再看看伪元素的定义。在这个例子里面,这个插入内容是放到到段落(p)里面的内容之前的。被定义的样式有border\padding\margin。

    看看这个图就明白了。

    Before Or After What?

    Before Or After What?

    外框是段落,内容插到段落里面内容的前面而不是到段落的前面。

    插入非文本的内容

    我之前提过可以给content属性设为空字符,或者一个文本内容。其实你还有其它的两种选择,就是给它加特定的内容,如下:

    第一,可以包含一个URL指向一个图片,在这里,你可以定义一个Data URI,就像你想定义一个背景图片一样。

    1
    2
    3
    p:before {
       content: url(image.jpg);
    }

    第二,你还有另外一个选择就是加上attr(x)这种形式的函数。根据定义,这个函数为选择器对象返回一个由属性X的值生成的字符串

    1
    2
    3
    a:after {
       content: attr(href);
    }

    attr()函数取得所定义的属性的值,并把它作为文本变成可以插入的伪内容。

    浏览器支持情况

    像对待其它的一些前端技术一样,开发者们关注的重点之一就是浏览器支持啦。在这点上,看似问题还没那么大。:before和:after的浏览器支持情况如下:

    Chrome 2+,
    Firefox 3.5+ (3.0有部分支持),
    Safari 1.3+,
    Opera 9.2+,
    IE8+ (尚有些小bug),
    大部分的移动设备浏览器。

    这里唯一真正的问题(毫无疑问)就是完全不支持的IE6和IE7。所以,如果你的目标用户是网页开发者群(或者其它较少使用IE浏览器的群体),那么你就大胆用吧。

    另外,说到伪元素的安全性,幸运的是,缺乏一个伪元素并不会引发什么功能上的问题。伪元素大多数是用来生成修饰性的内容,在不支持伪元素的浏览器里面,不会引发重大问题。所以,如果你的目标群体是IE浏览器使用者占大多数的,在某个程度上,你依然可以使用这个属性。

    几个提醒

    如前面所述,伪元素的内容不会在DOM结构中显示。这些元素不是真正的元素。它们在大多数的辅助设备中是不可访问的。所以对网页的使用性和可用性很关键的内容,要尽量避免使用伪元素来生成。

    另外,像Firebug这样的开发者工具,并不会显示由伪元素生成的内容。所以,如果滥用伪元素,会引发网页调试过程效率低下和网页维护不方便等问题。

    ([更新]在评论里提及的两点:你可以使用chrome的开发者工具来查看关于伪元素的样式,但这个元素不显示在DOM里面。还有一点,Firebug1.8已经添加了对伪元素的支持。)

  • 相关阅读:
    手把手教你封装属于自己的分段滚动视图(上)
    从 setNeedsLayout 说起
    cocoapods使用指南
    神奇的 BlocksKit(1):源码分析(下)
    Web应用开发中的几个问题
    Jquery Ajax自定义无刷新提交表单Form
    解耦HTML、CSS和JavaScript
    通过预加载器提升网页加载速度
    巧妙使用CSS创建可以打印的页面
    有用的JavaScript开发小建议
  • 原文地址:https://www.cnblogs.com/guozhe/p/2376992.html
Copyright © 2011-2022 走看看