tft每日頭條

 > 生活

 > css完全使用詳解

css完全使用詳解

生活 更新时间:2024-12-18 23:14:50

css完全使用詳解(CSS進階知識掃盲)1

CSS其實遠比我們想象的更複雜、他的任意一個點拿出來可能都可以寫出一篇篇幅不小的文章,往往就能見微知著。所以CSS不僅僅局限于他的名字,層疊樣式表,更像是一個世界,一個網頁中必不可少的重要組成。

圍繞着上面的CSS體系,當然上面的圖可能還不夠全面,但是也能說明CSS的主要構成了。我們簡單說下可能其中一些不為人知的“隐藏屬性”,先留下一個大體的印象,拓展自己的CSS學習體系,後續才能慢慢深入其中。

本篇也是筆者結合《CSS世界》、《CSS權威指南》上下冊、《CSS揭秘》後,總結的一些平時自己忽略的,或者說根本就不了解的地方,實地敲代碼在浏覽器中實踐而來。

文本排版

先來說字體,聲明字體很簡單,font-family聲明就完事了,但是有時我們可能會看到這樣的聲明:

h1 { font-family: -apple-system,system-ui,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Arial; }

這麼一大串到底是幾個意思呢,其實隻要知道這個font-faimly屬性中包含兩種類型值就能明白了,一種是字體名稱,一種叫做字體族。顧名思義,字體族就是所有字體的一個分類,在CSS世界中一般有以下幾種字體族:

  • 襯線字體。指的就是筆畫開始、結束處有額外的裝飾,并且筆畫粗細不同。
  • 無襯線字體。就是沒有裝飾,筆畫粗細相同。
  • 等寬字體。字形的寬度都相等。
  • 草書字體。模仿人類手寫的字體。
  • 奇幻字體。沒有歸于以上四類字體的其他字體。

所以諸如上面的聲明中的sans-serif、Helvetica指的是字體族,前者是襯線字體,後者是無襯線字體。那麼這其中的意思就很明确了,如果系統中有前面的字體,那就使用前面的字體,如果沒有的話,嘗試使用後面的襯線字體,如果沒有,則繼續往後面的聲明中尋找可用字體。

我自己是一名從事了多年開發的web前端老程序員,目前辭職在做自己的web前端私人定制課程,今年我花了一個月整理了一份最适合2020年學習的web前端學習幹貨,各種框架都有整理,送給每一位前端小夥伴,想要獲取的可以關注我的頭條号并在後台私信我:前端,即可免費獲取。

繼承

一般文本類的屬性都是可以繼承的,例如color,font-size,font-family等。

與之對應有些屬性時不能繼承的,例如border,padding,margin,background等。其實也很好理解這些屬性為何不能繼承,因為一旦這些屬性可以繼承,那麼會影響到了整個布局,例如,我們在父元素上加個邊框,但是其子元素,後代元素都繼承了邊框,那就不得不去寫更多的代碼來消除繼承的影響,這樣的結果肯定不是CSS設計的初衷。

line-height

首先需要明确的是line-height是作用在行内元素或者是行内塊級元素上的,我們聲明在塊級框上的line-height實際也是作用于塊級框中的内容的,因此經常可能看到會這麼使用:

div { line-height: 100px; font-size: 20px; }

于是看到了這樣的效果:

css完全使用詳解(CSS進階知識掃盲)2

可能下意識的就以為line-height就是作用在塊級盒子上的。實際上呢,他是作用于塊級盒子中的文本上的,如果去除 div 中的文本就會看到其高度就沒有 100px 了,文本也是行内元素,這點想必都是清楚的。

另外則是line-height的值可以為數值、百分比以及長度值,長度值也包括例如em這樣的相對單位。當值不是具體長度值的時候,也就是為數值或者是百分比的時候,相對計算的是其font-size屬性,如果font-size的值為16px,則line-height: 1.5的值就為16 * 1.5,就是24px,百分比值的時候也是這麼計算的,不過需要注意的是,百分比值在繼承的時候,會相對當前的font-size來計算,也就是說如果父子元素的font-size值不同,那麼line-height計算出來的值也是不一樣的。如果數值的話則沒有這個問題,始終都是相對于數值來計算的。

