概觀
<b-overlay>
可用於遮蔽幾乎所有事物。範例使用案例有表單、表格、刪除確認對話框,或者任何你用於傳達應用程式正在執行背景工作、表示某個元件不可用,或提供其他脈絡訊息給最終使用者的場合。
<b-overlay>
可用於覆蓋 (包覆) 一個元素或元件 (預設行為),或放入 position: relative
元素的子層 (非包覆模式) 中。
覆蓋層可視性由 show
屬性控制。預設情況下不會顯示覆蓋層。
請注意,此元件只會視覺上遮蔽其內容 (或網頁)。有關其他無障礙詳細資訊和疑慮,請參閱以下 無障礙 區段。
預設包覆模式範例
<template>
<div>
<b-overlay :show="show" rounded="sm">
<b-card title="Card with overlay" :aria-hidden="show ? 'true' : null">
<b-card-text>Laborum consequat non elit enim exercitation cillum.</b-card-text>
<b-card-text>Click the button to toggle the overlay:</b-card-text>
<b-button :disabled="show" variant="primary" @click="show = true">
Show overlay
</b-button>
</b-card>
</b-overlay>
<b-button class="mt-3" @click="show = !show">Toggle overlay</b-button>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
}
}
</script>
選項
提供許多可供設定覆蓋層樣式的選項,以及於覆蓋層內提供自訂內容的選項。
覆蓋層背景色
你可以透過 variant
屬性控制背景背景色。此變體會轉換為 Bootstrap 中的其中一個 背景變體公用程式類別。透過 opacity
屬性控制背景的不透明度 (不透明度值範圍為 0
至 1
)。而背景模糊可透過 blur
<template>
<div>
<b-row>
<b-col lg="6" aria-controls="overlay-background">
<b-form-group label="Variant" label-for="bg-variant" label-cols-sm="4" label-cols-lg="12">
<b-form-select id="bg-variant" v-model="variant" :options="variants"></b-form-select>
</b-form-group>
<b-form-group label="Opacity" label-for="bg-opacity" label-cols-sm="4" label-cols-lg="12">
<b-input-group>
<b-form-input
id="bg-opacity"
v-model="opacity"
type="range"
number
min="0"
max="1"
step="0.01"
></b-form-input>
<b-input-group-append is-text class="text-monospace">
{{ opacity.toFixed(2) }}
</b-input-group-append>
</b-input-group>
</b-form-group>
<b-form-group label="Blur" label-for="bg-blur" label-cols-sm="4" label-cols-lg="12">
<b-form-select id="bg-blur" v-model="blur" :options="blurs"></b-form-select>
</b-form-group>
</b-col>
<b-col lg="6">
<b-overlay
id="overlay-background"
show
:variant="variant"
:opacity="opacity"
:blur="blur"
rounded="sm"
>
<b-card title="Card with overlay" aria-hidden="true">
<b-card-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</b-card-text>
<b-button disabled variant="primary">Button</b-button>
</b-card>
</b-overlay>
</b-col>
</b-row>
</div>
</template>
<script>
export default {
data() {
return {
variant: 'light',
opacity: 0.85,
blur: '2px',
variants: [
'transparent',
'white',
'light',
'dark',
'primary',
'secondary',
'success',
'danger',
'warning',
'info',
],
blurs: [
{ text: 'None', value: '' },
'1px',
'2px',
'5px',
'0.5em',
'1rem'
]
}
}
}
</script>
作為 variant
屬性的替代方案,你可以透過 bg-color
屬性指定一個 CSS 顏色字串值。當 bg-color
中提供一個值時,variant
屬性值會被忽略。
註解
- 某些瀏覽器不支援背景模糊(例如:IE 11)。
- 對於模糊效果要明顯可見,模糊處理需要比較高的不透明度。
淡出轉場
預設情況下,疊加層會在顯示或隱藏時使用 Bootstrap 的淡出轉場。你可以透過將 no-fade
屬性新增到 <b-overlay>
來停用淡出轉場。
預設的 spinner 造型
預設的疊加層內容類別是 border
類型的 <b-spinner>
。你可以透過下列屬性來控制 spinner 的外觀。
spinner-type
:目前支援的值為 border
(預設值)或 grow
。 spinner-variant
:spinner 的變異主題顏色。預設值為 null
,它會繼承目前的字體顏色。 spinner-small
:設定為 true
可以呈現一個小型 spinner。
<template>
<div>
<b-overlay
show
spinner-variant="primary"
spinner-type="grow"
spinner-small
rounded="sm"
style="max-width: 320px;"
>
<b-card title="Card with spinner style" aria-hidden="true">
<b-card-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</b-card-text>
<b-button disabled variant="primary">Button</b-button>
</b-card>
</b-overlay>
</div>
</template>
疊加層圓角
預設情況下,疊加層背景有方形的角。如果你要包覆的內容具有圓角,你可以使用 rounded
屬性將圓角套用至疊加層的角,以符合被遮蔽內容的圓角。
可能的取值為
true
(或空字串 ''
)套用預設(中)圓角 false
(預設值)不對背景疊加層套用任何圓角 sm
套用小型圓角 lg
套用大型圓角 pill
套用藥丸狀圓角 circle
套用圓形(或橢圓形)圓角 top
僅圓角前兩個角 bottom
僅圓角後兩個角 left
僅圓角左邊兩個角 right
僅圓角右邊兩個角
<template>
<div>
<b-button @click="show = !show">Toggle overlay</b-button>
<b-row class="text-center mt-3">
<b-col md="6">
<p>With rounding</p>
<b-overlay :show="show" class="d-inline-block" rounded="circle">
<b-img thumbnail rounded="circle" fluid src="https://picsum.photos/200/200/?image=54" alt="Image 1"></b-img>
</b-overlay>
</b-col>
<b-col md="6">
<p>Without rounding</p>
<b-overlay :show="show" class="d-inline-block">
<b-img thumbnail rounded="circle" fluid src="https://picsum.photos/200/200/?image=54" alt="Image 1"></b-img>
</b-overlay>
</b-col>
</b-row>
</div>
</template>
<script>
export default {
data() {
return {
show: true
}
}
}
</script>
自訂疊加層內容
透過選擇性的作用域插槽 overlay
來放置自訂的內容在疊加層(取代預設的 spinner)。
<template>
<div>
<b-overlay :show="show" rounded="sm" @shown="onShown" @hidden="onHidden">
<b-card title="Card with custom overlay content" :aria-hidden="show ? 'true' : null">
<b-card-text>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</b-card-text>
<b-card-text>Click the button to toggle the overlay:</b-card-text>
<b-button ref="show" :disabled="show" variant="primary" @click="show = true">
Show overlay
</b-button>
</b-card>
<template #overlay>
<div class="text-center">
<b-icon icon="stopwatch" font-scale="3" animation="cylon"></b-icon>
<p id="cancel-label">Please wait...</p>
<b-button
ref="cancel"
variant="outline-danger"
size="sm"
aria-describedby="cancel-label"
@click="show = false"
>
Cancel
</b-button>
</div>
</template>
</b-overlay>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
},
methods: {
onShown() {
this.$refs.cancel.focus()
},
onHidden() {
this.$refs.show.focus()
}
}
}
</script>
下列作用域屬性可用於 overlay
插槽
屬性 | 說明 |
spinnerVariant | spinner-variant 屬性的值 |
spinnerType | spinner-type 屬性的值 |
spinnerSmall | spinner-small 屬性的值 |
將互動內容放置在疊加層時,基於可及性考量,你應將焦點放在自訂內容的容器或疊加層內容中其中一個可對焦的控制項上。你可以監聽 <b-overlay>
shown
事件,以得知何時疊加層內容可在文件中使用。
覆蓋內容置中
預設情況下,覆蓋內容將在覆蓋區域內水平及垂直置中。如要停用置中,請將 no-center
屬性設定為 true
。
在以下範例中,我們設定了 no-center
屬性,並將自訂的覆蓋插槽內容絕對定位在右上方。
<template>
<div>
<b-overlay no-center show rounded="sm">
<template #overlay>
<b-icon
icon="stopwatch"
variant="info"
scale="2"
shift-v="8"
shift-h="8"
class="position-absolute"
style="top: 0; right: 0"
></b-icon>
</template>
<b-card title="Card with no-center overlay" aria-hidden="true">
<b-card-text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
</b-card-text>
<b-button disabled variant="primary">Button</b-button>
</b-card>
</b-overlay>
</div>
</template>
寬度
<b-overlay>
的預設寬度為 100%
。包覆內聯或內聯區塊元素時,您需要新增類別 d-inline-block
(例如 <b-overlay class="d-inline-block">
)。
您也可以使用寬度 公用程式類別 或 CSS 樣式來控制覆蓋包裝容器元素的寬度。
非包裝模式
預設情況下,<b-overlay>
會包裝預設插槽的內容。某些情況下,您可能想要隱藏父容器。請使用 no-wrap
屬性來停用包裝的呈現(並忽略預設插槽)。請注意,這需要將要隱藏的Ancestor元素設為相對定位(透過公用程式類別 'position-relative'
或 CSS 樣式 'position: relative;'
)。
<template>
<div>
<div class="position-relative p-4 bg-info">
<p class="text-light font-weight-bold">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
<b-card title="Card with parent overlay">
<b-card-text>Laborum consequat non elit enim exercitation cillum.</b-card-text>
<b-card-text>Click the button to toggle the overlay:</b-card-text>
<b-button :disabled="show" variant="primary" @click="show = true">
Show overlay
</b-button>
</b-card>
<p class="text-light font-weight-bold mb-0">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
<b-overlay :show="show" no-wrap>
</b-overlay>
</div>
<b-button class="mt-3" @click="show = !show">Toggle overlay</b-button>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
}
}
</script>
請注意,Bootstrap v4 的一些元件樣式有定義相對定位(例如卡片、資料列等)。您可能需要調整在標記中 <b-overlay>
的位置。
例如,<b-card>
有相對定位,因此您可以將 <b-overlay no-wrap>
放置為 <b-card>
的子代
<template>
<div>
<b-card header="Card header" footer="Card footer">
<b-media>
<template #aside>
<b-img
thumbnail
rounded="circle"
src="https://picsum.photos/72/72/?image=58"
alt="Image"
></b-img>
</template>
<p class="mb-0">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
</b-media>
<b-overlay :show="show" no-wrap></b-overlay>
</b-card>
<b-button @click="show = !show" class="mt-3">Toggle overlay</b-button>
</div>
</template>
<script>
export default {
data() {
return {
show: true
}
}
}
</script>
在 no-wrap
模式中,<b-overlay>
對於隱藏的元素將不會設定 aria-busy
屬性。您可能也想要在應用程式中使用 aria-live
區域,以向螢幕讀取器使用者宣布頁面正在忙碌中。
請參閱下方的 Accessibility section 以取得其他詳細資訊與疑慮。
no-wrap
停靠定位相對於固定定位
在使用 no-wrap
屬性時,若要在某些情況下隱藏整個應用程式或頁面,您可以透過在 <b-overlay>
上設定 fixed
屬性來切換到視窗固定定位。請注意,這不會停用頁面的捲動,而且注意頁面上的任何互動元素仍會出現在文件索引順序中。
您可能也需要調整 覆蓋的 z-index 來確保背景出現在所有其他頁面元素上方。請使用 z-index
屬性來覆寫預設 z-index
值。
請參閱下方的 Accessibility section 以取得其他詳細資訊與疑慮。
覆蓋 z-index
某些情況下,您可能需要調整覆蓋使用的 z-index
(取決於在 DOM 中的定位或被遮蔽的內容)。只需設定 z-index
屬性,並使用適合您的應用程式或使用案例的值即可。預設 z-index
為 10
無障礙
請注意,覆蓋層僅用於顯示。覆蓋層顯示時,您必須停用任何互動元素(按鈕、連結等),否則遮擋的元素仍可透過鍵盤導覽(即仍位於文件分頁順序)存取。
如果您在遮蔽的內容中有任何連結,我們建議使用 <b-link>
組件,因為它支援 disabled
狀態,而本機連結 (<a href="...">
) 和 <router-link>
組件不支援 disabled 狀態。
當覆蓋層可見時,建議同時將 aria-hidden="true"
或 aria-busy="true"
屬性新增至您遮蔽的內容中。請小心不要將 aria-hidden="true"
新增至包含 <b-overlay>
組件的外框(在使用 no-wrap
時),因為這將對螢幕閱讀器使用者隱藏 overlay
區段中的任何互動式內容。
如果您將互動式內容置於 overlay
區段,您應在 'shown'
事件發出後使內容取得焦點。您可以視需要使用 hidden
事件觸發將焦點返回至元素,以於覆蓋層不再可見時。
使用包覆模式(未設定 no-wrap
屬性)時,外框將設定 aria-busy="true"
屬性,以讓螢幕閱讀器使用者知道已包覆的內容正處於忙碌或載入狀態。設定 no-wrap
屬性後,不會 套用此屬性。
當您使用 no-wrap
屬性,以及潛在使用 fixed
屬性,遮蔽整個應用程式或網頁時,您必須確保已停用所有國際頁面元素(覆蓋層內容除外),且不在 文件分頁順序中。
用例範例
以下是幾個 <b-overlay>
常見用例的範例。在所有情況下,我們都停用遮蔽區域中的任何互動元素,以防止透過鍵盤導覽(即 Tab 鍵)或螢幕閱讀器存取。
請參閱 易讀性區段,以取得更多詳細資料和注意事項。
輕鬆建立加載按鈕
<template>
<div>
<b-overlay
:show="busy"
rounded
opacity="0.6"
spinner-small
spinner-variant="primary"
class="d-inline-block"
@hidden="onHidden"
>
<b-button
ref="button"
:disabled="busy"
variant="primary"
@click="onClick"
>
Do something
</b-button>
</b-overlay>
</div>
</template>
<script>
export default {
data() {
return {
busy: false,
timeout: null
}
},
beforeDestroy() {
this.clearTimeout()
},
methods: {
clearTimeout() {
if (this.timeout) {
clearTimeout(this.timeout)
this.timeout = null
}
},
setTimeout(callback) {
this.clearTimeout()
this.timeout = setTimeout(() => {
this.clearTimeout()
callback()
}, 5000)
},
onHidden() {
this.$refs.button.focus()
},
onClick() {
this.busy = true
this.setTimeout(() => {
this.busy = false
})
}
}
}
</script>
在此範例中,我們遮蔽輸入和按鈕
<template>
<div>
<b-overlay :show="busy" rounded="lg" opacity="0.6" @hidden="onHidden">
<template #overlay>
<div class="d-flex align-items-center">
<b-spinner small type="grow" variant="secondary"></b-spinner>
<b-spinner type="grow" variant="dark"></b-spinner>
<b-spinner small type="grow" variant="secondary"></b-spinner>
<span class="sr-only">Please wait...</span>
</div>
</template>
<b-input-group size="lg" :aria-hidden="busy ? 'true' : null">
<b-form-input v-model="value" :disabled="busy"></b-form-input>
<b-input-group-append>
<b-button ref="button" :disabled="busy" variant="primary" @click="onClick">
Do something
</b-button>
</b-input-group-append>
</b-input-group>
</b-overlay>
</div>
</template>
<script>
export default {
data() {
return {
value: 'Some value',
busy: false,
timeout: null
}
},
beforeDestroy() {
this.clearTimeout()
},
methods: {
clearTimeout() {
if (this.timeout) {
clearTimeout(this.timeout)
this.timeout = null
}
},
setTimeout(callback) {
this.clearTimeout()
this.timeout = setTimeout(() => {
this.clearTimeout()
callback()
}, 5000)
},
onHidden() {
this.$refs.button.focus()
},
onClick() {
this.busy = true
this.setTimeout(() => {
this.busy = false
})
}
}
}
</script>
此範例稍微複雜一些,但顯示了如何使用 no-wrap
,以及如何使用 overlay
區段向使用者呈現提示對話方塊,並在確認後顯示上傳狀態指示器。此範例也示範說明更多易讀性的標記。
<template>
<div>
<b-form class="position-relative p-3" @submit.prevent="onSubmit">
<b-form-group label="Name" label-for="form-name" label-cols-lg="2">
<b-input-group>
<b-input-group-prepend is-text>
<b-icon icon="person-fill"></b-icon>
</b-input-group-prepend>
<b-form-input id="form-name" :disabled="busy"></b-form-input>
</b-input-group>
</b-form-group>
<b-form-group label="Email" label-for="form-mail" label-cols-lg="2">
<b-input-group>
<b-input-group-prepend is-text>
<b-icon icon="envelope-fill"></b-icon>
</b-input-group-prepend>
<b-form-input id="form-email" type="email" :disabled="busy"></b-form-input>
</b-input-group>
</b-form-group>
<b-form-group label="Image" label-for="form-image" label-cols-lg="2">
<b-input-group>
<b-input-group-prepend is-text>
<b-icon icon="image-fill"></b-icon>
</b-input-group-prepend>
<b-form-file id="form-image" :disabled="busy" accept="image/*"></b-form-file>
</b-input-group>
</b-form-group>
<div class="d-flex justify-content-center">
<b-button ref="submit" type="submit" :disabled="busy">Submit</b-button>
</div>
<b-overlay :show="busy" no-wrap @shown="onShown" @hidden="onHidden">
<template #overlay>
<div v-if="processing" class="text-center p-4 bg-primary text-light rounded">
<b-icon icon="cloud-upload" font-scale="4"></b-icon>
<div class="mb-3">Processing...</div>
<b-progress
min="1"
max="20"
:value="counter"
variant="success"
height="3px"
class="mx-n4 rounded-0"
></b-progress>
</div>
<div
v-else
ref="dialog"
tabindex="-1"
role="dialog"
aria-modal="false"
aria-labelledby="form-confirm-label"
class="text-center p-3"
>
<p><strong id="form-confirm-label">Are you sure?</strong></p>
<div class="d-flex">
<b-button variant="outline-danger" class="mr-3" @click="onCancel">
Cancel
</b-button>
<b-button variant="outline-success" @click="onOK">OK</b-button>
</div>
</div>
</template>
</b-overlay>
</b-form>
</div>
</template>
<script>
export default {
data() {
return {
busy: false,
processing: false,
counter: 1,
interval: null
}
},
beforeDestroy() {
this.clearInterval()
},
methods: {
clearInterval() {
if (this.interval) {
clearInterval(this.interval)
this.interval = null
}
},
onShown() {
this.$refs.dialog.focus()
},
onHidden() {
this.$refs.submit.focus()
},
onSubmit() {
this.processing = false
this.busy = true
},
onCancel() {
this.busy = false
},
onOK() {
this.counter = 1
this.processing = true
this.clearInterval()
this.interval = setInterval(() => {
if (this.counter < 20) {
this.counter = this.counter + 1
} else {
this.clearInterval()
this.$nextTick(() => {
this.busy = this.processing = false
})
}
}, 350)
}
}
}
</script>
在 <b-modal>
中使用
彈跳視窗主體已設定 位置:相關;
,所以當彈跳視窗主體中使用 <b-overlay no-wrap ...>
時,只會遮蓋彈跳視窗主體。如果你希望遮蓋整個彈跳視窗(包括標題和頁腳),你需要將 <b-modal>
屬性 主體類別
設定為 位置靜態
,同時也在 <b-overlay>
中將 圓角
屬性設定為 開
。