博客 / 詳情

返回

這 5 個冷門的 HTML 標籤,能讓你少寫 100 行 JS

🧑‍💻 寫在開頭

點贊 + 收藏 === 學會🤣🤣🤣

大家好!😁。

Code Review 的時候,我最怕看到什麼?

不是複雜的算法,也不是什麼正則。而是明明一個 HTML 標籤就能搞定的事,有人非要寫幾百行 JS + CSS 去重新發明輪子

前幾天,我看到一個新同學為了寫一個摺疊面板(Accordion),引入了一個重型的第三方庫,還寫了一堆 useStateonClick 和動畫邏輯。

我默默地把他的代碼全刪了,換成了 3 行 <details>。他看我的眼神,彷彿在看一個外星人🤣。

在 2025 年的今天,瀏覽器原生 HTML 的能力早已今非昔比。很多我們習慣用 JS 去模擬的交互,現在不僅有原生支持,而且性能更好、兼容性更強、無障礙(a11y)更完善

今天,我就來盤點 5 個被嚴重低估的HTML標籤👇。


<details> & <summary>:摺疊組件

你是不是還在寫這樣的 React 代碼?

// JS 模擬版
const [isOpen, setIsOpen] = useState(false);
return (
  <div className="accordion">
    <div className="header" onClick={() => setIsOpen(!isOpen)}>
      點擊展開 {isOpen ? '⬆️' : '⬇️'}
    </div>
    {isOpen && <div className="content">...</div>}
  </div>
);

為了這個功能,你還得寫 CSS 動畫,還得處理鍵盤事件(Tab 鍵能不能選到?回車能不能展開?等等)。

HTML 原生寫法:

<details>
  <summary>點擊展開</summary>
  <div class="content">
    這裏是展開後的內容,原生支持 Ctrl+F 頁內搜索!
  </div>
</details>
  • 沒有任何JS:自帶點擊展開/收起交互。
  • 無障礙(a11y)滿分:屏幕閲讀器能完美識別,Tab 鍵、回車鍵原生支持。
  • 頁內搜索:這是 JS 模擬版最大的痛點。如果內容被 JS 隱藏了(display: none),瀏覽器的 Ctrl+F 往往搜不到。但 <details> 裏的內容,即使摺疊,瀏覽器也能搜到並自動展開!

ScreenShot_2026-02-05_122617_090

 配合 CSS 👇

details {
  border: 1px solid #ccc;
  border-radius: 6px;
  padding: 8px;
}

summary {
  cursor: pointer;
  font-weight: bold;
}

/* 包住內容,讓它能動畫高度 */
details > .content {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: max-height .45s ease, opacity .3s ease;
}

/* details 處於 open 狀態時 */
details[open] > .content {
  max-height: 200px; /* 你內容高度大概多少設多少,足夠大即可 */
  opacity: 1;
}

依然可以做動畫。


<dialog>:彈窗組件

寫模態框(Modal)是前端最大的坑之一。你需要考慮:

  • z-index 層級會不會被遮擋?
  • 點擊遮罩層關閉?
  • Focus Trap(焦點鎖定) :打開彈窗後,Tab 鍵不能跑到底層頁面去。
  • 按下 Esc 鍵關閉?

為了解決這些,我們通常會引入 Antd Modal 或者 React Portal。但在輕量級場景下,原生 <dialog> 才是神🫅。

HTML 原生

<dialog id="myModal">
  <form method="dialog">
    <p>這是一個原生模態框</p>
    <button>關閉(自動)</button>
  </form>
</dialog>

<button onclick="myModal.showModal()">打開彈窗⏏</button>

ScreenShot_2026-02-05_122626_722

  1. Top Layer(頂層特性) :瀏覽器會把它渲染在所有 DOM 的最上層,徹底無視父元素的 z-index 和 overflow: hidden
  2. ::backdrop 偽元素:直接用 CSS 定製遮罩層樣式。
/* 背景遮罩 */
dialog::backdrop {
    background: rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(3px);
    transition: opacity .3s ease;
}
  1. 原生交互:自帶 Esc 關閉,自帶焦點管理,表單提交自動關閉。

<datalist>:搜索自動補全

當產品經理要求做一個帶搜索建議的輸入框時,你的第一反應是不是:“快!引入 Select2 或者 Antd AutoComplete!😖

且慢。如果只是簡單的建議列表,幾 KB 的 JS 庫都顯得太重了。

HTML 原生版:

<label>選擇你喜歡的框架:</label>
<input list="frameworks" />

<datalist id="frameworks">
  <option value="React">
  <option value="Vue">
  <option value="Svelte">
  <option value="Angular">
  <option value="Solid">
</datalist>
  1. 模糊搜索:瀏覽器原生支持模糊匹配(打 u 會出來 Vue)。
  2. 響應式:在手機上,它會調用系統原生的下拉選擇 UI,體驗比網頁模擬的更順滑。
  3. 解耦:它只是一個建議列表,用户依然可以輸入列表裏沒有的值(這點和 Select 不同)。

<fieldset> & disabled:一鍵禁用整個表單

場景:用户點擊提交按鈕後,為了防止重複提交,我們需要禁用表單裏的所有輸入框

JS 笨辦法:

// 還要一個個去拿 DOM,或者維護一個 loading 狀態傳給所有組件
inputs.forEach(input => input.disabled = true);
buttons.forEach(btn => btn.disabled = true);
HTML 原生寫法:
<form>
  <fieldset disabled id="login-group">
    <legend>登錄</legend>
    <input type="text" placeholder="用户名">
    <input type="password" placeholder="密碼">
    <button>提交</button>
  </fieldset>
</form>

<script>
  // 一行代碼搞定狀態切換
  document.getElementById('login-group').disabled = true; 
</script>

ScreenShot_2026-02-05_122634_940

 

這是一個極好的分組思維。通過給 <fieldset> 設置 disabled,瀏覽器會自動禁用內部所有的 <input>, <select>, <button>。不用寫循環,不用維護複雜的 State。


<input type="file" capture>:H5 調用手機相機

場景:業務需要用户上傳一張照片,可以是相冊選的,也可以是當場拍的

很多新手的反應是:是不是要接微信 JSSDK?是不是要寫個 Bridge 調原生 App 能力?

答案是不需要!

HTML 原生:

<input type="file" capture="environment" accept="image/*">

只要加上 capture 屬性,在移動端(iOS/Android)點擊上傳時,系統會直接拉起相機,而不是讓你去選文件。拍完照後,你拿到的就是一個標準的 File 對象。

不需要什麼 JS SDK,實現原生級體驗👍。


我總是強調 最好的代碼,是沒有代碼!

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文檔,大家一起討論學習,一起進步。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.