如何?「文字輸入高亮」的效果,「文字輸入高亮」
價值 | 思考 | 共鳴
簡評:TripAdvisor(中文網站為「貓途鷹」)的搜尋輸入框有文字高亮的效果很有意思,本文將分享如何一步一步建立這種效果。
即為 TripAdvisor 搜尋輸入框的「文字輸入高亮」效果,這個實現涉及 CSS 和 JavaScript 的知識。
TripAdvisor 的搜尋輸入框
這是已完成的 CodePen:Tripadvisor input highlight
1. 我們首先建立一個簡單的 React 組件
class App extends React.Component {
render() {
return (
<div className='input-wrapper'>
<input
placeholder='Search...'
spellCheck={false}
/>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
添加 CSS:
$input-font-size: 30px;
$input-line-height: 70px;
$font-family: Roboto Slab, sans-serif;
body {
background-color: #222222;
}
.input-wrapper {
width: 500px;
margin: 50px auto;
}
input {
height: 60px;
width: 100%;
min-width: 100%;
padding: 0;
border-radius: 0;
line-height: $input-line-height;
color: white;
font-size: $input-font-size;
border: none;
outline: none;
border-bottom: 3px solid #333333;
font-family: $font-family;
}
添加 HTML 容器:
<div id="root"></div>
之後我們就得到這個基本文字輸入介面:
2. 添加邊界
這一步實現痛點在於寬度需要與文本的末尾保持一致,也需要與任何font-family
和font-size
保持協同。
由於輸入元素width
是固定的,我們需要一些其他方法來檢測文本的末尾。
我們通過提供一個道具來將輸入從非受控狀態切換到受控狀態value
,於是 React 組件現在是這樣子的:
class App extends React.Component {
render() {
return (
<div className='input-wrapper'>
<input
placeholder='Search...'
spellCheck={false}
value='basic input, bottom border'
/>
<span className='input-highlight'>
basic input, bottom border
</span>
</div>
);
}
}
添加以下 CSS 規則input-highlight
注意:我們在這裡使用 SCSS 變數來確保和font
之間的屬性相同:inputspan
.input-highlight {
font-size: $input-font-size;
line-height: $input-line-height;
font-family: $font-family;
max-width: 100%;
}
效果是這樣:
接下來,添加一個頂部邊框span
和位置,使其邊框疊加輸入的底部邊框。
.input-highlight {
font-size: $input-font-size;
line-height: $input-line-height;
font-family: $font-family;
max-width: 100%;
border-top: 3px solid white;
position: absolute;
left: 0;
bottom: 0;
height: 0;
}
.input-wrapper {
width: 500px;
margin: 50px auto;
position: relative;
}
span 元素以文本結尾,這使得它的寬度與輸入文本寬度一致。
現在,簡單的部分是:每次輸入內容發生變化時,我們使用 JavaScript 來更新跨度中的文本。我們將使用 Reactstate
來同時更新輸入和跨度的值。
這是我們更新的組件:
class App extends React.Component {
constructor() {
super();
this.state = {
inputValue: ''
};
this.onInputChange = this.onInputChange.bind(this);
}
onInputChange(e) {
const { value } = e.target;
this.setState({
inputValue: value
});
}
render() {
const { inputValue } = this.state;
return (
<div className='input-wrapper'>
<input
onChange={this.onInputChange}
placeholder='Search...'
value={inputValue}
spellCheck={false}
/>
<span className='input-highlight'>
{ inputValue.replace(/ /g, "\u00a0") }
</span>
</div>
);
}
}
.replace(/ /g, "\u00a0")
這部分是 React 正確處理空間所必需的。
然後,通過將以下行添加到input-highlight
CSS 選取器來隱藏該跨度:
color: transparent;
user-select: none;
overflow: hidden;
我們需要overflow: hidden
跨度來限制其寬度,否則會導致容器水平展開
3. 大功告成
最後一步是為高光添加不同的onFocus
顏色。
要做到這一點,我們需要一種基於輸入的焦點狀態來設定範圍的方式,我們將使用 CSS 兄弟選取器(+
)。
這裡是完整input
選取器的代碼,包括兄弟選取器input-highlight
:
input {
height: 60px;
width: 100%;
min-width: 100%;
padding: 0;
border-radius: 0;
line-height: $input-line-height;
color: white;
font-size: $input-font-size;
border: none;
outline: none;
border-bottom: 3px solid #333333;
font-family: $font-family;
&:focus {
+ .input-highlight {
border-top: 3px solid #fbc91b;
}
}
}
大概就這樣 ~
英文原文:Text input highlight, TripAdvisor style
舊文推薦:
如何用 CSS 網格快速做出網站原型
怎麼做 Web API 版本控制?
節約 Web 開發時間的 67 個工具、庫和資源
▼點擊閱讀原文擷取文中連結