writing-mode
這個CSS屬性,我們是不是很少見到,很少用到!我們往往稱不常見的東西為“生僻”,就像是不常見的文字我們叫“生僻字”,因此不常見的CSS屬性,我們可以叫做“生僻屬性”,writing-mode
給我們的感覺就是一個“生僻屬性”,很弱,可有可無。
但是,實際上,我們都錯了,大錯特錯,writing-mode
很弱?臥槽,別開玩笑了,writing-mode
可以說是CSS世界裡面最逆天的CSS屬性了,直接顛覆CSS世界的眾多規則。
而writing-mode
之所以給人「生僻」的感覺,是有原因的。
其實writing-mode
這個CSS屬性在上古時代就誕生了,IE5.5瀏覽器就已經支援了:
那就奇怪了! writing-mode
既然這麼鳥,同時時間早,資格老,為啥一直沉寂了差不多20年呢?
那是因為,在很長一段時間裡,FireFox, Chrome這些現代瀏覽器都不支援writing-mode
,writing-mode
基本上就是IE瀏覽器的私有產物,大家對IE一直沒啥好感,對吧,愛屋及烏由此及彼,自然對writing-mode
也不待見。
然而,就在我們被流行前端技術一葉蔽目的時候,各大現代瀏覽器紛紛對writing-mode
實現了更加標準的支持(主要得益於FireFox瀏覽器的積極跟進),也就是說,不知什麼時候起,writing-mode
的兼容性已經不成問題了,加上該屬性本身特性逆天,我去,我彷彿看到了一個冉冉升起的新星,不對,是新月,而且是圓月。
和float
屬性有些類似,writing-mode
原本設計的是控制內聯元素的顯示的(即所謂的文字佈局-Text Layout)。因為在亞洲,尤其像中國這樣的東亞國家,存在文字的排版不是水平式的,而是垂直的,例如中國的古詩古文。
因此,writing-mode
就是用來實現文字可以豎立的。
您可以狠狠地點擊這裡:CSS writing-mode與文字垂直排版demo
#截自IE11瀏覽器IE8模式:
writing-mode語法writing-mode
的語法學習相比其他CSS屬性要高一些,因為我們需要記住兩套不同的語法。一個是IE私有屬性,第二個是CSS3規範屬性。
先看下未來所需的CSS3語法:
/* 关键字值 */ writing-mode: horizontal-tb; /* 默认值 */ writing-mode: vertical-rl; writing-mode: vertical-lr; /* 全局值-关键字inherit IE8+,initial和unset IE13才支持 */ writing-mode: inherit; writing-mode: initial; writing-mode: unset;
各個關鍵字屬性值的意義,我們透明名稱就能知道其大概的意思,例如,預設值horizontal -tb
表示,文字流是水平方向(horizontal)的,元素是從上往下(tb:top-bottom)堆疊的。
vertical-rl
表示文字是垂直方向(vertical)展示,然後閱讀的順序是從右往左(rl:right-l eft),跟我們古詩的讀經順序一致。 vertical-lr
表示文字是垂直方向(vertical)展示,然後閱讀的順序還是預設的從左到右(lr:left-right),也就是只是水平變垂直。
下面是各個值下的中英文表現對照(參考自MDN):
//zxx: 大家會發現英文字元橫過來了,可以試試使用text-orientation:upright
讓其直立,IE不支持,FireFox, Chrome支持。
下面來看下老IE瀏覽器的語法,由於歷史原因,顯得相當的複雜,IE官方文件顯示如下:
-ms-writing-mode: lr-tb | rl-tb | tb-rl | bt-rl | tb-lr | bt-lr | lr-bt | rl-bt | lr | rl | tb
根据自己的测试(非原生IE8,IE9),-ms-
私有前缀是可缺省的,直接writing-mode
所以IE浏览器都是支持的。-ms-writing-mode
这种写法IE7浏览器是不支持的,但是官方有如下说明:
Windows Internet Explorer 7. The rl-tb, and bt-rl values are available to the -ms-writing-mode
就是说IE7的-ms-writing-mode
可以使用rl-tb
和bt-rl
这两个值,但这和自己的测试不符,我觉得可能是原生IE7浏览器,但我没有原生IE7,没有进行过测试,因此,此说法(原生IE7支持)只是自己的推测。
我扳指头数了数,IE浏览器下的关键字值多达11个,正好可以组个足球队,
lr-tb
IE7+浏览器支持。初始值。内容从左往右(left-right),从上往下(top-bottom)水平流动,以及下一行水平元素在上一行元素的下面,所有符号都是直立定位。大部分的书写系统都是使用这种布局。
rl-tb
IE7+浏览器支持。内容从右往左(right-left,从上往下(top-bottom)水平流动,以及下一行水平元素在上一行元素的下面,所有符号都是直立定位。这种布局适合从右往左书写的语言,例如阿拉伯语,希伯来语,塔安那文,和叙利亚语。
tb-rl
IE7+浏览器支持。内容从上往下(top-bottom),从右往左(right-left)垂直流动, 下一个垂直行定位于前一个垂直行的左边,全角符号直立定位,非全角符号(也可以被称作窄拉丁文或者窄假名符号)顺时针方向旋转90°。这种布局多见于东亚排版。
bt-rl
IE7+浏览器支持。内容从下往上(bottom-top),从右往左(right-left)垂直流动, 下一个垂直行定位于前一个垂直行的左边,全角符号直立定位,非全角符号(也可以被称作窄拉丁文或者窄假名符号)顺时针方向旋转90°。此布局多见于在东亚垂直排版从右往左的文本块上。
tb-lr
IE8+浏览器支持。 内容从上往下(top-bottom),从左往右(left-right)垂直流动。下一个垂直行在前一个的右边。
bt-lr
IE8+浏览器支持。 内容从下往上(bottom-top),从左往右(left-right)垂直流动。
lr-bt
IE8+浏览器支持。 内容从下往上(bottom-top),从左往右(left-right)水平流动。下一个水平行在前一行的上面。
rl-bt
IE8+浏览器支持。内容从下往上(bottom-top), 从右往左(right-left)水平流动。
lr
IE9+浏览器支持。在SVG和HTML元素上使用。等同于lr-tb
.
rl
IE9+瀏覽器支援。在SVG和HTML元素上使用。等同於rl-tb
.
tb
IE9+瀏覽器支援。在SVG和HTML元素上使用。等同於tb-rl
.
各個屬性值的表現如下(form微軟官網)
一些說明:
相同的writing-mode
屬性值不會累加,例如父子都設定了writing-mode :tb-rl
,只會渲染一次,子元素並不會2次「旋轉」。
IE瀏覽器下,一個本身俱有佈局的元素(不是純文字之類元素)如果writing-mode
屬性值和父元素不同,當子元素的佈局流變化的時候,其父元素座標系統的可用空間會被充分利用。左邊文字太過術語,大家可能不懂,我解釋下就是,IE瀏覽器下,當佈局元素從水平變成垂直的時候(舉個例子),你就想像為元素在垂直方向是100%自適應父元素高度的。所以,IE瀏覽器下(不包括IE13+),元素vertical流的時候會發現高度高的嚇人,佈局和其他現代瀏覽器不一樣,就是這個原因。
Chrome瀏覽器下目前還需要-webkit-
私有前綴,雖然Chrome和Opera認識tb-rl
等老的IE屬性值,但是,僅僅是認識而已,根本不鳥,沒有任何效果,聾子的耳朵——擺設!
需要關注的writing-mode屬性值
#從著眼於直接開發的角度而言,雖然IE支援多達11個私有的屬性值,但是,我們需要關注的,也就那麼幾個,那究竟是哪幾個呢?
如果你的專案需要相容IE7,則只有專注於這兩個值就可以了:初始值lr-tb
和tb-rl
,對應於CSS3規範中的horizontal-tb
和vertical-rl
!其他9個屬性值就讓它們去過家家好了。
如果你的项目只需要兼容IE8+,恭喜你,你可以和CSS3规范属性完全对应上了,而且IE8下的writing-mode
要比IE7强大的多。我们需要关注:初始值lr-tb
, tb-rl
以及tb-lr
,分别对应于CSS3中的horizontal-tb
, vertical-rl
以及vertical-lr
。
看上去复杂的属性是不是变得很简单了,重新整一个实战版:
writing-mode: lr-tb | tb-rl | tb-lr (IE8+); writing-mode: horizontal-tb | vertical-rl | vertical-lr;
对,大家只要记住上面几个就可以了,enough! 因为所谓的垂直排版,实际web开发是很少很少遇到的。
有同学可能要疑问了,既然writing-mode
实现文本垂直排版场景下,那还有什么学习的意义呢?
前面也提到了,虽然writing-mode
创造的本意是文本布局,但是,其带来的文档流向的改变,不仅改变了我们多年来正常的CSS认知,同时可以巧妙实现很多意想不到的需求和效果。
writing-mode将页面默认的水平流改成了垂直流,颠覆了很多我们以往的认知,基于原本水平方向才适用的规则全部都可以在垂直方向适用!
1. 水平方向也能margin重叠
W3C文档margin重叠之一:
The bottom margin of an in-flow block-level element always collapses with the top margin of its next in-flow block-level sibling, unless that sibling has clearance.
清清楚楚写的bottom margin和top margin会重叠;然而,这是CSS2文档中的描述,在CSS3的世界中,由于writing-mode
的存在,这种说法就不严谨了,应该是对立流方向的margin值会发生重叠。换句话说,如果元素是默认的水平流,则垂直margin会重叠;如果元素是垂直流,则水平margin会重叠。
您眼见为实,您可以狠狠地点击这里:CSS writing-mode与margin水平重叠demo
结果:
2. 可以使用margin:auto实现垂直居中
我们应该都是的,传统的web流中,margin
设置auto
值的时候,只有水平方向才会居中,因为默认width
是100%
自适应的,auto
才有计算值可依,而垂直方向,height没有任何设置的时候高度绝不会自动和父级高度一致,因此,auto
没有计算空间,于是无法实现垂直居中。但是,在writing-mode的世界里,纵横规则已经改变,元素的行为表现发生了翻天覆地的变化。
图片元素
我们先来看下,图片元素margin:auto
实现垂直居中,您可以狠狠地点击这里:CSS writing-mode与图片margin:auto垂直居中demo
其中图片:
img { display: block; margin-top: auto; margin-bottom: auto; }
FireFox浏览器下(P白省流量):
但是,在IE浏览器下,却没有垂直居中~~
纳尼?!难道IE不支持垂直流下的垂直居中?非也,根据鄙人的测试,也就是图片这类替换元素貌似不行,普通的block元素都是可以的。
普通块状元素
您可以狠狠地点击这里:CSS writing-mode与普通block元素margin:auto垂直居中demo
此时,不仅IE11 edge,甚至IE8浏览器也都垂直居中了!
3. 可以使用text-align:center实现图片垂直居中
前面提过,auto
无法实现IE浏览器下的图片垂直居中,如果我们非要让图片垂直居中,可以使用text-align:center
,您可以狠狠地点击这里:CSS writing-mode与图片text-align:center垂直居中demo
结果,之前病恹恹的IE浏览器活了:
由于我们直接使用内联特性进行控制的,因此,IE7浏览器也是可以实现text-align:center
下的图片垂直居中,但是,根据我在IE11↘IE7下的测试,writing-mode
需要写在最后重置下(原生估计不会这样),因此,完整的writing-mode
代码为:
.verticle-mode { writing-mode: tb-rl; -webkit-writing-mode: vertical-rl; writing-mode: vertical-rl; *writing-mode: tb-rl; }
4. 可以使用text-indent实现文字下沉效果
这是真实项目例子,要增加一个按钮按下文字下沉的效果。如果你来实现,你会这么实现呢?行高控制?但默认文本就不居中(对于高度自适应的按钮,line-height下沉为了避免按钮高度变化,默认是不能完全居中的)。padding+height精确控制,又略烦。然而,在writing-mode
垂直流下,我们又有了新思路,例如,直接使用text-indent
实现垂直方向的控制,没想到吧,无需关心height高度padding间距大小,任何按钮都可以通用,因为text-indent
不会影响元素原本的盒布局。
您可以狠狠地点击这里:CSS writing-mode与text-indent文字下沉效果demo
包括IE7在内的浏览器都是支持的(同上最后要*writing-mode
覆盖下)都是支持下沉的。
为什么有如此的实现呢?这要归功于中文,在垂直流排版的时候,中文是不会旋转的,还是直立的,也就是说,虽然我们肉眼看上去文字没什么变化,但是,布局流已经发生了变化,以前类似text-indent
/letter-spacing
等水平控制属性都作用在垂直方向了。
当然,我们这个例子比较巧的是按钮文字只有一个,要是按钮文字有多个,怕是就没这么轻松和绝妙了。
5. 可以实现全兼容的icon fonts图标的旋转效果
在老的IE浏览器下,我们要实现小图标的旋转效果是不是很烦?要使用IE的旋转或翻转滤镜(filter)什么的,具体可参见我之前的“CSS垂直翻转/水平翻转提高web页面资源重用性”以及“IE矩阵滤镜Matrix旋转与缩放及结合transform的拓展”一文。
现在我们有了writing-mode
,我们就不要这么烦心了。
前面可能也注意到了,當writing-mode
把文檔變成垂直流的時候,我們的英文和數字符號是會「躺著」顯示,也就是天然90°旋轉了。此時,我們不妨腦洞大開一下,假如我們使用icon fonts技術讓這些字符直接映射某個小圖標,那豈不是鬆松實現小圖標旋轉了,關鍵在於,就算是千年殺的IE6,IE7瀏覽器也是支援的啊,這要比濾鏡什麼的簡單多了!
眼見為實,您可以狠狠地點選這裡:writing-mode實作icon fonts圖示旋轉效果demo
就算是IE7瀏覽器,也是很給力的!
6. 充分利用高度的高度自適應佈局
臥槽,不行了,內容太多了,五一前也寫不完了……
往下的7,8,9,10一起都略了吧~~
總之,放開自己的大腦,理論上講,有了 writing-mode
,我們能夠做的事情比以前多了50%,就怕你想不到,不怕做不到。
上個月剛介紹了CSS direction
屬性,也是好東西,具體參見「CSS direction屬性簡介與實際應用”,其可以改變文字的走向,那他和writing-mode
是個什麼關係呢?
writing-mode
, direction
, unicode-bidi
(MDN文檔)是CSS世界中3大可以改變文字佈局流向的屬性。其中direction
, unicode-bidi
#屬於近親,經常在一起使用,也是唯一兩個不受CSS3 all屬性影響的CSS屬性,基本上就是和內聯元素一起使用,且據說貌似為阿拉伯文字設計。
乍一看,writing-mode
似乎包含了direction
, unicode-bidi
某些功能和行為,例如vertical-rl
的rl
和direction
的rtl
值有相似之處,都是從右往左。然而,實際上,兩者是沒有交集的。因為vertical-rl
此時的文件流為垂直方向,rl
表示水平方向,此時再設定direction:rtl
,實際上值 rtl
改變的是垂直方向的內聯元素的文字方向,一橫一縱,沒有交集。而且writing-mode
可以對塊狀元素產生影響,直接改變了CSS世界的縱橫規則,要比direction
強大和鬼畜的多。且據說貌似為東亞文字設計。
然而,CSS的奇妙就在於,某些特性當初可能就是問了某些圖文排版設計,但是,我們可以利用其帶來的特性,發揮自己的創造力,實現其他很多意想不到的效果。所以,上面出現的三劍客都是非常好的資源。
CSS3中出現了諸多*-start
/*-end
屬性(也稱為CSS邏輯屬性),例如:margin-start
/margin-end
, border-start
/border-end
, padding-start
/padding-end
, 以及text-align:start
/text-align:end
聲明。
下面問題來了,為什麼會蹦出這麼多*-start
/*-end
鬼?
那是因為現代瀏覽器加強了對流的支持,包括老江湖direction
,以及最近年月跟進的writing-mode
。
在很久以前,我們的認知裡,網頁佈局就一種流向,就是從左往右,從上往下,因此,我們使用margin-left
/margin-right
沒有任何問題。但是,如果我們流是可以變化的,例如,一張圖片距離左邊緣20像素,我們希望其文件流是從右往左,同時距離右側是20像素,怎麼辦?
此時,margin-left:20px
在圖片direction
變化後,就無效了;但是,margin-start
就不會有此問題,所謂start, 指的是文檔流開始的方向,換句話說,如果頁面是預設的文檔流,則margin-start
等同於margin-left
,如果是水平從右往左文檔流,則margin-start
等同於margin-right
。 margin-end
也是類似的。
webkit核心的瀏覽器也支援*-before
和*-end
,預設流下的margin- before
近似於margin-top
,margin-after
近似於margin-bottom
,然而,規範貌似沒提及,FireFox也沒支持, *-before
和*-after
出場的機會不多,為什麼呢?因為實際上,配合writing-mode,*-start
/*-end
已經可以滿足我們對邏輯位置的需求了,水平和垂直都可以控制,對立方向適用老的*-top
/*-bottom
.
例如,我們設定writing-mode
值為vertical-rl
,此時margin-start
等同於margin-top
,如果此時margin-start
,margin-top
同時存在,會遵循權重和後來居上原則進行相互的覆蓋。
可以看到,場景不同,margin-start
的作用也不能,能上能下,能左能右簡直在世百變星君。
關於*-start
/*-end
以後有機會會具體展開論述,這裡就先點到為止,大家估計目前也不會在實際項目中使用。
以上是CSS中writing-mode屬性改變縱橫規則的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!