继上篇深入了解css伪类选择器的用法(代码示例)记录完伪类后,我自然而然要向伪元素伸出“魔掌”的啦。本文讲讲述伪元素以及功能强大的contet属性,让我们可以通过伪元素更好地实现更多的可能!
初识伪元素 说起伪元素我第一想到的莫过于::before和::after这两个了,它俩其实就是在其附属的选择器命中的元素上插入第一个子节点和追加最后一个子节点。那这时我不禁地想问:“直接添加两个class为.before和.after不是一样的吗?”
其实使用伪元素::before和::after以下两个好处:
html的代码量减少,对seo有帮助;
提高javascript查询元素的效率。
那为什么会这两好处呢?原因就是伪元素并不存在于dom中,而是位于cssom,html代码和dom tree中均没有它的身影,量少了自然效率有所提升。但这也引入一个问题——我们没办法通过javascript完全操控伪元素(我将在下面一节为大家讲述)
一大波伪元素来了除了::before和::after外,别漏了以下的哦!
:first-line:只能用于块级元素。用于设置附属元素的第一个行内容的样式。可用的css属性为font,color,background,word-spacing,letter-spacing,text-decoration,vertical-align,text-transform,line-height,clear。
:first-letter:只能用于块级元素。用于设置附属元素的第一个字母的样式。可用的css属性为font,color,background,marin,padding,border,text-decoration,vertical-align,text-transform,line-height,float,clear。
::selection:匹配选中部分的内容。可用的css属性为background,color。
有没有发现有的伪元素前缀是:有的却是::呢?::是css3的写法,其实除了::selection外,其他伪元素既两种前缀都是可以的,为兼容性可选择使用:,为容易区分伪元素和伪类则使用::,但我还是建议使用::来提高可读性,兼容性就让postcss等工具帮我们处理就好了。
::before和::after的注意事项
默认display: inline;
必须设置content属性,否则一切都是无用功;
默认user-select: none,就是::before和::after的内容无法被用户选中的;
伪元素和伪类结合使用形如:.target:hover::after。
javascript操作伪元素 上文提到由于伪元素仅位于cssom中,因此我们仅能通过操作cssom api——window.getcomputedstyle来读取伪元素的样式信息,注意:我们能做的就是读取,无法设置的哦!
{- window.getcomputedstyle的类型 -}data pseudoelement = :before | ::before | :after | ::after | :first-line | ::first-line | :first-letter | ::first-letter | ::selection | :backdrop | ::backdrop | nullwindow.getcomputedstyle :: htmlelement -> pesudoelement -> cssstyledeclaration{- cssstyledeclaration实例的方法 -}data csspropertyname = float | backround-color | ......data dompropertyname = cssfloat | stylefloat | backgroundcolor | ......-- ie9+的方法cssstyledeclaration#getpropertyvalue :: csspropertyname -> *-- ie6~8的方法cssstyledeclaration#getattribute :: csspropertyname -> *-- 键值对方式获取cssstyledeclaration#[dompropertyname] -> *
示例:
.target[title=hello world]::after{ display: inline-block; content: attr(title); background: red; text-decoration: underline;}const eltarget = document.queryselector(.target)const computedstyle = window.getcomputedstyle(eltarget, ::after)const content = computedstyle.getpropertyvalue(content)const bg = computedstyle.getattribute(backgroundcolor)const txtdecoration = computedstyle[text-decoration]console.log(content) // hello worldconsole.log(bg) // redconsole.log(txtdecoration) // underline
玩透content属性 到这里我们已经可以利用::before和::after实现tooltip等效果了,但其实更为强大的且更需花时间研究的才刚要开始呢!那就是content属性,不仅仅可以简单直接地设置一个字符串作为伪元素的内容,它还具备一定限度的编程能力,就如上面attr(title)那样,以其附属元素的title特性作为content值。下面请允许我为大家介绍吧!
p::after{ content: 普通字符串; content: attr(父元素的html属性名称); content: url(图片、音频、视频等资源的url); /* 使用unicode字符集,采用4位16进制编码 * 但不同的浏览器显示存在差异,而且移动端识别度更差 */ content: \21e0; /* content的多个值可以任意组合,各部分通过空格分隔 */ content: ' attr(title) '; /* 自增计数器,用于插入数字/字母/罗马数字编号 * counter-reset: [<identifier> <integer>?]+,必选,用于标识自增计数器的作用范围,<identifier>为自定义名称,<integer>为起始编号默认为0。 * counter-increment: [<identifier> <integer>?]+,用于标识计数器与实际关联的范围,<identifier>为counter-reset中的自定义名称,<integer>为步长默认为1。 * <list-style-type>: disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | lower-alpha | upper-alpha */ content: counter(<identifier>, <list-style-type>); /* 以父附属元素的qutoes值作为content的值 */ content: open-quote | close-quote | no-open-quote | no-close-quote;}
换行符:html实体为 ,css为\a,js为\ua。
可以看到content接受6种类型,和一种组合方式。其中最后两种比较复杂,我们后面逐一说明。
自定义计数器 html为我们提供ul或ol和li来实现列表,但如果我们希望实现更为可性化的列表,那么该如何处理呢?content属性的counter类型值就能帮到我们。
<!-- html 部分-->.dl .dt{chapter1} .dd{text11} .dd{text12} .dt{chapter2} .dd{text21} /* css部分 */.dl { counter-reset: dt 0; /* 表示解析到.dl时,重置dt计数器为0 */ & .dt { counter-reset: dd 0; /* 表示解析到.dt时,重置dd计数器为0 */ &::before{ counter-increment: dt 1; /* 表示解析到.dt时,dt计数器自增1 */ content: counter(dt, lower-roman) ; } } & .dd::before { counter-increment: dd 1; /* 表示解析到.dd时,dd计数器自增1 */ content: counter(dd) ; }}
通过counter-reset来定义和重置计数器,通过counter-increment来增加计数器的值,然后通过counter来决定使用哪个计数器,并指定使用哪种样式。
如果用javascript来表示应该是这样的
const globalcounters = {__temp:{}}function resetcounter(name, value){ globalcounters[name] = value}function incrementcounter(name, step){ const oval = globalcounters[name] if (oval){ globalcounters[name] = oval + step } else{ globalcounters.__temp[name] = step }}function counter(name, style){ return globalcounters[name] || globalcounters.__temp[name]}function applycss(mount){ const clz = mount.classname if (clz == dl){ resetcounter(dt, 0) const children = mount.children for (let i = 0; i q{英语}p[lang=no]>q{挪威语}p[lang=zh]>q{汉语}p[lang=en]>q.no-quote{英语2}div[lang=no]>.quote{挪威语2}
css片段:
p[lang=en] > q{ quotes: <!--" "-->; /* 定义引号 */}p[lang=en] > q.no-quote::before{ content: no-open-quote; /*或者 content: none;*/}div[lang=no] > .quote { quotes: <<-" "->>;}div[lang=no] > .quote::before { content: open-quote;}div[lang=no] > .quote::after { content: close-quote;}
示例分割线p.sep{or}
.sep { position: relative; text-align: center; &::before, &::after { content: ; box-sizing: border-box; height: 1px; width: 50%; border-left: 3em solid transparent; border-right: 3em solid transparent; position: absolute; top: 50%; } &::before { left: 0; } &::after { right: 0; }}
只读效果(通过遮罩原来的元素实现).input-group { position: relative; &.readonly::before { content: ; position: absolute; width: 100%; height: 100%; top: 0; left: 0; }}
计数器.selections>input[type=checkbox]{option1}+input[type=checkbox]{option2}.selection-count
.selections{ counter-reset: selection-count; & input:checked { counter-increment: selection-count; }}.selection-count::before { content: counter(selection-count);}
以上就是css伪元素和content属性的详细分析(代码示例)的详细内容。
