我腦中飄來飄去的 CSS 魔幻屬性

2021-03-06 前端大全

(點擊上方公眾號,可快速關注)

作者:Denzel

https://segmentfault.com/a/1190000012417553

最近看到一篇20個CSS高級技巧匯總的匯總,感觸很深,不過我想,與技巧相比,有些常見css布局難題,有時候更加讓我們的日常開發變得躊躇沮喪吧。

在寫這一篇文章之前,自己還寫過一篇:我所不注意的那些CSS冷知識,但卻阻止了我做項目的速度,如果你看了,我相信你也會受益的。

為什麼此處li標籤內的p元素看起來獨自撐開了一行

這是我在segmentfault上看到的一個問題,以前自己遇到過,所以就很熱情洋溢的去回答了一下,難道遇到個自己會的,示例代碼是這樣的:

   li{

       display: inline-block;

       text-align: center;

   }

   .left,.center,.right{

       width:300px;

       height:300px;

   }

   .left{

       background-color: #999;

   }

   .center{

       background-color: #ccc;

   }

   .right{

       background-color: #eee;

   }  

   HTML:

   <ul>

       <li class="left">

           <p style="display: inline-block;">1</p>  

       </li>

       <li class="center"></li>

       <li class="right"></li>

   </ul>  

大概就是這樣子,其實文和圖有點不對應,代碼中第一個模塊他只寫了一個「1」,我為了現象更加明顯,且好說明為什麼,就打了一大段文字,現在我們來說說為什麼。先來一張圖,看懂vertical-align的幾個屬性,順便帶上圖片出處,文章講得還可以,理解這張圖片,後面就好理解了。

inline-block的vertical-align 屬性默認是baseline對齊(深入理解的送福利),也就是英文文字小寫字母a,b,c這類字母底部的那條線,因為這些是外國人發明的,所以以英文字母才有針對性。

inline-block擁有vertical-align屬性,其默認是基線對齊的,所以這三個inline-box需要基線對齊,而其基準線就是正常流中最後一個line box的基線,如果這個元素是空的,沒有內容,那麼這個基線就是最後這個元素的margin-bottom線;如果這個元素不為空,那麼這個元素的基線就是元素裡面內容最後一行文字的基線;所以我們一個一個來套,發現這三個li元素在一行,第一個有文字,其基線為文字底部;最後一個沒有文字,其基線為margin-bottom線,考試要考,劃重點,可以自己為元素設置margin-bottom試試,這就會造成第一個和二,三個錯行的感覺,其實他兩是為了基線對齊,所以多敲幾十個文字就能明顯看出其差別。

所以最簡單的解決方案就是為li添加vertical-align: 屬性不為baseline,氣不氣,改變其縱向的對齊方式的默認屬性;為啥非弄個折騰人勒。關於vertical-align,如果還想做這方面的深入了解,可以看看張大俠的分析

img圖片撐不滿整個div,有空隙

直接上圖更直觀(箭頭所指):

相關css和html:

   <style>

       body,div{margin: 0;padding: 0;}

       .test{

           background-color: yellowgreen;

       }

       img{

           width:260px;

           height:260px;

       }

   </style>

   <body>

   <div class="test">

       <img width="130" height="130" src="https://user-gold-cdn.xitu.io/2017/12/10/160409cc0f090c6f">

   </div>

</body>

其實這個問題,如果你單單這樣看,和我一樣涉世未深的話,是一眼看不出答案的,但是如果你在圖片後面多敲兩個文字,你就會發現,和上個問題,這又是一個有關於vertical-align屬性相關的問題。

   <div class="test">

       <img width="130" height="130" src="https://user-gold-cdn.xitu.io/2017/12/10/160409cc0f090c6f"><span>abcd看文字</span>

   </div>  

讓人恍然大悟的效果圖:

