HTML5中有很多十分有趣的標籤,相比於article
/section
等這些我們所熟知並且已經應用的標籤,還有些標籤或者因為相容性,或者因為還處於草稿階段而不那麼為人所知。在使用Bootstrap
/Element
等UI元件時,常常看到某個標籤上會應用一些如role="dialog"
的不常見的屬性,這是因為HTML語義化的需要。role
屬性主要供有障礙人士使用,作用是告訴如螢幕朗讀程式等輔助程式當前元素所扮演的角色。由於HTML5標籤本身已經實現了語義化,role
屬性不建議被新增。而對於一些老瀏覽器或者一些模擬元素(如div模擬dialog),role
屬性則應該被註明。Bootstrap
中有很多註明了role
屬性的元件,而這些元件有一部分已經被HTML5所實現,並已經標籤化,如dialog
,progress
等。當然,這些標籤的原始樣式各個瀏覽器不統一,並且可以說很簡陋,對此,可以通過一些自定義CSS樣式來進行優化。
特別說明:本文介紹的標籤,目前相容性都很差(雖然部分標籤有對應的polyfill),僅供學習和了解,請勿用於生產環境。同時,DEMO僅限Chrome瀏覽器預覽。
專案地址
可以在github上關注該專案,目前已經實現了dialog
,progress
,range
,collapse
等元件,後續會陸續總結其他。
Dialog
dialog
元素表示一個對話方塊或者互動式視窗元件.
dialog
元素可以說完全滿足了對互動的需求,如我們所期望的完全的在頁面上水平垂直居中,智慧的啟用層置頂(無需手動設定z-index
), 共享backdrop
層等。並且diaolog
有對應的open(show,showModal)和close方法。dialog
的預設樣式如下圖:
自定義樣式
- 可以通過
::backdrop
偽類優化遮罩層
.nui-dialog::backdrop {
background-color: rgba(0, 0, 0, .5)
}
複製程式碼
open
屬性:當呼叫show
或者showModal
方法時,瀏覽器會自動為dialog
新增上open
的屬性,用來表示當前dialog
處於啟用狀態,因此可以通過給open
屬性新增動畫來實現dialog
啟用時的動畫效果
.nui-dialog[open] {
animation: slide-up 0.4s ease-out;
}
@keyframes slide-up {
0% {
opacity: 0;
transform: translate(0, 15px);
}
100% {
opacity: 1;
transform: translate(0, 0);
}
}
複製程式碼
JavaScript方法和事件
支援方法
show
: 啟用dialog
, 基於DOM流的位置顯示元素showModal
: 啟用dialog
, 推薦 .預設顯示在頁面的中心位置,並且常駐頂層(無需設定z-index
)close
: 用來關閉dialog
支援事件
close
:dialog
關閉時觸發cancel
:dialog
取消(如按esc
鍵)時觸發
虛擬碼
<script>
var dialog = document.getElementById('dialog')
button.addEventListener('click', function(e){
dialog.showModal() // or .show
})
closeBtn.addEventListener('close', function(e){
dialog.close() // dialog.close('type') 可以傳遞一個字串
})
// 當關閉時會觸發 close 事件
dialog.addEventListener('close', function(e) {
console.log(e) // e.type 就是呼叫close方法時傳遞的type字串,預設值為close
})
// 當取消時(如按esc鍵)會觸發 cancel 事件
dialog.addEventListener('cancel', function(e) {})
</script>
複製程式碼
為指定按鈕繫結關閉事件
通過事件代理,可以很方便的為標記了[data-dismiss="modal"][aria-label="Close"]
屬性的元素來邦定關閉事件。
<button type="button" class="nui-dialog__close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<a data-dismiss="modal" aria-label="Close">關閉</a>
複製程式碼
document.addEventListener('click', function (e) {
var target = e.target
var selector = '[data-dismiss="modal"][aria-label="Close"]'
if (target.matches(selector) || target.closest(selector)) {
var modal = target.closest('dialog')
modal && modal.close()
}
})
複製程式碼
Progress
progress
元素用來顯示一項任務的完成進度
預設樣式和修改後的樣式(自定義樣式採用Bootstrap中Progress bar的樣式)
自定義樣式的實現
::-webkit-progress-bar
: 偽類::-webkit-progress-bar
用來定義Progress bar層的樣式::-webkit-progress-value
: 偽類::-webkit-progress-value
用來定義Progress value層的樣式
:root {
--primary-color: #43a3fb;
}
.nui-progress::-webkit-progress-bar{
background-color: #e9ecef;
border-radius: 0;
}
.nui-progress::-webkit-progress-value{
background-color: var(--primary-color);
cursor: default;
}
複製程式碼
Collapse
利用
details
和summary
標籤,實現摺疊皮膚的效果.
details
用於描述文件的細節,與summary
標籤配合使用可以為details
定義標題。標題是可見的,使用者點選標題時,會顯示出 details
自定義樣式
::-webkit-details-marker
:偽元素::-webkit-details-marker
可以用來定義或覆蓋list-item的樣式.一般情況下,設定::-webkit-details-marker
不可見,轉而為summary
元素新增一個::before/::after
的偽類來自定義icon樣式。然後再為details[open]
狀態下重新定義icon(::before/::after
)
.nui-collapse>.nui-collapse__title::-webkit-details-marker {
display: none;
}
/* normal */
.nui-collapse>.nui-collapse__title::before {
content: '';
position: absolute;
left: auto;
right: 0;
width: 6px;
height: 6px;
border: 1px solid var(--title-color);
border-right-width: 0;
border-bottom-width: 0;
transform: translate(-50%) rotate(135deg);
transition: transform .2s;
}
/* open */
.nui-collapse[open]>.nui-collapse__title::before {
transform: translate(-50%) rotate(225deg);
}
複製程式碼
- 利用
open
屬性,通過加入少許javascript程式碼,還可以實現手風琴效果
<div class="nui-collapse-accordion">
...
<details class="nui-collapse nui-collapse--right">
<summary class="nui-collapse__title">Title</summary>
<p class="nui-collapse__body">...</p>
</details>
...
</div>
<script>
var ARRAY_SLICE = Array.prototype.slice
document.addEventListener('click', function(e) {
var target = e.target
var selector = '.nui-collapse-accordion .nui-collapse__title'
if (target.matches(selector) || target.closest(selector)) {
var collapse = target.closest('.nui-collapse')
if (collapse) {
var group = collapse.closest('.nui-collapse-accordion')
if (group) {
ARRAY_SLICE.call(group.querySelectorAll('.nui-collapse')).forEach(function(el) {
if (el !== collapse) {
el.open = false
}
})
}
}
}
})
</script>
複製程式碼
Range
input[type="range"]元素顯示為滑塊,表示輸入型別用於應該包含指定範圍值的輸入欄位
自定義range
的樣式主要通過::-webkit-slider-runnable-track
,::-webkit-slider-thumb
來實現。
dialog
等目前相容性極差,離投入生產還尚遠。請勿用於生產環境中。
本文釋出於《我的部落格》