另外經常會看到這樣的用法,讓文字垂直居中:

div { line-height: 100px; height: 100px; }

實際就是隻需要line-height就能實現垂直居中,和下面的高度沒有什麼關系,而為什麼這麼設置可以垂直居中呢?這就要來看line-height設置的屬性究竟如何作用的。還是來看上面的圖,當設置line-height的時候,div 的高度就被設置為了 100px,但是這個值是這麼分配的,用100px - 1em得到的值分成兩份,分别加到字體的上部分和下部分的區域,這樣字體就平分上下區域,形成一種垂直居中的情況,1em就是字體的大小。當然這裡其實是近似的垂直,因為不同字體實際占據的1em的大小是不一樣的,因此分配上下半行高的時候,會有存在偏差,除此之外,下面說的一種屬性也會影響到這種情況。

strut(支柱)

這是個在CSS中看不見,但卻無處不在,有些書中将之稱為空白節點。他是支撐内聯文本存在的支柱。可以通過這種方法來看到他:

.line1 { line-height: 0; border: 1px solid red; font-size: 20px; }

css完全使用詳解(CSS進階知識掃盲)3

根據上面學到的關于line-height的知識,當設置為 0 時,文本行高為 0,那麼外面的包含塊,也就是父元素理論上也應該是 0,但是我們發現這裡的高度是 2,其實這就是所謂支柱的存在了,存在于每個内聯盒子的前面,先記住他,下面會用到。

vertical-align

<div class="line3"> <img src="../../../assets/css_mindgraphy.png" width="100"> </div>

于是我們發現圖片的下面出現了一點間隙,針對這種情況,vertical-align就可以出場了,隻要将vertical-align設置為除默認值之外的位置值就可以了。

.line3 > img { vertical-align: top; }

css完全使用詳解(CSS進階知識掃盲)4

可以看到圖片下面的間隙沒有了,當然這裡除了使用vertical-align以外,還可以設置line-height: 0、font-size: 0都能去解決這個問題。原因就在于上面說到strut, 圖片是内聯元素,因此其也存在一個看不見的文本節點,相當于這樣

css完全使用詳解(CSS進階知識掃盲)5

噢~這樣就知道應該是默認的行高起的作用,對了,還有vertical-align的作用,因為其默認值是baseline也就是基線對齊,可以看到圖片底部可以文本的底部對齊了,那麼當設置vertical-align: top、line-height: 0或者font-size: 0,前者相當于将基線對齊變成了頂部對齊,自然不會出現下面的間隙了,後兩者則是将行高去掉,另外則是隐藏了文本大小,那麼自然間隙也都不存在了。

除此之外,我們還有一種方法能夠解決這個問題,就是直接改變圖片的display值,将其設置為塊級元素,那麼上面所說的空白節點strut自然就不存在了,也能解決這個問題。不過這裡改變了display值,可能會影響到布局,所以還是推薦使用上面幾種辦法。

vertical-align除了設置位置值,也就是除了top,middle,bottom這些關鍵字,還可以設置具體的數值,百分數,也可以設置負數值,負數值其實就是向下偏移指定的值,百分數就是相對line-height的值設定。

CSS的全局關鍵字

全局關鍵字就是所有的屬性都能使用的屬性值,總共是有三個inherit,initial,unset。這些關鍵字是CSS3才出現的,在IE11以前和Opera Mini是不支持的。

inherit 就是打破了上面的繼承限制,隻要屬性值設置為 inherit,那麼就能從父元素繼承這個屬性。

initial 則是将屬性設置為初始值,主要是用于那些沒有預定義的初始值的屬性,例如 color 屬性,默認是取決于用戶代理,就是用戶設置的某個顔色值,而設置為 initial 則會将字體顔色變成黑色。