這下你應該就懂了,下面的空隙的距離實際上等與1個line-height的底邊與baseline之間的間距。仔細觀察,圖片的底邊是和a的下邊緣是在一條水平線上的,而不是和『看』字下邊緣一條水平線上的。所以為什麼上面說這又是一個和vertical-align屬性相關的問題。先說解決方案。

針對於父元素div

設置行高足夠小,比如.test{line-height:0},至於這麼小嗎,其實高度小於top線和baseline線之間的距離的距離就行了,至於到底多小,這和font-size是相關的,其目的就是沒有多餘的高度拿來給baseline下面的空間用(個人理解);

上面說了設置line-height最小和font-size相關,所以,還有的方法,就是直接設置字體大小為0,.test{font-size:0;},道理你應該懂;

針對於圖片div

上面說了這是一個和vertical-align屬性相關的問題,所以設置vertical-align屬性不為baseline也可以解決,比如img{vertical-align:top;},當然也可以是數字,比如img{vertical-align:-10px;},這個數值絕對不是正值,其數值應該是大於bottom線和line-height的底邊距離的;

最後一種,就是vertical-align是一個對塊狀元素無效的屬性,僅針對於內聯元素有效的,當然inline-block也有效.所以img{display:block;}也可以解決問題。

也許到這裡,你和我一樣,有疑惑,為什麼vertical-align是一個對塊狀元素無效的屬性,設置img為塊級元素,其和div就可以完美在一起,而一個內聯元素放在塊狀元素裡,就非得有隔閡。

開始,我也是有這個疑問的,個人理解就是塊狀元素裡面裝了一個內聯元素,如果塊狀沒有顯示的設置高度,其高度是由裡面的最高的lineboxes組成的,這個div其實就是有兩個lineboxes組成,圖片linebox和,其實還有一個linebox就是div自身的innerText(''),這不過這裡內容為空,如果你把span去掉,你就更能理解這個隱身的linebox,所以就像是兩個內聯元素在一起,需要baseline對齊。

所以網上有人說設置img{font-size:0;},是非常錯誤的,img元素很特殊,他不但是內聯元素,他還是一個置換元素(下面會講),它的高度不是文字內容撐開的,是其置換的圖片高度撐開的,所以設置font-size是無效的。

浮動不按想要的方式浮

像上圖那樣的形式,盒子由導航欄和右側一個搜索框或者登錄名什麼的一起組成,這也是我們常用浮動的方式來解決這樣的布局。
說浮動前,先說三點概念:

浮動最初出現的意義是為了解決文字環繞圖片這種在雜誌報紙中常會出現的布局樣式; (看下圖)

浮動與絕對定位能實現相同的效果,但的區別是,浮動未脫離正常文檔流,但絕對定位脫離了正常文檔流;

浮動能帶來靈活的布局,但同時也帶來了父元素高度塌陷的缺點(看下圖),所以清除浮動是使用浮動前的必修課,後面會說到;

現在看一下高度塌陷相關的代碼:

       <div class="test">

       <img width="130" height="130" src="https://user-gold-cdn.xitu.io/2017/12/10/160409cc0f090c6f">

       1.浮動最初出現的意義是為了解決文字環繞圖片這種在雜誌報紙中常會出現的布局樣式;<br>

       2.浮動與絕對定位能實現相同的效果,但的區別是,浮動未脫離正常文檔流,但絕對定位脫離了正常文檔流;<br>

       3.浮動能帶來靈活的布局,但同時也帶來了父元素高度塌陷的缺點,所以清除浮動是使用浮動前的必修課,後面會說到;<br>

       <br>

       </div>

       <div class="blank"></div>

       <div>

       <div class="box">

           <span class="dot"></span>

           我是下面一個div的文字。

       </div>

           <div class="blank"></div>

       <div class="box">

           <span class="dot"></span>

           我是再下面一個div的文字。。

       </div>

           <input  width="260" value="輸入一段文字"/>

       </div>

       .test {

       background-color: yellowgreen;

       font-size: 18px;

       vertical-align: top;

       }

       .test span {

           background-color: bisque;

       }

       .blank {

           line-height: 20px;

           height: 20px;

       }

       img {

           width: 260px;

           height: 260px;

           float: left;

       }

       input {

           border: 1px solid red;

           height: 24px;

           margin-left: 30px;

       }

       .box {

           background: black;

           color: white;

           padding-left: 20px;

           line-height: 10px;

       }

       .box .dot {

           display: inline-block;

           width: 4px;

           height: 4px;

           background: white;

           vertical-align: bottom;

       }

圖片一中,實現了文字環繞圖片那種想要的效果,並且後面的元素沒有上移錯位,其原因是上面說過的,如果塊狀元素沒有顯示的設置高度,其高度由其元素內的最高的linebox決定,所以第一張圖片div的高度是比img高度高的,因為我重要的事情說了三遍,文字夠多。而第二張圖片,div高度只有144px,因為img是浮動的,他的linebox被浮動屬性破壞了,而文字又不夠多,所以就造成了所謂的高度塌陷,致使最後兩個div陷進了圖片所在的div中,要知道,這種情況在正常塊狀元素布局中是根本不會出現的。至於解決浮動引起的高度塌陷,我總結了兩條,分別是:

使用clear:both,常見的什麼clearfix;

觸發浮動元素父元素的BFC(塊狀格式上下文,為解決盒子與盒子之間,內容不相符影響而生的概念);

清除浮動,相信大家都懂,而觸發bfc。

我說說我常用的幾條,網上講bfc的很多:

除了上面講的這些,我還遇到過有人問,為什麼我用了浮動,但元素沒有浮在這一行,卻換了行,像下圖這樣

      <div>

       <div class="gr">我是導航欄的一些文字</div>

       <div class="fr">我想浮在右邊</div>

      </div>

      .gr{

         background-color: yellowgreen;

         margin:5px;

       }

       .fr{

         float:right;

         background-color: green;

       }

上面這種沒按想要的方式浮,是因為塊狀元素會不敢其內容長度有沒有一行的長度,其都會佔據一行的長度,後面的元素會自動換行。解決這個其最簡單的方式就是將fr元素放在gr元素前,為什麼這樣就可以,因為float破壞了div元素的塊狀屬性,但其未撐開父元素的高度,其浮動屬性為right,默認從右側開始布局,所以後面的div仍按正常的文檔流從最左端開始布局。

有一種行內元素,又叫置換元素

如果你看上面一題代碼的時足夠細心,你會發現我給img設置了width和height兩個屬性值為130,但由於又在css屬性裡定義了寬高260,但最終表現出的寬高為260。如果css不定義寬高呢?答案是多少,要不你試試,你慢慢試,我還是先公布答案:130.這裡我們將會說一個css中的一個鮮為人知的術語:置換元素,那什麼又是置換元素呢?

置換元素是指:瀏覽器根據元素的標籤和屬性,來決定元素的具體顯示內容。

例如:瀏覽器根據標籤的src屬性顯示圖片。input元素根據標籤的type屬性決定顯示輸入框還是按鈕。還有,還有近來很火的canvas。

置換元素有如下共同點:

置換元素一般內置寬高屬性,因此可以設置其寬高;

置換元素與一般的行內元素相比,其可以設置margin,padding,height,width等css屬性;

感覺要寫的還有很多,事件根本不夠用,先睡了,未完待續
如果文中有任何不足和錯誤之處,還請及時指正。

覺得本文對你有幫助?請分享給更多人

關注「前端大全」,提升前端技能

