[多行文本] 樣式怎麼沒了?

[多行文本] 樣式怎麼沒了?

背景

- “線上樣式有個小問題,有時間幫忙改下”
- “誒,什麼情況,訂單訊息的商品名稱不是做了多行文本截取了嗎,怎麼沒效果啦...”

是的,線上的多行文字截取沒了

技術概況

多行文本...通常情況下會採用如下方案:

.multi-ellipsis{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;}

百試不爽...

然後,webpack bundle 配置:

{test:/.(sass|scss)$/,use:ExtractTextPlugin.extract({fallback:'style-loader',use:[{loader:'css-loader',options:{minimize:true,},},{loader:'postcss-loader',options:{sourceMap:true,plugins:()=>[autoprefixer],},},{loader:'sass-loader',},],}),}

其中, postcss-loader使用了autoprefixer插件。

求解過程

1. 查看線上頁面元素樣式,發現元素下的樣式只有:

{display:-webkit-box;-webkit-line-clamp:2;}

2. 拉取最新代碼,本地構建,查看本地環境

“誒,我這是好的啊,是不是你電腦有問題啊,要不清個緩存吧,重啟也行(:”

@leohxj登場,用一句話指明了正確的解題思路:

雲構建的包依賴是會更新到最新的,你把本地node_modules 刪了重新裝一下試試

3. rm -rf node_modules & npm i ,然後再看本地環境

“果然如此啊,那就是哪個包升級所導致的了”

4.首先,懷疑的肯定是autoprefixer ,只有它會做類似的事情,先移除看看...

{loader:'postcss-loader',options:{sourceMap:true,plugins:()=>[],},}

編譯,wtf ... 怎麼還是沒有?難道還有包也乾這種事情啊...

5.中間過程甚是艱辛,暫且不表,反正最後發現了css loader的options的配置裡面其實是可以傳cssnano的配置參數的

是的,去翻代碼的看到了這樣的玩意:

如果css-loader 開啟了minimize, cssnano 的配置參數就可以通過options 傳進來了,比如:

{loader:'css-loader',options:{minimize:true,zindex:true,},}

就可以開啟構建中使用cssnano 做zindex 的優化了...

但是,有沒有發現有個貨不在裡面?是的,autoprefixer 啊! autoprefixer 是默認開啟的啊! fuck...

於是,options中設置autoprefixer: false構建試試,在了!這次沒消失!

敲黑板:css-loader中使用了cssnano, v0.26.0之前的版本中默認開啟autoprefixer.在0.26.0關掉了此配置。因此,如果你代碼中有使用到css-loader 並且無cssnano 配置參數,建議升級,減少代碼執行不確定性。

6. autoprefixer

autoprefixer issue 中,已經有相關的問題了,ai 給了回复:

一直在找構建工具的問題,忽略CSS 本身是否有問題...

7. CSS

我們的CSS寫法屬於Flexbox的old 2009 version ,目前我們常用的display: flex屬於現代的版本。

問題在於,因為有一定的瀏覽器支持度,2009 version 的寫法似乎已經被大家下意識的“標準”化了,大家都在使用這種方式處理多行文字截取的問題,但是始終都是要被拋棄的...

我們上面遇到的問題就是一種體現,也是一種警醒...

如果你不想去改代碼,可以指定構建時的瀏覽器支持度:

autoprefixer({browsers:['> 0.5%','last 2 versions']})

多行文本的正確姿勢

使用weird webkit flexbox去解決...的問題其實很奇怪,為什麼要用flexbox去解決這個問題,沒想過...而且給元素設置padding是會影響的:

without padding
with padding: 10px

那該用什麼方法解決呢?

最穩妥的方法應該是JS庫的介入了,比如: Clamp.js ,體積小且通用;

如果不想用JS 庫的話,我還看到了一種“歪”方法:

.text{position:relative;height:3.6em;/* exactly three lines */}.text:after{content:"";text-align:right;position:absolute;bottom:0;right:0;width:20%;height:1.2em;background:linear-gradient(toright,rgba(255,255,255,0),rgba(255,255,255,1)80%);}

定高n 倍,結尾處放置一個漸變塊...

當然,也可以:

.text:after{content:"...";text-align:right;position:absolute;bottom:0;right:0;height:1.2em;background:#fff;}

但是這種容易把字截斷,不可控...

結語

如果你正在尋找方法,實現多行文字截取,可以考慮使用正確的姿勢;

如果你已經遇到了上述同樣的問題,建議:

  1. 把css-loader 升級到0.28 以上版本( autoprefixer 默認不開啟);
  2. 把autoprefixer升級到8.0以上版本,並指定browsers,通常為: ['> 1%', 'last 2 versions']

重要的備註

1. css-loader 在0.27 後,cssnano 的參數移到了option.minimize 中,即:

{minimize:{zindex:true}}

2. autoprefixer 8.0 依賴的browserslist@3.0.0, 在browserslist 3.0 版本中,對默認值做了變更:

你也可以使用默認值,但是要去掉not dead ...顧名思義,old version supporter無人權...

Rematch: 重新設計Redux

Promise 使用技巧九則