一卿樱、冉冉升起的writing-mode
writing-mode這個(gè)CSS屬性抚笔,我們是不是很少見到饰迹,很少用到!我們往往稱不常見的東西為“生僻”切端,就像是不常見的文字我們叫“生僻字”鲸拥,因此不常見的CSS屬性,我們可以叫做“生僻屬性”吵取,writing-mode給我們的感覺就是一個(gè)“生僻屬性”,很弱锯厢,可有可無皮官。
但是,實(shí)際上实辑,我們都錯(cuò)了捺氢,大錯(cuò)特錯(cuò),writing-mode很弱剪撬?臥槽摄乒,別開玩笑了,writing-mode可以說是CSS世界里面最逆天的CSS屬性了残黑,直接顛覆CSS世界的眾多規(guī)則馍佑。
而writing-mode之所以給人“生僻”的感覺,是有原因的梨水。
實(shí)際上writing-mode這個(gè)CSS屬性在上古時(shí)代就誕生了拭荤,IE5.5瀏覽器就已經(jīng)支持了:
那就奇怪了!writing-mode既然這么鳥冰木,同時(shí)時(shí)間早野崇,資格老沦泌,為啥一直沉寂了差不多20年呢孝情?
那是因?yàn)榱涔悖诤荛L一段時(shí)間里帅腌,F(xiàn)ireFox, Chrome這些現(xiàn)代瀏覽器都不支持writing-mode绿满,writing-mode基本上就是IE瀏覽器的私有產(chǎn)物亿胸,大家對(duì)IE一直沒啥好感汹想,對(duì)吧追葡,愛屋及烏由此及彼腺律,自然對(duì)writing-mode也不待見。
然而宜肉,就在我們被流行前端技術(shù)一葉蔽目的時(shí)候匀钧,各大現(xiàn)代瀏覽器紛紛對(duì)writing-mode實(shí)現(xiàn)了更加標(biāo)準(zhǔn)的支持(主要得益于FireFox瀏覽器的積極跟進(jìn)),也就是說谬返,不知什么時(shí)候起之斯,writing-mode的兼容性已經(jīng)不成問題了,加上該屬性本身特性逆天遣铝,我去佑刷,我仿佛看到了一個(gè)冉冉升起的新星莉擒,不對(duì),是新月瘫絮,而且是圓月涨冀。
二、writing-mode的原本作用
和float屬性有些類似麦萤,writing-mode原本設(shè)計(jì)的是控制內(nèi)聯(lián)元素的顯示的(即所謂的文本布局-Text Layout)鹿鳖。因?yàn)樵趤喼蓿绕湎裰袊@樣的東亞國家频鉴,存在文字的排版不是水平式的栓辜,而是垂直的,例如中國的古詩古文垛孔。
因此藕甩,writing-mode就是用來實(shí)現(xiàn)文字可以豎著呈現(xiàn)的。
您可以狠狠地點(diǎn)擊這里:CSS writing-mode與文字垂直排版demo
截自IE11瀏覽器IE8模式:
writing-mode語法
writing-mode的語法學(xué)習(xí)相比其他CSS屬性要高一些周荐,因?yàn)槲覀冃枰涀商撞煌恼Z法狭莱。一個(gè)是IE私有屬性,第二個(gè)是CSS3規(guī)范屬性概作。
先看下未來所需的CSS3語法:
/* 關(guān)鍵字值 */writing-mode: horizontal-tb;/* 默認(rèn)值 */writing-mode: vertical-rl;writing-mode: vertical-lr;/* 全局值-關(guān)鍵字inherit IE8+腋妙,initial和unset IE13才支持 */writing-mode:inherit;writing-mode:initial;writing-mode:unset;
各個(gè)關(guān)鍵字屬性值的含義,我們透明名稱就能知道其大概的意思讯榕,例如骤素,默認(rèn)值horizontal-tb表示,文本流是水平方向(horizontal)的愚屁,元素是從上往下(tb:top-bottom)堆疊的济竹。
vertical-rl表示文本是垂直方向(vertical)展示,然后閱讀的順序是從右往左(rl:right-left)霎槐,跟我們古詩的閱讀順序一致送浊。
vertical-lr表示文本是垂直方向(vertical)展示,然后閱讀的順序還是默認(rèn)的從左往右(lr:left-right)丘跌,也就是僅僅是水平變垂直袭景。
下面是各個(gè)值下的中英文表現(xiàn)對(duì)照(參考自MDN):
//zxx: 大家會(huì)發(fā)現(xiàn)英文字符橫過來了,可以試試使用text-orientation:upright讓其直立闭树,IE不支持耸棒,F(xiàn)ireFox, Chrome支持。
下面來看下老IE瀏覽器的語法报辱,由于歷史原因与殃,顯得相當(dāng)?shù)膹?fù)雜,IE官方文檔顯示如下:
-ms-writing-mode: lr-tb | rl-tb | tb-rl | bt-rl | tb-lr | bt-lr | lr-bt | rl-bt | lr | rl | tb
根據(jù)自己的測試(非原生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這兩個(gè)值衣屏,但這和自己的測試不符躏升,我覺得可能是原生IE7瀏覽器,但我沒有原生IE7狼忱,沒有進(jìn)行過測試膨疏,因此,此說法(原生IE7支持)只是自己的推測钻弄。
我扳指頭數(shù)了數(shù)佃却,IE瀏覽器下的關(guān)鍵字值多達(dá)11個(gè),正好可以組個(gè)足球隊(duì)窘俺,
lr-tb
IE7+瀏覽器支持饲帅。初始值。內(nèi)容從左往右(left-right)瘤泪,從上往下(top-bottom)水平流動(dòng)灶泵,以及下一行水平元素在上一行元素的下面,所有符號(hào)都是直立定位对途。大部分的書寫系統(tǒng)都是使用這種布局赦邻。
rl-tb
IE7+瀏覽器支持。內(nèi)容從右往左(right-left实檀,從上往下(top-bottom)水平流動(dòng)惶洲,以及下一行水平元素在上一行元素的下面,所有符號(hào)都是直立定位膳犹。這種布局適合從右往左書寫的語言恬吕,例如阿拉伯語,希伯來語镣奋,塔安那文币呵,和敘利亞語怀愧。
tb-rl
IE7+瀏覽器支持侨颈。內(nèi)容從上往下(top-bottom),從右往左(right-left)垂直流動(dòng)芯义, 下一個(gè)垂直行定位于前一個(gè)垂直行的左邊哈垢,全角符號(hào)直立定位,非全角符號(hào)(也可以被稱作窄拉丁文或者窄假名符號(hào))順時(shí)針方向旋轉(zhuǎn)90°扛拨。這種布局多見于東亞排版耘分。
bt-rl
IE7+瀏覽器支持。內(nèi)容從下往上(bottom-top),從右往左(right-left)垂直流動(dòng)求泰, 下一個(gè)垂直行定位于前一個(gè)垂直行的左邊央渣,全角符號(hào)直立定位,非全角符號(hào)(也可以被稱作窄拉丁文或者窄假名符號(hào))順時(shí)針方向旋轉(zhuǎn)90°渴频。此布局多見于在東亞垂直排版從右往左的文本塊上芽丹。
tb-lr
IE8+瀏覽器支持。 內(nèi)容從上往下(top-bottom)卜朗,從左往右(left-right)垂直流動(dòng)拔第。下一個(gè)垂直行在前一個(gè)的右邊。
bt-lr
IE8+瀏覽器支持场钉。 內(nèi)容從下往上(bottom-top)蚊俺,從左往右(left-right)垂直流動(dòng)。
lr-bt
IE8+瀏覽器支持逛万。 內(nèi)容從下往上(bottom-top)泳猬,從左往右(left-right)水平流動(dòng)。下一個(gè)水平行在前一行的上面宇植。
rl-bt
IE8+瀏覽器支持暂殖。內(nèi)容從下往上(bottom-top), 從右往左(right-left)水平流動(dòng)当纱。
lr
IE9+瀏覽器支持呛每。在SVG和HTML元素上使用。等同于lr-tb.
rl
IE9+瀏覽器支持坡氯。在SVG和HTML元素上使用晨横。等同于rl-tb.
tb
IE9+瀏覽器支持。在SVG和HTML元素上使用箫柳。等同于tb-rl.
各個(gè)屬性值的表現(xiàn)如下(form微軟官網(wǎng))
一些說明:
相同的writing-mode屬性值并不會(huì)累加手形,例如父子均設(shè)置了writing-mode:tb-rl,只會(huì)渲染一次悯恍,子元素并不會(huì)2次“旋轉(zhuǎn)”库糠。
IE瀏覽器下,一個(gè)自身具有布局的元素(不是純文本之類元素)如果writing-mode屬性值和父元素不同涮毫,當(dāng)子元素的布局流變化的時(shí)候瞬欧,其父元素坐標(biāo)系統(tǒng)的可用空間會(huì)被充分利用。左邊文字太過術(shù)語罢防,大家可能不懂艘虎,我解釋下就是,IE瀏覽器下咒吐,當(dāng)布局元素從水平變成垂直的時(shí)候(舉個(gè)例子)野建,你就想象為元素在垂直方向是100%自適應(yīng)父元素高度的属划。所以,IE瀏覽器下(不包括IE13+)候生,元素vertical流的時(shí)候會(huì)發(fā)現(xiàn)高度高的嚇人同眯,布局和其他現(xiàn)代瀏覽器不一樣,就是這個(gè)原因唯鸭。
Chrome瀏覽器下目前還需要-webkit-私有前綴嗽测,雖然Chrome和Opera認(rèn)識(shí)tb-rl等老的IE屬性值,但是肿孵,僅僅是認(rèn)識(shí)而已唠粥,根本不鳥,沒有任何效果停做,聾子的耳朵——擺設(shè)晤愧!
需要關(guān)注的writing-mode屬性值
從著眼于直接開發(fā)的角度而言,雖然IE支持多達(dá)11個(gè)私有的屬性值蛉腌,但是官份,我們需要關(guān)注的,也就那么幾個(gè)烙丛,那究竟是哪幾個(gè)呢舅巷?
如果你的項(xiàng)目需要兼容IE7,則只有關(guān)注這兩個(gè)值就可以了:初始值lr-tb和tb-rl河咽,對(duì)應(yīng)于CSS3規(guī)范中的horizontal-tb和vertical-rl钠右!其他9個(gè)屬性值就讓它們?nèi)ミ^家家好了。
如果你的項(xiàng)目只需要兼容IE8+忘蟹,恭喜你飒房,你可以和CSS3規(guī)范屬性完全對(duì)應(yīng)上了,而且IE8下的writing-mode要比IE7強(qiáng)大的多媚值。我們需要關(guān)注:初始值lr-tb,tb-rl以及tb-lr狠毯,分別對(duì)應(yīng)于CSS3中的horizontal-tb,vertical-rl以及vertical-lr。
看上去復(fù)雜的屬性是不是變得很簡單了褥芒,重新整一個(gè)實(shí)戰(zhàn)版:
writing-mode: lr-tb | tb-rl | tb-lr (IE8+);
writing-mode: horizontal-tb | vertical-rl | vertical-lr;
對(duì)嚼松,大家只要記住上面幾個(gè)就可以了,enough! 因?yàn)樗^的垂直排版锰扶,實(shí)際web開發(fā)是很少很少遇到的献酗。
有同學(xué)可能要疑問了,既然writing-mode實(shí)現(xiàn)文本垂直排版場景下少辣,那還有什么學(xué)習(xí)的意義呢凌摄?
前面也提到了羡蛾,雖然writing-mode創(chuàng)造的本意是文本布局漓帅,但是,其帶來的文檔流向的改變,不僅改變了我們多年來正常的CSS認(rèn)知忙干,同時(shí)可以巧妙實(shí)現(xiàn)很多意想不到的需求和效果器予。
三、writing-mode不經(jīng)意改變了哪些規(guī)則捐迫?
writing-mode將頁面默認(rèn)的水平流改成了垂直流乾翔,顛覆了很多我們以往的認(rèn)知,基于原本水平方向才適用的規(guī)則全部都可以在垂直方向適用施戴!
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會(huì)重疊反浓;然而,這是CSS2文檔中的描述赞哗,在CSS3的世界中雷则,由于writing-mode的存在,這種說法就不嚴(yán)謹(jǐn)了肪笋,應(yīng)該是對(duì)立流方向的margin值會(huì)發(fā)生重疊月劈。換句話說,如果元素是默認(rèn)的水平流藤乙,則垂直margin會(huì)重疊猜揪;如果元素是垂直流,則水平margin會(huì)重疊坛梁。
您眼見為實(shí)而姐,您可以狠狠地點(diǎn)擊這里:CSS writing-mode與margin水平重疊demo
結(jié)果:
2. 可以使用margin:auto實(shí)現(xiàn)垂直居中
我們應(yīng)該都是的,傳統(tǒng)的web流中划咐,margin設(shè)置auto值的時(shí)候毅人,只有水平方向才會(huì)居中,因?yàn)槟J(rèn)width是100%自適應(yīng)的尖殃,auto才有計(jì)算值可依丈莺,而垂直方向,height沒有任何設(shè)置的時(shí)候高度絕不會(huì)自動(dòng)和父級(jí)高度一致送丰,因此缔俄,auto沒有計(jì)算空間,于是無法實(shí)現(xiàn)垂直居中器躏。但是俐载,在writing-mode的世界里,縱橫規(guī)則已經(jīng)改變登失,元素的行為表現(xiàn)發(fā)生了翻天覆地的變化遏佣。
圖片元素
我們先來看下,圖片元素margin:auto實(shí)現(xiàn)垂直居中揽浙,您可以狠狠地點(diǎn)擊這里:CSS writing-mode與圖片margin:auto垂直居中demo
其中圖片:
img { display: block; margin-top: auto; margin-bottom: auto; }
FireFox瀏覽器下(P白省流量):
但是状婶,在IE瀏覽器下意敛,卻沒有垂直居中~~
納尼?膛虫!難道IE不支持垂直流下的垂直居中草姻?非也,根據(jù)鄙人的測試稍刀,也就是圖片這類替換元素貌似不行撩独,普通的block元素都是可以的。
普通塊狀元素
您可以狠狠地點(diǎn)擊這里:CSS writing-mode與普通block元素margin:auto垂直居中demo
此時(shí)账月,不僅IE11 edge综膀,甚至IE8瀏覽器也都垂直居中了!
3. 可以使用text-align:center實(shí)現(xiàn)圖片垂直居中
前面提過局齿,auto無法實(shí)現(xiàn)IE瀏覽器下的圖片垂直居中僧须,如果我們非要讓圖片垂直居中,可以使用text-align:center项炼,您可以狠狠地點(diǎn)擊這里:CSS writing-mode與圖片text-align:center垂直居中demo
結(jié)果担平,之前病懨懨的IE瀏覽器活了:
由于我們直接使用內(nèi)聯(lián)特性進(jìn)行控制的,因此锭部,IE7瀏覽器也是可以實(shí)現(xiàn)text-align:center下的圖片垂直居中暂论,但是,根據(jù)我在IE11↘IE7下的測試拌禾,writing-mode需要寫在最后重置下(原生估計(jì)不會(huì)這樣)取胎,因此,完整的writing-mode代碼為:
.verticle-mode {
writing-mode: tb-rl;
-webkit-writing-mode: vertical-rl;
writing-mode: vertical-rl;
*writing-mode: tb-rl;
}
4. 可以使用text-indent實(shí)現(xiàn)文字下沉效果
這是真實(shí)項(xiàng)目例子湃窍,要增加一個(gè)按鈕按下文字下沉的效果闻蛀。如果你來實(shí)現(xiàn),你會(huì)這么實(shí)現(xiàn)呢您市?行高控制觉痛?但默認(rèn)文本就不居中(對(duì)于高度自適應(yīng)的按鈕,line-height下沉為了避免按鈕高度變化茵休,默認(rèn)是不能完全居中的)薪棒。padding+height精確控制,又略煩榕莺。然而俐芯,在writing-mode垂直流下,我們又有了新思路钉鸯,例如吧史,直接使用text-indent實(shí)現(xiàn)垂直方向的控制,沒想到吧唠雕,無需關(guān)心height高度padding間距大小贸营,任何按鈕都可以通用吨述,因?yàn)閠ext-indent不會(huì)影響元素原本的盒布局。
您可以狠狠地點(diǎn)擊這里:CSS writing-mode與text-indent文字下沉效果demo
包括IE7在內(nèi)的瀏覽器都是支持的(同上最后要*writing-mode覆蓋下)都是支持下沉的莽使。
為什么有如此的實(shí)現(xiàn)呢锐极?這要?dú)w功于中文笙僚,在垂直流排版的時(shí)候芳肌,中文是不會(huì)旋轉(zhuǎn)的,還是直立的肋层,也就是說亿笤,雖然我們?nèi)庋劭瓷先ノ淖譀]什么變化,但是栋猖,布局流已經(jīng)發(fā)生了變化净薛,以前類似text-indent/letter-spacing等水平控制屬性都作用在垂直方向了。
當(dāng)然蒲拉,我們這個(gè)例子比較巧的是按鈕文字只有一個(gè)肃拜,要是按鈕文字有多個(gè),怕是就沒這么輕松和絕妙了雌团。
5. 可以實(shí)現(xiàn)全兼容的icon fonts圖標(biāo)的旋轉(zhuǎn)效果
在老的IE瀏覽器下燃领,我們要實(shí)現(xiàn)小圖標(biāo)的旋轉(zhuǎn)效果是不是很煩?要使用IE的旋轉(zhuǎn)或翻轉(zhuǎn)濾鏡(filter)什么的锦援,具體可參見我之前的“CSS垂直翻轉(zhuǎn)/水平翻轉(zhuǎn)提高web頁面資源重用性”以及“IE矩陣濾鏡Matrix旋轉(zhuǎn)與縮放及結(jié)合transform的拓展”一文猛蔽。
現(xiàn)在我們有了writing-mode,我們就不要這么煩心了灵寺。
前面可能也注意到了曼库,當(dāng)writing-mode把文檔變成垂直流的時(shí)候,我們的英文和數(shù)字符號(hào)是會(huì)“躺著”顯示略板,也就是天然90°旋轉(zhuǎn)了毁枯。此時(shí),我們不妨腦洞大開一下叮称,假如我們使用icon fonts技術(shù)讓這些字符直接映射某個(gè)小圖標(biāo)后众,那豈不是松松實(shí)現(xiàn)小圖標(biāo)旋轉(zhuǎn)了,關(guān)鍵在于颅拦,就算是千年殺的IE6,IE7瀏覽器也是支持的啊蒂誉,這要比濾鏡什么的簡單多了!
眼見為實(shí)距帅,您可以狠狠地點(diǎn)擊這里:writing-mode實(shí)現(xiàn)icon fonts圖標(biāo)旋轉(zhuǎn)效果demo
就算是IE7瀏覽器右锨,也是很給力的!
6. 充分利用高度的高度自適應(yīng)布局
臥槽碌秸,不行了绍移,內(nèi)容太多了悄窃,五一前也寫不完了……
往下的7,8,9,10一起都略了吧~~
總之,放開自己的大腦蹂窖,理論上講轧抗,有了writing-mode,我們能夠做的事情比以前多了50%瞬测,就怕你想不到横媚,不怕做不到。
四月趟、writing-mode和direction的關(guān)系
上個(gè)月剛剛介紹了CSSdirection屬性灯蝴,也是個(gè)好東西,具體參見“CSS direction屬性簡介與實(shí)際應(yīng)用”孝宗,其可以改變文字的走向穷躁,那他和writing-mode是個(gè)什么關(guān)系呢?
writing-mode,direction,unicode-bidi(MDN文檔)是CSS世界中3大可以改變文本布局流向的屬性因妇。其中direction,unicode-bidi屬于近親问潭,經(jīng)常在一起使用,也是唯一兩個(gè)不受CSS3 all屬性影響的CSS屬性婚被,基本上就是和內(nèi)聯(lián)元素一起使用使用狡忙,且據(jù)說貌似為阿拉伯文字設(shè)計(jì)。
乍一看摔寨,writing-mode似乎包含了direction,unicode-bidi某些功能和行為去枷,例如vertical-rl的rl和direction的rtl值有相似之處,都是從右往左是复。然而删顶,實(shí)際上,兩者是沒有交集的淑廊。因?yàn)関ertical-rl此時(shí)的文檔流為垂直方向逗余,rl表示水平方向,此時(shí)再設(shè)置direction:rtl季惩,實(shí)際上值rtl改變的是垂直方向的內(nèi)聯(lián)元素的文本方向录粱,一橫一縱,沒有交集画拾。而且writing-mode可以對(duì)塊狀元素產(chǎn)生影響啥繁,直接改變了CSS世界的縱橫規(guī)則,要比direction強(qiáng)大和鬼畜的多青抛。且據(jù)說貌似為東亞文字設(shè)計(jì)旗闽。
然而,CSS的奇妙就在于,某些特性當(dāng)初可能就是問了某些圖文排版設(shè)計(jì)适室,但是嫡意,我們可以利用其帶來的特性,發(fā)揮自己的創(chuàng)造力捣辆,實(shí)現(xiàn)其他很多意想不到的效果蔬螟。所以,上面出現(xiàn)的三劍客都是非常好的資源汽畴。
五旧巾、writing-mode和*-start屬性的流機(jī)制
CSS3中出現(xiàn)了諸多*-start/*-end屬性(亦稱為CSS邏輯屬性),例如:margin-start/margin-end,border-start/border-end,padding-start/padding-end, 以及text-align:start/text-align:end聲明整袁。
下面問題來了菠齿,為什么會(huì)蹦出這么多*-start/*-end鬼佑吝?
那是因?yàn)楝F(xiàn)代瀏覽器加強(qiáng)了對(duì)流的支持坐昙,包括老江湖direction,以及最近年月跟進(jìn)的writing-mode芋忿。
在很久以前炸客,我們的認(rèn)知里,網(wǎng)頁布局就一種流向戈钢,就是從左往右痹仙,從上往下,因此殉了,我們使用margin-left/margin-right沒有任何問題开仰。但是,如果我們流是可以變化的薪铜,例如众弓,一張圖片距離左邊緣20像素,我們希望其文檔流是從右往左隔箍,同時(shí)距離右側(cè)是20像素谓娃,怎么辦?
此時(shí)蜒滩,margin-left:20px在圖片direction變化后滨达,就無效了;但是俯艰,margin-start就不會(huì)有此問題捡遍,所謂start, 指的是文檔流開始的方向,換句話說竹握,如果頁面是默認(rèn)的文檔流画株,則margin-start等同于margin-left,如果是水平從右往左文檔流,則margin-start等同于margin-right污秆。margin-end也是類似的劈猪。
webkit內(nèi)核的瀏覽器還支持*-before和*-end,默認(rèn)流下的margin-before近似于margin-top良拼,margin-after近似于margin-bottom战得,然而,規(guī)范貌似沒提及庸推,F(xiàn)ireFox也沒支持常侦,*-before和*-after出場的機(jī)會(huì)并不多,為什么呢贬媒?因?yàn)閷?shí)際上聋亡,配合writing-mode,*-start/*-end已經(jīng)可以滿足我們對(duì)邏輯位置的需求了际乘,水平和垂直都可以控制坡倔,對(duì)立方向適用老的*-top/*-bottom.
例如,我們?cè)O(shè)置writing-mode值為vertical-rl脖含,此時(shí)margin-start等同于margin-top罪塔,如果此時(shí)margin-start,margin-top同時(shí)存在养葵,會(huì)遵循權(quán)重和后來居上原則進(jìn)行相互的覆蓋征堪。
可以看到,場景不同关拒,margin-start的作用也不能佃蚜,能上能下,能左能右簡直在世百變星君着绊。
關(guān)于*-start/*-end以后有機(jī)會(huì)會(huì)具體展開論述谐算,這里就先點(diǎn)到為止,大家估計(jì)目前也不會(huì)在實(shí)際項(xiàng)目中使用畔柔。