[多行文本] 樣式怎麼沒了?
背景
- 「線上樣式有個小問題,有時間幫忙改下」
- 「誒,什麼情況,訂單信息的商品名稱不是做了多行文本截取了嗎,怎麼沒效果啦 ...」
是的,線上的多行文字截取沒了
技術概況
多行文本...
通常情況下會採用如下方案:
.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 是會影響的:
那該用什麼方法解決呢?
最穩妥的方法應該是 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( to right, 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;}
但是這種容易把字截斷,不可控 ...
結語
如果你正在尋找方法,實現多行文字截取,可以考慮使用正確的姿勢;
如果你已經遇到了上述同樣的問題,建議:
- 把 css-loader 升級到 0.28 以上版本 ( autoprefixer 默認不開啟 );
- 把 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 無人權 ...
推薦閱讀:
※用 cooking 搭建一個多頁面易配置的 Vue 2 項目(進階篇)
※webpack 4.0.0-alpha.3 新功能:JSON Tree Shaking
※你不知道的webpack和webpack-dev-server高級玩法
※用 webpack 構建 node 後端代碼,使其支持 js 新特性並實現熱重載
※React學習資源匯總