unset 則是前兩個關鍵字的替代,就是對于繼承的屬性來說,unset 就表示 inherit,而對于不繼承的屬性則表示 initial。

還有一個特殊屬性 all 就隻支持這三個關鍵字。all 表示除了 direction 和 unicode-bidi 之外的所有的屬性。因此如果設置了 all: inherit 則表示除了上述兩個屬性外,其他所有的CSS屬性都從其父元素繼承。

選擇符

這裡選擇符,就是平常所說的選擇器。選擇器的種類非常多,但大多就是上面列舉的幾種,除此之外,還有一些平時可能忽略的通用選擇符:

* { box-sizing: border-box; }

看起來非常的簡單,但是濫用他會造成一些意向不到的結果。首頁就是他會給所有的元素都添加上對應的屬性,即使這個元素壓根就用不到這個屬性,這樣就造成了一定的性能浪費,另外一點則是非常容易忽視的地方在于他的優先級,也是我們說的特指度,通用選擇器的特指度為0,結合上面的繼承來說,繼承是沒有特指度的,因此你如果用了通用選擇符,然後指望元素通過繼承獲得父元素的繼承屬性,卻會發現不起作用。來看個

* { color: green; } div#page { color: black; }

<div id="page"> 我是CSS世界的小<em>菜雞</em> </div>

css完全使用詳解(CSS進階知識掃盲)6

很明顯,最終看到的菜雞是綠色的。因此這也是非常容易讓人困惑的地方,所以推薦是盡量不要過度使用

盒模型塊級盒子

我們都知道BFC、IFC這樣的名詞,也知道他們的定義,比如BFC,就是塊級格式化上下文,表示塊級盒子定義的區域,擁有自己的渲染規則,并且盒子之間不會相互影響等。但是具體包含了哪些渲染規則以及如何渲染可能知道的比較模糊,這裡也是說下容易忽略的地方。

在說這些渲染規則之前,先來說下一些概念,理解了這些概念,才能更好的理解盒模型。

  • 塊級框,div 等塊級元素生成的框體就是塊級框
  • 行内框,同理,span 這樣的行内元素生成的框體就是行内框
  • 行内塊級框,即 display: inline-block的行内塊級元素生成的框體就是行内塊級框。
  • 容納快,就是包含當前元素的父級框體,簡單來說,塊級元素的容納塊就是塊級框,行内元素的容納塊就是行内框,當然也有可能是塊級框。

而BFC、IFC這樣的格式化上下文就是在容納塊中定義的。先從橫向布局開始說起,看下面的

.line8 > .child1 { width: auto; margin-left: 50px; margin-right: 20px; } .line8 > .child2 { width: 300px; margin-left: auto; margin-right: 150px; } .line8 > .child3 { width: 300px; margin-left: auto; margin-right: auto; } .line8 > .child4 { width: 300px; margin-left: auto; margin-right: -200px; }

得到的結果如下:

css完全使用詳解(CSS進階知識掃盲)7

從中也不難看出:

  1. 橫向布局時,外邊距不會發生折疊
  2. 包含一個auto值時,用整個容納塊的寬度減去設置的寬度,剩下的寬度分配給設置給auto的元素,因為外邊距可以是負值,因此對于負值而言,也同樣适用上述規則,可以看到第四個div就是負值外邊距的情況。
  3. 包含兩個auto值時,就是将剩餘距離平分為兩份,每個auto值各占一半,這也是我們平時經常使用margin: 0 auto;居中的原理是一樣的。

需要注意的時,這裡關于塊級盒子的一些屬性,如外邊距,内邊距,邊框,輪廓等,除了外邊距可以設置為負值,其他設置為負值的時候,浏覽器會忽略掉整條規則,并且auto值也隻有寬高、外邊距以及輪廓屬性可以設置,其他設置auto值都是無效的,會被浏覽器忽略掉。

再說縱向布局會産生margin折疊,折疊的規則就是取大值,也就是對于兩個縱向布局的元素,margin-bottom和margin-top發生重疊,那麼誰的值大就取誰的值作為折疊後的外邊距的值。如果margin為負值的話,則取其絕對值大的那個值為折疊後的邊距,如下所示:

