白話:即上一篇我腦中飄來飄去的css魔幻屬性本身的文章推出以後,這是本身寫的第四篇CSS相關的文章,文章絕大部分是本身工做總結得來,另外一部分是平日sf回答的與面試中向面試官交流學到的,都是一些比較基礎,刨根問底的知識分享。css
在上一篇我腦中飄來飄去的css魔幻屬性提到浮動不按想要的方式浮,裏面提到清除浮動其實按原理來說,就兩個:html
前面由於沒咋搞明白,就沒有說爲何,最近由於偶然在sf上有人提問,就順着這個問題去搜了相關資料,找了點答案。前端
clear清除浮動的操做,基本思路是這樣。首先爲要清除浮動的盒子引入清除元素,現實表現裏通常爲一個空元素或者僞元素(before,after)。設置了clear屬性後,盒子渲染時,會將這個元素的top border(上邊緣)與浮動元素的底部對齊,來達到將盒子撐開的目的。可是這個與浮動元素底部對齊的元素與clear設置的屬性(both,left,top)有關,具體能夠看W3C標準。仍是很簡單易懂的。若是說的不是很明白,能夠拷貝這段代碼,試一下,而後切換clear的值,就會有種恍然大悟的感受。 若是你以爲還不夠直觀,你能夠將content的「」裏寫兩個字,或則加個margin,border什麼的。
html 代碼 css3
<body> <div class="float-left"> 這是左邊浮動元素 </div> <div class="clear-box"> <div class="float-right">這是右側浮動元素</div> <div>這是正常佈局文檔流元素。</div> </div> </body>
css代碼 web
.float-left{ float: left; width: 100px; height: 100px; background-color: lightpink; } .clear-box{ margin-top: 50px; //這個沒有用 background-color: lightgreen; font-size: 16px; } .clear-box:after{ content: ''; display: block; clear: right; //both left } .float-right{ width:100px; height:75px; float:left; background-color:red; border:1px solid black; }
說BFC清除浮動以前,得知道BFC的概念:
塊格式化上下文(Block Formatting Context,BFC) 是Web頁面的可視化CSS渲染的一部分,是佈局過程當中生成塊級盒子的區域,也是浮動元素與其餘元素的交互限定區域。其做用簡單來說就是,保證整個文檔流中盒子與盒子之間的佈局不相互干擾,這裏其實已經很顯示的說明BFC一大功效就是清除浮動,觸發BFC的條件詳見MDN。
至於BFC爲何能夠清除浮動,就是造成BFC的盒子,其邊框會去查詢盒子裏全部的正常佈局文檔流,和浮動的文檔流,而後將盒子的底部邊緣與盒子裏最底部元素的盒子邊緣對齊(這麼講會不會被警察關禁閉)。與clear區別的,這種清除浮動因爲是盒子本身觸發BFC,因此只能清除盒子裏面的元素,而前面能夠清除同一行全部左右兩邊的浮動。面試
自此,清除浮動的原理就講完了。但在此次參加面試前,一個問題本身也一直想搞懂,浮動是否脫離了文檔流。MDN中是這樣定義的:float CSS屬性指定一個元素應沿其容器的左側或右側放置,容許文本和內聯元素環繞它。該元素從網頁的正常流動中移除,儘管仍然保持部分的流動性(與絕對定位相反)。這相反指的是什麼,想知道。 segmentfault
重點強調:設置了float屬性的元素,其display是什麼屬性。答案:block。inline元素設置爲float後,其width和height都變成了可設置的屬性。其緣由就是設置float觸發了BFC。是inline元素變成了一個塊級盒子。其一樣適用於設置position屬性爲絕對定位或固定定位的內聯元素。瀏覽器
學前端的,出去面試,浮動和盒模型是必問。這裏也再也不說正常盒模型(W3C)與怪異盒模型(IE)的區別,重點談padding。ide
首先是說說單位。通常來講設定盒子某一屬性,有以下幾種單位能夠設置:wordpress
px,vh,vw,rem這些絕對單位很好理解,但若是是em和%,你是否足夠留意,其是根據誰來做爲參照來計算的。首先%,直接看代碼和效果圖:
<div class="big"> <div class="small">這是子元素</div> </div> .big{ height:200px; width:1000px; background-color: yellowgreen; } .big .small{ width:50%; height:50%; margin-top:5%; margin-left:5%; border-top: 5px solid red; border-left: 5px solid red; padding-top: 5%; padding-left: 5%; background-color: #0e8cf6; }
從上面的圖能夠看出,margin,padding不管是top仍是left設置爲5%都是50,算下來就是以父級元素的寬度來做爲參照的。不要問爲啥border不能設置百分比,我不知道,我也沒這種需求。
再看一下以em爲單位是以誰作參照,HTML與上面一致,上css代碼:
.big{ height:200px; width:1000px; font-size: 14px; background-color: yellowgreen; } .big .small{ width:50%; height:50%; margin-top:2em; margin-left:2em; border-top: 5px solid red; border-left: 5px solid red; padding-top: 2em; padding-left: 2em; font-size: 20px; background-color: #0e8cf6; }
從計算樣式盒子能夠看出,margin,padding不管是top仍是left設置爲2em都是以元素自身的font-size來計算的,因此和百分比又不同。
若是知道這些,UI需求是讓你在一個盒子裏畫一個正方形盒子,你就很天然的會想到。用padding的百分比特性來作。
若是再多想一些,當咱們用css3特性來作位移好比:transform:translate(50%,50%),其又是相對誰來計算呢?這裏直接給出答案:其參照值是元素自己的長和寬,和前面padding又不同。
本身寫了一年css,其實一直只關注了設置border-box與content-box盒子模型時padding表現的差異。但這個盒子的零點,及子元素固定定位相對的零點在哪裏呢?仍是先看代碼和效果圖:
<div class="big"> <div class="small"> <!--<div class="normal">這是正常文檔流子元素</div>--> <div class="position">這是絕對定位子元素</div> </div> </div> .small .normal{ height:40px; background-color: #999; } .small .position{ position: absolute; width: 90%; height:30px; //top:0; //left:0; background-color: white; }
上面四張圖片,分別展現了絕對定位時,設置top,left與不設置的差異。不設置時,其文檔流開始的起點是正常文檔流的位置,而設置了top,left的地方,其起點是父元素(padding+content)區域零點的位置。以上效果和父元素設置不設置box-sizing: border-box屬性無關,表現一致。
sf上面有這樣一個提問:爲何設置display:inline後,padding-bottom仍然起做用?若是通常看過css基礎知識的人,都知道內聯元素設置margin-top、bottom,padding-top、bottom是不起做用的,因此平常開發,咱們通常不會用這兩個屬性,要用時更多也是把內聯元素轉換爲inline-box。重現問題:
<div id="fu"> <p>1505</p> <p>計科</p> </div> #fu{ // margin-top: 20px; // background-color: yellowgreen; } #fu p{ display: inline; margin: 20px; padding: 20px; border: 5px solid transparent; background-color: #0e8cf6; }
上面是三幅圖,分別表明三種狀態。經過不斷遞進,咱們就能夠回答上面那個問題了。其實不是padding-bottom仍然起做用,準確來講是padding-bottom與padding-top都會起做用,只是起做用只是從表現上起做用,但並不佔據文檔流。怎麼理解?第一:父元素黃綠色背景區域的高度和子元素內容高度一致,說明padding高度並無被計算在內;第二:父元素沒有加margin-top來佔位時,padding-top那塊區域是不可見的,因此內聯元素padding是沒有在正常文檔流的。至於爲何,能夠理解爲內聯元素沒有盒模型,其高度由內容決定。因爲其沒有盒模型,因此無法控制padding-top和padding-bottom。
這一波面試,談css的技術面試官,基本都會提怎麼垂直水平居中。這確實是一個老生常談的問題,以至於我越日後,回答的越含糊,若是你還不知道,能夠看看這篇文章。基本就四種:table,flex,translate,定位加margin:auto。最後這一種不多人據說,但在居中盒子長寬值肯定時,適用性確實很高。具體怎麼操做呢:
<div class="item"> <div class="items-center"> 這是一個居中 </div> </div> .item{ width: 500px; height: 500px; position: relative;/*關鍵設置*/ background-color: #999; } .item-center{ position: absolute; /*關鍵設置,也可fixed*/ top:0; /*關鍵設置*/ bottom: 0;/*關鍵設置*/ left:0;/*關鍵設置*/ right:0;/*關鍵設置*/ height:300px;/*關鍵設置,也可其餘單位*/ width: 300px;/*關鍵設置,也可其餘單位*/ margin: auto;/*關鍵設置*/ background-color: yellowgreen; border: 5px solid darkgray; }
上面的效果圖,能夠看到這種水平垂直居中方案也是666啊,前提是width,height必須顯示設定,只兼容IE8+,其一樣也適用於position:fixed的狀況,具體視UI需求。咱們一般只知道針對於塊級元素,若是其定寬,可使用margin:0 auto;來水平居中的,那這裏又用auto實現了垂直居中,怎麼實現的?原本想好好寫的,可又看見我張老師已經作了一次剖析,本身只能仰望,獻上地址。基本上從兩個方面解釋,能稍微解釋同:
1:left,right,top,bottom設置爲0,那麼就說明item-center這個盒子,是會填滿整個父級容器item的;
2:margin:auto 默認只會計算左右邊距,因此上下若是設置爲auto時默認是0;但對於脫離了正常文檔流的定位元素,這個auto對於上下也是有效的,會自動均分左右兩邊的距離。因此這個盒子已經顯示設定寬高,那麼margin就會自動計算均分,達到居中的效果。
下面是一些零碎的經驗分享,寫出來共勉。
字體圖標出現之後,其實精靈圖的不少實用場景就被取代了,前端切圖仔又能夠好好安心寫代碼了。但使用字體圖標圖標仍是有須要注意的地方,好比上方那張圖,從正常到不正常(字體邊框模糊),其實也就是font-weight設置的問題,因爲font的繼承性關係,因此很容易出現問題,因此字體圖標樣式初始化的時候將font-style與weight置爲important仍是頗有必要的。
.ued-components{
font-family:"fe-components" !important; //引用字體圖標庫 font-size:16px; font-style:normal !important; //設置字體樣式 font-weight:normal !important; //設置字體加粗程度 -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
<div class="ued-components send-img"></div>
以上是一個用css3 animation 作的一個演示動畫,若是仔細看,能夠感受到那種車速和檔位不匹配的那種感受,就是抖、抖、抖,看一下css代碼的實現:
.logo-animate { position: relative; line-height: 0; width: 240px; animation: move-float 8s linear 0s infinite; } @keyframes move-float { 0% { margin-top:0; } 50% { margin-top:-22px; } 100% { margin-top:0; } }
在過往依賴jQuery的animate作圖片輪播和列表輪播時,習慣於用margin來作位移。可是用純css來作得時候,發現實現有明顯的卡頓。後面一查看了一篇文章,發現css的animation實現最好依賴於transform來作,避免使用height,width,margin,padding等,具體緣由在前面文章中有提到。因此代碼優化一下,就是下面這樣:
@keyframes move-float { 0% { transform: translate(95px, 0); } 50% { transform: translate(95px, -22px); } 100% { transform: translate(95px, 0); } }
如上圖展現的那樣,當我文字過多時,須要截斷文字,使用省略號來保證正常的顯示效果。用css的實現基本都是下面這段代碼:
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
可是遇到table的狀況,儘管你設置了td的width屬性,但仍是不起做用。這是由於table佈局的流體屬性,其會根據內容再從新分配空間,因此還須要加上一個table-layout:fixed 這樣的屬性設置。其實除了單行能夠用css作文字截取,多行也能夠,只是在兼容性上和效果上還不足以在線上環境來使用。可是實現思路仍是能夠看一看:
display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
因使用了WebKit的CSS擴展屬性,該方法適用於WebKit瀏覽器及移動端,可是要想作到兼容及顯示效果完美,仍是用css配合js來作,單行css來作已足夠,但記得設置title屬性,保證hover能讀到完整的信息。 做爲一個寫CSS不到兩年的前端,在工做中吃了不少基礎不紮實的虧。學CSS也不如JS那樣簡單,知識成體系,因此除了看完一本CSS基礎知識的書之外,更多的仍是寫、寫、寫,而後思考,嘗試用不一樣的思路來解決。