摘要:前言繼上篇魔法堂稍稍深入偽類選擇器記錄完偽類后,我自然而然要向偽元素伸出魔掌的啦。和的注意事項默認必須設置屬性,否則一切都是無用功默認,就是和的內容無法被用戶選中的偽元素和偽類結合使用形如。
前言
?繼上篇《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" | Null window.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 world" console.log(bg) // red console.log(txtDecoration) // underline玩透Content屬性
?到這里我們已經可以利用::before和::after實現tooltip等效果了,但其實更為強大的且更需花時間研究的才剛要開始呢!那就是Content屬性,不僅僅可以簡單直接地設置一個字符串作為偽元素的內容,它還具備一定限度的編程能力,就如上面attr(title)那樣,以其附屬元素的title特性作為content值。下面請允許我為大家介紹吧!
div::after{ content: "普通字符串"; content: attr(父元素的html屬性名稱); content: url(圖片、音頻、視頻等資源的url); /* 使用unicode字符集,采用4位16進制編碼 * 但不同的瀏覽器顯示存在差異,而且移動端識別度更差 */ content: "21e0"; /* content的多個值可以任意組合,各部分通過空格分隔 */ content: """ attr(title) """; /* 自增計數器,用于插入數字/字母/羅馬數字編號 * counter-reset: [?]+,必選,用于標識自增計數器的作用范圍, 為自定義名稱, 為起始編號默認為0。 * counter-increment: [ ?]+,用于標識計數器與實際關聯的范圍, 為counter-reset中的自定義名稱, 為步長默認為1。 * : 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( , ); /* 以父附屬元素的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類型值就能幫到我們。
.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 < children.length; ++i){ applyCSS(children[i]) } } else if (clz == "dt"){ resetCounter("dd", 0) incrementCounter("dt", 1) const elAsBefore = document.createElement("span") elAsBefore.textContent = counter("dt", "lower-roman") + " " mount.insertBefore(mount.firstChild) } else if (clz == "dd"){ incrementCounter("dd", 1) const elAsBefore = document.createElement("span") elAsBefore.textContent = counter("dd", "lower-roman") + " " mount.insertBefore(mount.firstChild) } }嵌套計數器
?對于多層嵌套計數器我們可以使用counters(
.ol .li .ol .li{a} .li{b} .li .ol .li{c}
.ol { counter-reset: ol; & .li::before { counter-increment: ol; content: counters(ol, "."); } }Content的限制
IE8+才支持Content屬性;
除了Opera9.5+中所有元素均支持外,其他瀏覽器僅能用于:before,:after內使用;
無法通過JS獲取Counter和Counters的運算結果。得到的就只能是"counter(mycouonter) " ""。
自定義引號?引號這個平時很少在意的符號,其實在不同的文化中使用的引號將不盡相同,如簡體中文地區使用的"",而日本則使用「」。那我們根據需求自定義引號呢?答案是肯定的。
?通過open-quote,close-quote,no-open-quote和no-close-quote即可實現,下面我們通過例子來理解。
?會根據父元素的lang屬性自動創建::before和::after來實現插入quotation marks。
p[lang=en]>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); }最后
?尊重原創,轉載請注明來自:https://www.cnblogs.com/fsjoh... 肥仔John^_^
參考http://www.wozhuye.com/compat...
https://dev.opera.com/article...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/116949.html
摘要:不耽誤表單提交數據雖然我們無法看到的元素,但當表單提交時依然會將隱藏的元素的值提交上去。讓元素在見面上不可視,但保留元素原來占有的位置。不過由于各瀏覽器實現效果均有出入,因此一般不會使用這個值。繼承父元素的值。 前言 ?還記得面試時被問起請說說display:none和visibility:hidden的區別嗎?是不是回答完display:none不占用原來的位置,而visibilit...
摘要:一鋪搞定一鋪清袋粵語的一鋪搞定其實就是一次完成全部工作的意思,上面關于的屬性,要是每次都逐個設置那要敲多少次鍵盤啊。。。語法粵語的一鋪清袋其實就是把之前的成果一次性歸零。 前言 ?當CSS3推出border-radius屬性時我們是那么欣喜若狂啊,一想到終于不用再添加額外元素來模擬圓角了,但發現border-radius還分水平半徑和垂直半徑,然后又發現border-top-left/...
摘要:魔法堂重新認識和魔法堂你一定誤解過的魔法堂就這個樣魔法堂說說那個被埋沒的志向深入細節后會發現中定位模式之間,和之間存在千絲萬縷的關系,必須以俯瞰的角度捋一下。當采用時,屬性的實際值會被重置為。由于和則需要通過來引入來提供盒子定位微調的功能。 前言 ?對于Box Model和Positioning Scheme中3種定位模式的細節,已經通過以下幾篇文章記錄了我對其的理解和思考。?《CSS...
摘要:時其寬度始終保持占滿寬度的態度。清除浮動就是為浮動影響的范圍劃邊界。那么可歸結為的父容器包裹所有子元素。注意屬性值不能為空白,否則無法清除浮動。 前言 ?定位系統中第一難理解就是Normal flow,而第二就非Float莫屬了,而Float難理解的原因有倆,1. 一開頭我們就用錯了;2. 它跟Normal flow靠得太近了。本文嘗試理清Float的特性和行為特征,若有紕漏望各位指正...
摘要:前言過去零零星星地了解和使用和等偽類偽元素選擇器,最近看書時發現這方面有所欠缺,于是決定稍微深入學習一下,以下為偽類部分的整理。偽類偽類選擇器實質上是讓設計師可以根據元素特定的狀態,設置不同的視覺效果。也就是符合以下選擇器的元素均支持狀態。 前言 ?過去零零星星地了解和使用:link、::after和content等偽類、偽元素選擇器,最近看書時發現這方面有所欠缺,于是決定稍微深入學習...
閱讀 1017·2023-04-25 22:27
閱讀 871·2021-11-22 14:56
閱讀 983·2021-11-11 16:54
閱讀 1678·2019-08-30 15:54
閱讀 3499·2019-08-30 13:20
閱讀 1212·2019-08-30 10:55
閱讀 2080·2019-08-26 13:34
閱讀 3280·2019-08-26 11:53