.line8 > .child5 { margin-bottom: 10px; } .line8 > .child6 { margin-top: -50px; }

css完全使用詳解(CSS進階知識掃盲)8

行内盒子

行内元素分為兩個,一個是非置換元素,一個是置換元素。這兩個元素在布局上也是有所不同的。

老規矩,先來說些概念:

  • 匿名文本,就是不包含标簽的文本,比如之前例子中我們給 span 元素前面加上了x-height這樣的文本就是匿名文本。
  • 字體框,顧名思義,就是font-size屬性決定的字體占據的框
  • 行距,就是line-height屬性設置的值減去font-size的值就是行高,除以2分配和字體上下兩端,則是半行距。
  • 行内框,就是行距加上内容區,也就是字體文本的區域,對行内非置換元素來說,就是line-height設置的值,對于置換元素來說,就是他的内容區。
  • 行框,經過一行内所有的行内框的最高點到一行内行内框的最低點之間的距離。

下面是他的示意圖

css完全使用詳解(CSS進階知識掃盲)9

  1. 非置換元素 結合上面的概念,來看個

.line10 { border: 1px solid red; } .line10 > p { font-size: 12px; line-height: 12px; } .line10 > p::first-line { border: 1px solid #ccc; background: #f2f2f2; } .line10 > p > strong { font-size: 24px; }

得到如下的顯示:

css完全使用詳解(CSS進階知識掃盲)10

可以看出來,加粗文本那段明顯超出了内容區,即便如此,文本也都還是默認對齊的,下面改變一下強調文本,添加一些樣式:

.line10 > p > em { padding: 20px; } .line10 > p > em { border: 20px solid blue; } .line10 > p > em { margin: 20px; }

css完全使用詳解(CSS進階知識掃盲)11

css完全使用詳解(CSS進階知識掃盲)12

css完全使用詳解(CSS進階知識掃盲)13

這裡 1 像素的藍色邊框是為了能夠看清強調文本所占據的範圍,通過這幾個結果對比,我們能看到,對于行内元素來說,無論是padding、border、還是margin對于行框來說完全沒有影響,也就是縱向距離保持不變,不過文本的左右還是會産生了間距,同理對于負margin來說,行框大小依然不變,不過左右會産生重疊。

css完全使用詳解(CSS進階知識掃盲)14

那麼既然行内元素縱向布局不受這些組成盒模型的屬性所影響,那麼到底什麼屬性影響行框大小呢,試試這個屬性:

.line10 > p > strong { font-size: 24px; vertical-align: 4px; }

css完全使用詳解(CSS進階知識掃盲)15

可以看到行框的高度比之前多出了4px,這也就是說vertical-align會影響到縱向布局。在前一部分的時候說過,vertical-align計算是會受到line-height影響的,并且對于下面說到的置換元素而言,line-height就是置換元素的内容區,所以我們知道,影響行内元素縱向布局的主要屬性就是這兩個了。

  1. 置換元素 置換元素的布局則又不同了,還是看個

.line11 { font-size: 15px; line-height: 18px; border: 1px solid red; } .line11 > img { height: 30px; /* margin: 20px; */ /* border: 0; */ /* padding: 0; */ }

css完全使用詳解(CSS進階知識掃盲)16

展示的結果其實和我們上面介紹圖片間隙的例子是一樣的,現在來看看對布局的影響,上面注釋的三個屬性,一個一個嘗試一下,會發現都會對行内框的高度有影響,這是和非置換元素完全不同的表現。這裡就不展示具體的結果了,可以自己去嘗試看看。

  1. 行内塊級元素 這裡将行内塊級元素放在這裡是因為行内塊級元素可以看做是置換元素,因此他們的布局影響是一樣的,盒模型的屬性都會對上下左右産生影響,因此不再贅述。

css完全使用詳解(CSS進階知識掃盲)17

原文鍊接:https://juejin.im/post/6866789805615742989

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved