CSS 自適應內容寬度的輸入框

XboxYan發表於2021-11-29

通常我們見到的輸入框都是寬度固定的,但有時也會碰到自適應內容寬度的,像這樣

Kapture 2021-11-25 at 19.58.26

目前我所知道的有兩種方式,相信不難找到

  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;
}

還不太瞭解這個屬性的可以參考這篇文章:理解CSS3 max/min-content及fit-content等width值 « 張鑫旭-鑫空間-鑫生活 (zhangxinxu.com)

但是,在 input 中,這些都不好使了,從開發者工具也可以看到,input 還有一層 shadow-root

image-20211127162956868

並且瀏覽器也沒有暴露出相關的選擇器供開發者使用,因此,僅僅通過常規方式是不能實現自適應內容寬度的

二、下劃線樣式

看到效果圖中的輸入框能想到什麼?沒錯,就是下劃線。下劃線是文字修飾的一種,是跟隨文字走的,所以去除 input 的邊框後,加上下劃線

input{
  border: 0;
  outline: 0;
  text-decoration: 4px solid underline;
}

效果如下

Kapture 2021-11-28 at 11.53.35

下劃線確實出來了,而且也是跟隨輸入內容的,不過有點貼的太緊了

三、下劃線偏移

為了解決上述這個問題,需要用到一個新的 CSS 屬性 text-underline-offset,表示下劃線偏移位置。目前來說,相容性還算不錯,除了 IE,主流瀏覽器均支援了

image-20211128120100256

現在,給下劃線偏移一點距離

input{
  /* */
  text-underline-offset: 10px;
}

下劃線居然不見了!如下text-underline-offset 從 0px → 10px 的變化

Kapture 2021-11-28 at 12.40.08

這是由於內部尺寸的問題,下劃線已經偏移出容器之外了,試著給 input 新增高度,比如

input{
  /* */
  height: 60px;
  text-underline-offset: 10px;
}

但是,沒什麼效果

image-20211128124645027

從開發者工具中可以看到,外面設定的高度並不能影響到內部尺寸,所以內部仍然是預設的高度

image-20211128121523848

那麼,還有什麼辦法可以改變高度呢?

答案就是行高line-height

input{
  /* */
  line-height: 2;
  text-underline-offset: 10px;
}

行高屬於文字屬性,可以繼承到內部,這樣內部尺寸就直接被撐開了,下劃線也可見了

Kapture 2021-11-28 at 12.21.05

四、預設最小寬度

由於使用的是下劃線,當輸入框沒有內容時,或者僅僅只有 placeholder,下劃線是不存在的,比如

<input placeholder="請輸入...">

效果如下

Kapture 2021-11-28 at 12.24.29

可能覺得有些不好看,希望加上一個最小寬度的下劃線(當然需要設計來定奪)

這時,可以用線性漸變畫一條下劃線就可以了

input{
  background: linear-gradient(currentColor,currentColor) center bottom 6px no-repeat;
  background-size: 10rem 4px;
}

這樣就有一個類似最小寬度的效果了

Kapture 2021-11-28 at 12.28.41

需要注意的是,下劃線的位置和線性漸變的位置要保持一致

五、聚焦的樣式

現在加上一點聚焦的樣式,看起來更像一個輸入邊框,下劃線需要改變顏色,然後剛才的線性漸變也需要改變顏色

input:focus{
  text-decoration-color: dodgerblue;
  background-image: linear-gradient(dodgerblue,dodgerblue)
}

這樣就實現了文章開頭的效果

Kapture 2021-11-25 at 19.58.26

完整程式碼可以訪問:auto input (codepen.io)

六、總結和說明

以上介紹了一種全新的可以實現自適應內容寬度的純 CSS 方案,用到了平時不太起眼的下劃線相關樣式,如果你的專案不用相容 IE,也剛好有這方面的需求,就可以放心用起來了,不過,就算用不上,也可以學習一下思路。下面總結一下要點:

  1. input 是一個可替換元素
  2. 下劃線是跟隨文字的,而不是容器
  3. 現在有一個全新的 text-underline-offset 可以用來控制下劃線的偏移
  4. 輸入內容為空時下劃線也就不存在了
  5. 利用 CSS 漸變可以繪製一個下劃線
  6. 下劃線顏色可以通過文字修飾顏色 text-decoration-color 修改

還有一個小細節時,input 其實是設定了寬度為 100% 的,也就是整行都可以輸入,只是視覺上看著好像是下劃線那一部分是輸入框而已,算是一個小小的障眼法。如果覺得還不錯,對你有幫助的話,歡迎點贊、收藏、轉發❤❤❤

相關文章