目前我所知道的有兩種方式,相信不難找到
1、給普通 div 標簽設置 contenteditable="true",設置 inline-block 以后,就可以自適應內容寬度了
2、將 input 的輸入內容同步到一個透明的 div ,父級寬度跟隨 div 的寬度,然后設置 input 為絕對定位並覆蓋在上面,設置寬度為 100%
都是很不錯的方案。這次帶來一個全新的純 CSS 實現方案,相信能帶來不一樣的感受
一、可替換元素
首先,input 不同於普通的 div 元素,它是一個可替換元素在 CSS 中,可替換元素(replaced element)的展現效果不是由 CSS 來控制的。這些元素是一種外部對象,它們外觀的渲染,是獨立於 CSS 的。
正常情況下,如果希望一個元素寬度由內部決定,可以設置
div{
display: inline-block;
}
在 CSS3 中,還可以通過另一種方式實現
div{
width: fit-content;
}
但是,在 input 中,這些都不好使了,從開發者工具也可以看到,input 還有一層 shadow-root
並且瀏覽器也沒有暴露出相關的選擇器供開發者使用,因此,僅僅通過常規方式是不能實現自適應內容寬度的。
二、下划線樣式
看到效果圖中的輸入框能想到什么?沒錯,就是下划線。前端培訓下划線是文本修飾的一種,是跟隨文字走的,所以去除 input 的邊框后,加上下划線
input{
border: 0;
outline: 0;
text-decoration: 4px solid underline;
}
下划線確實出來了,而且也是跟隨輸入內容的,不過有點貼的太緊了
三、下划線偏移
為了解決上述這個問題,需要用到一個新的 CSS 屬性 text-underline-offset,表示下划線偏移位置。目前來說,兼容性還算不錯,除了 IE,主流瀏覽器均支持了。
現在,給下划線偏移一點距離
input{
/* */
text-underline-offset: 10px;
}
下划線居然不見了!如下text-underline-offset 從 0px → 10px 的變化
這是由於內部尺寸的問題,下划線已經偏移出容器之外了,試着給 input 添加高度,比如
input{
/* */
height: 60px;
text-underline-offset: 10px;
}
但是,沒什么效果。
從開發者工具中可以看到,外面設置的高度並不能影響到內部尺寸,所以內部仍然是默認的高度
那么,還有什么辦法可以改變高度呢?
答案就是行高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;
}
這樣就有一個類似最小寬度的效果了
需要注意的是,下划線的位置和線性漸變的位置要保持一致
五、聚焦的樣式
現在加上一點聚焦的樣式,看起來更像一個輸入邊框,下划線需要改變顏色,然后剛才的線性漸變也需要改變顏色
input:focus{
text-decoration-color: dodgerblue;
background-image: linear-gradient(dodgerblue,dodgerblue)
}
六、總結和說明
以上介紹了一種全新的可以實現自適應內容寬度的純 CSS 方案,用到了平時不太起眼的下划線相關樣式,如果你的項目不用兼容 IE,也剛好有這方面的需求,就可以放心用起來了,不過,就算用不上,也可以學習一下思路。下面總結一下要點:
input 是一個可替換元素
下划線是跟隨文本的,而不是容器
現在有一個全新的 text-underline-offset 可以用來控制下划線的偏移
輸入內容為空時下划線也就不存在了
利用 CSS 漸變可以繪制一個下划線
下划線顏色可以通過文本修飾顏色 text-decoration-color 修改
還有一個小細節時,input 其實是設置了寬度為 100% 的,也就是整行都可以輸入,只是視覺上看着好像是下划線那一部分是輸入框而已,算是一個小小的障眼法。