原文連接
github.com/XboxYan/not…css
剛入前端那會,產品經理提出了這樣一個需求html
這段文字能不能這樣判斷一下,當文字不足一行時,讓它居中顯示,當文字超過一行就讓它居左,否則居中顯示很奇怪,由於最後一行是吊着的前端
琢磨了一下,當時我還真按照產品經理的邏輯,經過js
判斷一下文字的高度,若是超過一行,就添加一個類名,並且這樣的文字不少地方都有,因此還作了遍歷,還有最重要的一點是關於方法執行的時機,有可能剛加載的時候高度還獲取不到(當時好像還用了定時器,還形成了先居中隨後居左跳動的現象)...css3
//僞代碼
$('.text').each(function(){
if($(this).height()>30){
$(this).addClass('mul');
}
})
複製代碼
而後這些文本有可能仍是動態生成的,因此還得在生成文本的地方再調用一次這個方法,功能是作出來了,可別說有多囉嗦了,體驗也不咋地(雖然外面的人看不到)git
當時也在想,若是是CSS
實現,那麼就徹底不用考慮這些問題了!github
其實只要你邏輯清晰,js
都能實現出來,按照正常的思路一步一步走下來就好了。CSS
可不是這樣,她須要你有更多的想象力。chrome
好比上面這種需求,表面上來看是須要判斷文本行數,這徹底不是CSS
能幹的事呀,不過咱們能夠換個方向思考,文本默認是居左的(默認文本流),只有首行是居中的,首行能夠聯想到::first-line
僞元素,因此能夠試着這樣實現一下segmentfault
<p>這段文字能不能這樣判斷一下,當文字不足一行時,讓它居中顯示,當文字超過一行就讓它居左</p>
複製代碼
p::first-line{
text-align:center;
}
複製代碼
很好理解是吧,只針對首行進行居中操做,當多行時,首行已經鋪滿了,居中或者居左效果已經不明顯了,只是稍微有點瑕疵,首行的居中效果和後面的文字看着有些不太整齊的感受(由於當一行剩餘空間不足一個字符的時候會掉下去)wordpress
解決這個問題也很簡單,上面的問題是因爲首行一直處於居中狀態,那有沒有什麼辦法能夠只要一行的時候才居中呢?這裏能夠藉助一下text-align-last
,意思就是規定多行文本的最後一行的居中方式,若是和::first-line
一塊兒使用,既要知足首行又要知足是最後一行,是否是就判斷出了當前只有一行呢?工具
p::first-line{/*匹配首行*/
text-align-last:center;/*最後一行居中*/
}
複製代碼
這下就正常了,有點首尾夾擊的味道~
遺憾的是,因爲::first-line
支持樣式很是有限(MDN),上述實現方法僅在chrome
下有效,不過這種邏輯仍是和js
差異很大的
雖然上述並無
text-align
相關屬性,不過chrome
卻已經支持了~
text-align:center
,子級inline-block
+text-align:left
首先來看看兼容性最好的實現方式
結構以下
<div class="content">
<span class="text">這段文字能不能這樣判斷一下,當文字不足一行時,讓它居中顯示,當文字超過一行就讓它居左</span>
</div>
複製代碼
樣式以下
.content{
text-align: center;
}
.text{
display: inline-block;
text-align: left;
}
複製代碼
這個方式最先是在《CSS世界》中學到的,
大概原理以下:
對於一個元素,若是其
display
屬性值是inline-block
,那麼其寬度由內部元素決定,但永遠小於「包含塊」容器的尺寸,也就是「包裹性(shrink-to-fit)」
可能這樣描述的不夠直觀,來上述的案例簡單來說
當文本比較少時,.text
的寬度跟隨文本,而後咱們可使用父級text-align:center
來使一個inline-block
元素居中,因此能夠知足單行文本居中的效果,
當文本比較多時,.text
的寬度跟隨父級容器,因爲text-align:center
會繼承下去,因此在.text
上修復一下便可
兼容性一級棒~
width:fit-content
+margin:auto
上述方式是經過父級text-align:center
來實現inline-block
居中的,很巧妙,可是額外增長了標籤,由於inline-block
元素沒法自己居中的。
塊級block
元素能夠在設置寬度後直接經過margin:0 auto
來實現居中,可是必須指明寬度,否則就水平填充了,這二者的關係很微妙,有沒有什麼辦法可以讓塊級block
元素的寬度像inline-block
元素跟隨內部元素呢?
答案就是width:fit-content
,詳細可參考這篇文章
width:fit-content
能夠實現元素收縮效果的同時,保持本來的block
水平狀態,因而,就能夠直接使用margin:auto
實現元素向內自適應同時的居中效果了。
下面的實現方式均只須要單層標籤
<p class="text">這段文字能不能這樣判斷一下,當文字不足一行時,讓它居中顯示,當文字超過一行就讓它居左</p>
複製代碼
.text{
width: fit-content;
width: -moz-fit-content;//火狐須要-moz-前綴
margin: 0 auto;
}
複製代碼
固然,這種特性IE
確定是不支持的~
position:relative
+transform
仍需設置display:inline-block
來實現自適應,而後配合transform
來實現水平方向居中效果,實現也很簡潔~
.text{
display: inline-block;
position: relative;
left: 50%;
transform: translateX(-50%);
}
複製代碼
display:table
+margin:auto
前一種方式width:fit-content
頗有效,IE
不支持怎麼辦呢?其實默認display
已經有這種特性了,當display
屬性值是table
,元素會表現出和width:fit-content
的效果,既支持寬度跟隨內部元素,又支持水平方向上margin
居中
.text{
display: table;
margin: 0 auto;
}
複製代碼
IE8
也完美支持~
flex
和grid
實現對於flex
和grid
來講,實現這樣一個效果仍是挺容易的。
在flex
容器中,全部子項成爲彈性項,包括純文本節點(匿名盒子),就好像包裹了一層,因此很容易經過justify-content: center
實現居中,同時(匿名盒子)也跟隨文本自適應寬度,當超過一行時,就按照默認的文本對齊方式。
grid
同理,只不過對齊方式須要經過justify-items: center
。
flex
實現.text{
display: flex;
justify-content: center;
}
複製代碼
grid
實現.text{
display: grid;
justify-items: center;
}
複製代碼
相對於flex
,grid
的兼容性要差一些,因此儘可能選取flex
方式,至少移動端和IE10
(須要-ms-
)是沒問題的
float
實現本覺得float
實現不了的,感謝林小志提供了float
居中的實現方法,大體原理以下:自己float
元素是具有包裹特性的,主要難點在於如何居中,畢竟沒有float:center
這種寫法,這裏主要用到兩層標籤,利用position:relative;left:50%
正負抵消來實現
.content{
position: relative;
float: left;
left: 50%;/**父級設置50%**/
}
.text{
position: relative;
float: left;
left: -50%;/**子級設置-50%**/
}
複製代碼
略微繁瑣一點,不過也不失爲一種方法,兼容性也極好
上述一共列舉了8種實現方式,固然第一種屬於實驗性質的,兼容性少的可憐,但也不失爲一種思路。怎麼想到這些方法呢?
第一就是聯想。好比上述提到了自適應(簡單來說就是尺寸由內容決定),我就想哪些能夠實現自適應呢?除了inline-block
,還有float
、position:absolute
、display:table
等...首先(通過試驗,能夠實現)。float
就排除了,元素設置了float
後,總體居中實際上是件麻煩的事,幾乎不可能position:absolute
仍是挺有但願的,藉助left:50%;transform:translateX(-50%)
能夠實現居中效果, 嘗試了一番,發現寬度沒法自適應父級寬度,一樣失敗(說不定能夠,只是沒有想到)~~最後選擇了diaplay:table
,也算是按部就班。flex
和grid
就更不用說了,自然就是爲彈性佈局而生了,實現這類效果不奇怪。
第二仍是基礎。CSS
屬性可就那麼多,那只是停留在表面,不少看起來不相關的屬性在整個體系中又會有些微妙的關係,好比上面的width:fill-content
,單獨看這個確定很雞肋,徹底能夠用inline-block
來代替,可是他卻可讓一個普通的div
元素具有inline-block
的特性,不得不佩服CSS
的設計~(確定有設計人員參與)
前一段時間在思考作一個可視化編輯工具,但願能夠經過一些屬性,就像photoshop
那樣,直接做出一個頁面來,想一想看,發現只能做出最最基本的樣式,也就顏色,大小什麼的,若是要作成本文這樣一個效果,八成是作不了的,除了自己是作開發,別人怎麼可能知道這樣設置呢?可視化編輯工具的道路還很長很長,因此作前端的也無需擔憂被其餘什麼「一鍵生成工具」給取代了~
各位小夥伴若是還有其餘實現方式可在下方留言評論,若是文章有錯誤請及時指出,謝謝~