相關焦點

  • 教師招聘《飄來飄去的小島》試講問題解析
    一、教材分析:本課是人教版美術四年級(下)15課飄來飄去的小島,學習領域為造型•表現,1課時。本課的要點是讓學生利用白色泡沫板製作小島,培養學生的創造力和動手製作能力。(問題:學生在處理三維目標時,極容易把知識與技能目標、過程與方法目標弄混淆,其實針對本課和所有設計應用課時,知識與技能目標是源於本課的基礎美術知識點和一些操作步驟,即是靜態的知識;而過程與方法目標即掌握製作步驟後去運用的過程,是動態的知識。)
  • 注意CSS代碼中的!important屬性
    important屬性 CSS中的!important是一個非常重要的屬性,有時候發揮著非常大的作用,這方面的知識並不是非常多,我們看下面的文章,對它作比較感觀的了解。
  • CSS中position屬性的用法和作用
    CSS中position屬性的用法和作用 本文向大家介紹一下CSS中Position屬性的用法和作用,Position屬性有四個可選值,它們分別是:static、absolute、fixed、relative。
  • 暨南大學我來了!楊飄同學今天正式報到!
    9月18日暨南大學官方公號發出深情邀請約楊飄來報到!楊飄也於9月19日踏上了前往大學的路。暨南大學我來了9月19日,因為飛機晚點,楊飄和姐姐楊嬌嬌晚上六點才抵達珠海。說起在飛機上的感覺,楊飄表示,「在路上感覺挺激動,但是又感覺有點兒不真實!」
  • 《怪物獵人:世界》帝王金弓風飄怎麼配裝 帝王金弓風飄配裝攻略
    導 讀 《怪物獵人:世界》帝王金弓風飄是歷戰王絢輝龍系列的武器之一,是一把冰屬性的弓,這把弓要怎麼配裝才能發揮出實力呢,下面小編就為大家帶來一篇「汐易晨曦_
  • CSS中behavior屬性語法簡介
    CSS中behavior屬性語法簡介 你對CSS中behavior屬性的語法是否熟悉,這裡向大家簡單描述一下,在進行CSS網頁布局的時候,我們經遇到刷新要保留表單裡內容的時候,CSS中的behavior就為我們很好的解決了這個問題。
  • 書香飄萬家|繪本故事:我去外婆家
    書香飄萬家|繪本故事:我去外婆家 2020-04-25 10:00 來源:澎湃新聞·澎湃號·政務
  • 我的英文首馬——讀《飄》始末
    按照我自己的標準,我讀過的長篇小說大概一雙手能數得過來。因為沒耐心,我連肥皂劇都很少追,超過二十集的連續劇我基本不看,我喜歡短平快的電影作品。結合以上兩條,我居然看完了一本比磚頭還厚的原版小說,是不是人生大事? 我一直覺得世間萬物都講究個緣分,人和書之間也是。為什麼第一本原版長篇小說會選擇《飄》呢?這是有原因的,聽我慢慢道來。
  • 隔壁飄來的咖啡香
    那時候,不知是從哪裡看到還是聽說了喝咖啡的諸多好處,一直喜歡喝茶的先生忽然宣布以後以咖啡代茶飲,並且熱情高漲地買來了煮咖啡所需要的大致用具:一個迷你的木質磨豆機,一個煮咖啡的,然後是一大箱的咖啡豆。每天的空閒時分,便裝上一點咖啡豆慢慢地磨上半天,待手都搖得快酸了,一小杯豆粉才算磨成,然後便滿懷期待地等待著那一室的芳香,等待著那一刻與咖啡的完美相遇。
  • 紛亂的思緒飄啊飄
    今天早上我準備早餐,蒸了米飯,熬了小米稀飯,炒了白蘿蔔配紅蘿蔔。這讓媳婦兒稀罕了好一會兒:「我還是第一次見白蘿蔔配紅蘿蔔炒呢。」吃完早飯,媳婦外出採購屯貨。我在家陪兒子。一邊用恐龍玩過家家,一邊看動畫片,一邊放飛著這些紛亂的思緒。
  • css flex屬性筆記
    flex屬性定義及用法在css中,flex屬性是使用來設置或檢索彈性盒模型對象的子元素如何分配空間,是 flex-grow屬性、flex-shrink屬性和 flex-basis 屬性的簡寫屬性。flex屬性針對的是彈性盒模型對象的子元素,對於其它元素,flex屬性不起任何作用;一些主流瀏覽器還不支持flex屬性,需要在該屬性之前加對應的前綴才能識別該屬性。Internet Explorer 9及更早版本不支持flex屬性,但是可以通過-ms-flex屬性來支持, IE11 及更新版本完全支持flex屬性,不再需要-ms-前綴。
  • 就這麼飄來飄去—從來沒有一種堅持會被辜負
    第一章,寫在前面的話——就這麼飄來飄去題記是引用之前寫給一位好友同事的話語,Ryan Lee是2016取的英文名,Ryan是堅韌的意思,我喜歡這個詞。之前一直想用偏文藝的腔調寫一篇文,去祭奠一些事和人,關於少年、青春,關於高中摯友相聚相離的這十年,從十六七到二十六七的青蔥年歲。
  • 楊飄,暨南大學喊你來報到
    >「媽媽最大的願望就是我能好好學習,通過知識改變命運,考上一所理想的大學。」「我寧可放棄大學,也要給媽媽治病。」「媽媽和大學,你一個都不要放棄」楊飄對好心人也表示感謝「感謝所有幫助過我的人,是你們讓我學會了堅強,更學會了感恩。」
  • CSS margin屬性與用法教程
    margin 屬性是css用於在一個聲明中設置所有 margin 屬性的簡寫屬性,margin是css控制塊級元素之間的距離
  • css list-style-type屬性筆記
    list-style-type屬性定義及用法在css中,list-style-type屬性是使用來設置列表項標記的類型,在有序列表和無序列表中經常都會使用該屬性。目前,所有主流瀏覽器都支持list-style-type屬性,但是任何版本的Internet Explorer(包括 IE8)都不支持屬性值"decimal-leading-zero"、"lower-greek"、"lower-latin"、"upper-latin"、"armenian"、"georgian" 或 "inherit";
  • css left屬性左邊緣偏移
    left屬性定義及用法在css中,left屬性是使用來定義定位元素左外邊距邊界與其包含塊左邊界之間的偏移,其實就是元素向右的偏移量;left屬性通常和position、right、top、bottom等屬性一起使用
  • 射手座真的越來越飄了……飄起來簡直是恨不得別人來倒貼自己
    射手女很難去愛上一個人,因為怕受傷所以不敢去愛,很多時候只是讓自己去喜歡一個人。也是因為如此才會像風一樣飄啊飄的,遊蕩在不同的港灣。所以很多人都會認為射手很花心,其實射手只是太在乎愛。在射手的心中愛一個人是一輩子的事情,所以那份珍貴的愛怎可輕易付出。 當射手女愛上一個人,可能對她來說會是一場災難,因為那份愛是自己的全部。
  • css line-height屬性設置行高
    line-height屬性定義及用法在css中,line-height屬性是使用來設置行高,即設置行間的距離。在應用到一個塊級元素時,它定義了該元素中基線之間的最小距離而不是最大距離;line-height 與 font-size 的計算值之差(在 CSS 中成為「行間距」)分為兩半,分別加到一個文本行內容的頂部和底部。
  • css3 punctuation-trim屬性筆記
    punctuation-trim屬性punctuation-trim屬性定義及用法在css中,punctuation-trim屬性是使用來規定如果標點位於行開頭或結尾處punctuation-trim屬性是css3中新增屬性,目前主流瀏覽器都還不支持該屬性。
  • 抗疫歌曲《你像一片雪花飄去》——致敬白衣戰士
    在抗擊疫情的過程中,醫務人員挺身而出、英勇逆行,像潔白的雪花,融化自己,迎來春色換人間。抗疫歌曲《你像一片雪花飄去》,向白衣天使致敬!《你像一片雪花飄去》作詞:陳寶亮作曲:王俊峰演唱:逢君你像一片雪花飄去,一生是這樣短暫悽迷,你像一片雪花飄去,一生都這樣默默無語