骨架
Framework7 附帶 Skeleton Elements 函式庫 (又稱 UI Skeletons、Skeleton Screens、Ghost Elements) - UI 可提升感知效能。
Skeleton Elements 函式庫已整合至 Framework7,您不必另外安裝。如需完整的 API 文件和更多範例,請查看官方 Skeleton Elements 文件。
Skeleton 區塊
Skeleton 區塊只是一個具有灰色背景色的常見區塊元素,可以是任何所需大小。
若要建立 skeleton 區塊元素,我們只需要建立一個具有 skeleton-block
類別的 div
元素,最好具有固定寬度
...
<div class="list">
<ul>
<li class="item-content">
<div class="item-inner">
<div class="item-title">
<!-- Use skeleton block instead of list item title -->
<div class="skeleton-block" style="width: 100px"></div>
</div>
</div>
</li>
</ul>
</div>
...
Skeleton 文字
Skeleton 文字更有趣。Framework7 附帶特殊內建 Skeleton 字型,將每個字元呈現為一個小灰色矩形。當我們將 skeleton-text
類別套用至任何元素時,它會將文字轉換為灰色區塊/線條。優於 skeleton-block
的優點是,此類「skeleton 文字」可以完全回應,其大小會反映實際文字大小。
Skeleton 文字字型支援以下字元組 (包括「空格」)
0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ - . , : ; / ! / * & ' " | ( ) { } [ ]
...
<div class="list media-list">
<ul>
<!-- we just add "skeleton-text" class to list item and its text will be rendered as gray boxes -->
<li class="item-content skeleton-text">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">Item Title</div>
</div>
<div class="item-subtitle">Item Subtitle</div>
<div class="item-text">Item text goes here, and it will be rendered as gray box too.</div>
</div>
</li>
<!-- In the next item we use "_" character instead of actual text -->
<li class="item-content skeleton-text">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">____ _____</div>
</div>
<div class="item-subtitle">____ _______</div>
<div class="item-text">____ ____ ____ _____ ___ __ ____ __ ________ __ ____ ___ ____</div>
</div>
</li>
</ul>
</div>
...
Skeleton 效果
Skeleton 元素也支援三種動畫效果:淡入、波浪和脈衝。
若要啟用特殊 skeleton 動畫效果,我們需要將以下類別之一新增至 skeleton 元素,或新增至包含 skeleton 元素的父元素
skeleton-effect-fade
- 新增淡入效果skeleton-effect-wave
- 新增波浪效果skeleton-effect-pulse
- 新增脈衝效果
CSS 變數
以下是相關 CSS 變數 (CSS 自訂屬性) 清單。
:root {
--skeleton-color: #ccc;
--skeleton-icon-color: rgba(0, 0, 0, 0.25);
}
.dark {
--skeleton-color: #515151;
--skeleton-icon-color: rgba(255, 255, 255, 0.25);
}
範例
skeleton.html
<template>
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner sliding">
<div class="title">Skeleton Elements</div>
</div>
</div>
<div class="page-content">
<div class="block block-strong-ios block-outline-ios">
<p>Skeleton (or Ghost) elements designed to improve perceived performance and make app feels faster.</p>
<p>Framework7 comes with two types of such elements: Skeleton Block and Skeleton Text. Skeleton block is a gray
box that can be used as placeholder for any element. Skeleton text uses special built-in skeleton font to
render each character of such text as gray rectangle. Skeleton text allows to make such elements responsive
and feel more natural.</p>
<p>It can be used in any places and with any elements.</p>
</div>
<div class="block-title">Skeleton List</div>
<div class="list list-strong-ios list-outline-ios list-dividers-ios media-list skeleton-text">
<ul>
<li class="item-content">
<div class="item-media">
<div class="skeleton-block" style="width: 40px; height: 40px; border-radius: 50%"></div>
</div>
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">Title</div>
</div>
<div class="item-subtitle">Subtitle</div>
<div class="item-text">
Placeholder text line 1<br />
Text line 2
</div>
</div>
</li>
<li class="item-content">
<div class="item-media">
<div class="skeleton-block" style="width: 40px; height: 40px; border-radius: 50%"></div>
</div>
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">Title</div>
</div>
<div class="item-subtitle">Subtitle</div>
<div class="item-text">
Placeholder text line 1<br />
Text line 2
</div>
</div>
</li>
</ul>
</div>
<div class="block-title">Skeleton Card</div>
<div class="card card-outline skeleton-text">
<div class="card-header">Card Header</div>
<div class="card-content card-content-padding">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi
lobortis et massa ac interdum. Cras consequat felis at consequat hendrerit.</div>
<div class="card-footer">Card Footer</div>
</div>
<div class="block-title">Loading Effects</div>
<div class="block block-strong-ios block-outline-ios">
<p>It supports few loading effects:</p>
<p class="grid grid-cols-3 grid-gap">
<a class="button button-fill button-small button-round" @click=${()=> load('fade')}>Fade</a>
<a class="button button-fill button-small button-round" @click=${()=> load('wave')}>Wave</a>
<a class="button button-fill button-small button-round" @click=${()=> load('pulse')}>Pulse</a>
</p>
</div>
<div class="list list-strong-ios list-outline-ios list-dividers-ios media-list">
<ul>
${loading ? $h`
<li class="item-content skeleton-text skeleton-effect-${effect}">
<div class="item-media">
<div class="skeleton-block" style="width: 40px; height: 40px; border-radius: 50%"></div>
</div>
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">Full Name</div>
</div>
<div class="item-subtitle">Position</div>
<div class="item-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi lobortis et massa ac
interdum. Cras consequat felis at consequat hendrerit. Aliquam vestibulum vitae lorem ac iaculis.
Praesent nec pharetra massa, at blandit lectus. Sed tincidunt, lectus eu convallis elementum, nibh nisi
aliquet urna, nec imperdiet felis sapien at enim.</div>
</div>
</li>
<li class="item-content skeleton-text skeleton-effect-${effect}">
<div class="item-media">
<div class="skeleton-block" style="width: 40px; height: 40px; border-radius: 50%"></div>
</div>
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">Full Name</div>
</div>
<div class="item-subtitle">Position</div>
<div class="item-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi lobortis et massa ac
interdum. Cras consequat felis at consequat hendrerit. Aliquam vestibulum vitae lorem ac iaculis.
Praesent nec pharetra massa, at blandit lectus. Sed tincidunt, lectus eu convallis elementum, nibh nisi
aliquet urna, nec imperdiet felis sapien at enim.</div>
</div>
</li>
<li class="item-content skeleton-text skeleton-effect-${effect}">
<div class="item-media">
<div class="skeleton-block" style="width: 40px; height: 40px; border-radius: 50%"></div>
</div>
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">Full Name</div>
</div>
<div class="item-subtitle">Position</div>
<div class="item-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi lobortis et massa ac
interdum. Cras consequat felis at consequat hendrerit. Aliquam vestibulum vitae lorem ac iaculis.
Praesent nec pharetra massa, at blandit lectus. Sed tincidunt, lectus eu convallis elementum, nibh nisi
aliquet urna, nec imperdiet felis sapien at enim.</div>
</div>
</li>
` : $h`
<li class="item-content">
<div class="item-media">
<img src="https://placeimg.com/80/80/people/1" style="width: 40px; height: 40px; border-radius: 50%" />
</div>
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">John Doe</div>
</div>
<div class="item-subtitle">CEO</div>
<div class="item-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi lobortis et massa ac
interdum. Cras consequat felis at consequat hendrerit. Aliquam vestibulum vitae lorem ac iaculis.
Praesent nec pharetra massa, at blandit lectus. Sed tincidunt, lectus eu convallis elementum, nibh nisi
aliquet urna, nec imperdiet felis sapien at enim.</div>
</div>
</li>
<li class="item-content">
<div class="item-media">
<img src="https://placeimg.com/80/80/people/2" style="width: 40px; height: 40px; border-radius: 50%" />
</div>
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">Jane Doe</div>
</div>
<div class="item-subtitle">Marketing</div>
<div class="item-text">Cras consequat felis at consequat hendrerit. Aliquam vestibulum vitae lorem ac
iaculis. Praesent nec pharetra massa, at blandit lectus. Sed tincidunt, lectus eu convallis elementum,
nibh nisi aliquet urna, nec imperdiet felis sapien at enim.</div>
</div>
</li>
<li class="item-content">
<div class="item-media">
<img src="https://placeimg.com/80/80/people/3" style="width: 40px; height: 40px; border-radius: 50%" />
</div>
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">Kate Johnson</div>
</div>
<div class="item-subtitle">Admin</div>
<div class="item-text">Sed tincidunt, lectus eu convallis elementum, nibh nisi aliquet urna, nec imperdiet
felis sapien at enim.</div>
</div>
</li>
`}
</ul>
</div>
</div>
</div>
</template>
<script>
export default (props, { $update }) => {
let loading = false;
let effect = null;
const load = (newEffect) => {
if (loading) return;
effect = newEffect;
loading = true;
$update();
setTimeout(function () {
loading = false;
$update();
}, 3000);
}
return $render;
}
</script>