巧妙實現(xiàn)自適應寬度的內容輸入框
本文由閱文大佬 XBOXYAN 授權原創(chuàng)轉發(fā)?
原文鏈接:https://juejin.cn/post/7035819149016170510
通常我們見到的輸入框都是寬度固定的,但有時也會碰到自適應內容寬度的,像這樣

目前我所知道的有兩種方式,相信不難找到
給普通 div 標簽設置 contenteditable="true",設置 inline-block 以后,就可以自適應內容寬度了 將 input 的輸入內容同步到一個透明的 div ,父級寬度跟隨 div 的寬度,然后設置 input 為絕對定位并覆蓋在上面,設置寬度為 100%
都是很不錯的方案。這次帶來一個全新的純 CSS 實現(xiàn)方案,相信能帶來不一樣的感受
一、可替換元素
首先,input 不同于普通的 div 元素,它是一個可替換元素
在 CSS 中,**可替換元素**(**replaced element**)[1]的展現(xiàn)效果不是由 CSS 來控制的。這些元素是一種外部對象,它們外觀的渲染,是獨立于 CSS 的。
正常情況下,如果希望一個元素寬度由內部決定,可以設置
div{
??display:?inline-block;
}
在 CSS3 中,還可以通過另一種方式實現(xiàn)
div{
??width:?fit-content;
}
還不太了解這個屬性的可以參考這篇文章:理解CSS3 max/min-content及fit-content等width值 ? 張鑫旭-鑫空間-鑫生活 (zhangxinxu.com)[2]
但是,在 input 中,這些都不好使了,從開發(fā)者工具也可以看到,input 還有一層 shadow-root

并且瀏覽器也沒有暴露出相關的選擇器供開發(fā)者使用,因此,僅僅通過常規(guī)方式是不能實現(xiàn)自適應內容寬度的
二、下劃線樣式
看到效果圖中的輸入框能想到什么?沒錯,就是下劃線。下劃線是文本修飾[3]的一種,是跟隨文字走的,所以去除 input 的邊框后,加上下劃線
input{
??border:?0;
??outline:?0;
??text-decoration:?4px?solid?underline;
}
效果如下

下劃線確實出來了,而且也是跟隨輸入內容的,不過有點貼的太緊了
三、下劃線偏移
為了解決上述這個問題,需要用到一個新的 CSS 屬性 text-underline-offset,表示下劃線偏移位置。目前來說,兼容性還算不錯,除了 IE,主流瀏覽器均支持了

現(xiàn)在,給下劃線偏移一點距離
input{
??/*?*/
??text-underline-offset:?10px;
}
下劃線居然不見了!如下text-underline-offset 從 0px → 10px 的變化

這是由于內部尺寸的問題,下劃線已經(jīng)偏移出容器之外了,試著給 input 添加高度,比如
input{
??/*?*/
??height:?60px;
??text-underline-offset:?10px;
}
但是,沒什么效果

從開發(fā)者工具中可以看到,外面設置的高度并不能影響到內部尺寸,所以內部仍然是默認的高度

那么,還有什么辦法可以改變高度呢?
答案就是行高line-height!
input{
??/*?*/
??line-height:?2;
??text-underline-offset:?10px;
}
行高屬于文本屬性,可以繼承到內部,這樣內部尺寸就直接被撐開了,下劃線也可見了

四、默認最小寬度
由于使用的是下劃線,當輸入框沒有內容時,或者僅僅只有 placeholder,下劃線是不存在的,比如
<input?placeholder="請輸入...">
效果如下

可能覺得有些不好看,希望加上一個最小寬度的下劃線(當然需要設計來定奪)
這時,可以用線性漸變畫一條下劃線就可以了
input{
??background:?linear-gradient(currentColor,currentColor)?center?bottom?6px?no-repeat;
??background-size:?10rem?4px;
}
這樣就有一個類似最小寬度的效果了

需要注意的是,下劃線的位置和線性漸變的位置要保持一致
五、聚焦的樣式
現(xiàn)在加上一點聚焦的樣式,看起來更像一個輸入邊框,下劃線需要改變顏色,然后剛才的線性漸變也需要改變顏色
input:focus{
??text-decoration-color:?dodgerblue;
??background-image:?linear-gradient(dodgerblue,dodgerblue)
}
這樣就實現(xiàn)了文章開頭的效果

完整代碼可以訪問:auto input (codepen.io)[4]
六、總結和說明
以上介紹了一種全新的可以實現(xiàn)自適應內容寬度的純 CSS 方案,用到了平時不太起眼的下劃線相關樣式,如果你的項目不用兼容 IE,也剛好有這方面的需求,就可以放心用起來了,不過,就算用不上,也可以學習一下思路。下面總結一下要點:
input 是一個可替換元素 下劃線是跟隨文本的,而不是容器 現(xiàn)在有一個全新的 text-underline-offset可以用來控制下劃線的偏移輸入內容為空時下劃線也就不存在了 利用 CSS 漸變可以繪制一個下劃線 下劃線顏色可以通過文本修飾顏色 text-decoration-color修改
還有一個小細節(jié)時,input 其實是設置了寬度為 100% 的,也就是整行都可以輸入,只是視覺上看著好像是下劃線那一部分是輸入框而已,算是一個小小的障眼法。如果覺得還不錯,對你有幫助的話,歡迎點贊、收藏、轉發(fā)???
參考資料
可替換元素(replaced element): https://developer.mozilla.org/zh-CN/docs/Web/CSS/Replaced_element
[2]理解CSS3 max/min-content及fit-content等width值 ? 張鑫旭-鑫空間-鑫生活 (zhangxinxu.com): https://www.zhangxinxu.com/wordpress/2016/05/css3-width-max-contnet-min-content-fit-content/
[3]文本修飾: https://developer.mozilla.org/zh-CN/docs/Web/CSS/text-decoration
[4]auto input (codepen.io): https://codepen.io/xboxyan/pen/gOGYWRG
結語
「關注公眾號IQ前端,一個專注于CSS/JS開發(fā)技巧的前端公眾號,更多前端小干貨等著你喔」
歡迎關注 IQ前端,更多「CSS/JS開發(fā)技巧」只在公眾號推送
