Skeleton
Provide a placeholder while you wait for content to load, or to visualise content that doesn't exist yet.
When To Use#
When a resource needs long time to load.
When the component contains lots of information, such as List or Card.
Only works when loading data for the first time.
Could be replaced by Spin in any situation, but can provide a better user experience.
Examples
TypeScript
JavaScript
import { Skeleton } from 'antd';
import React from 'react';
const App: React.FC = () => <Skeleton />;
export default App;
TypeScript
JavaScript
import { Skeleton } from 'antd';
import React from 'react';
const App: React.FC = () => <Skeleton avatar paragraph={{ rows: 4 }} />;
export default App;
TypeScript
JavaScript
import { Skeleton } from 'antd';
import React from 'react';
const App: React.FC = () => <Skeleton active />;
export default App;
TypeScript
JavaScript
import type { RadioChangeEvent } from 'antd';
import { Divider, Form, Radio, Skeleton, Space, Switch } from 'antd';
import { DotChartOutlined } from '@ant-design/icons';
import React, { useState } from 'react';
type SizeType = 'default' | 'small' | 'large';
type ButtonShapeType = 'circle' | 'square' | 'round' | 'default';
type AvatarShapeType = 'circle' | 'square';
const App: React.FC = () => {
const [active, setActive] = useState(false);
const [block, setBlock] = useState(false);
const [size, setSize] = useState<SizeType>('default');
const [buttonShape, setButtonShape] = useState<ButtonShapeType>('default');
const [avatarShape, setAvatarShape] = useState<AvatarShapeType>('circle');
const handleActiveChange = (checked: boolean) => {
setActive(checked);
};
const handleBlockChange = (checked: boolean) => {
setBlock(checked);
};
const handleSizeChange = (e: RadioChangeEvent) => {
setSize(e.target.value);
};
const handleShapeButton = (e: RadioChangeEvent) => {
setButtonShape(e.target.value);
};
const handleAvatarShape = (e: RadioChangeEvent) => {
setAvatarShape(e.target.value);
};
return (
<>
<Space>
<Skeleton.Button active={active} size={size} shape={buttonShape} block={block} />
<Skeleton.Avatar active={active} size={size} shape={avatarShape} />
<Skeleton.Input active={active} size={size} />
</Space>
<br />
<br />
<Skeleton.Button active={active} size={size} shape={buttonShape} block={block} />
<br />
<br />
<Skeleton.Input active={active} size={size} block={block} />
<br />
<br />
<Space>
<Skeleton.Image active={active} />
<Skeleton.Node active={active}>
<DotChartOutlined style={{ fontSize: 40, color: '#bfbfbf' }} />
</Skeleton.Node>
</Space>
<Divider />
<Form layout="inline" style={{ margin: '16px 0' }}>
<Form.Item label="Active">
<Switch checked={active} onChange={handleActiveChange} />
</Form.Item>
<Form.Item label="Button and Input Block">
<Switch checked={block} onChange={handleBlockChange} />
</Form.Item>
<Form.Item label="Size">
<Radio.Group value={size} onChange={handleSizeChange}>
<Radio.Button value="default">Default</Radio.Button>
<Radio.Button value="large">Large</Radio.Button>
<Radio.Button value="small">Small</Radio.Button>
</Radio.Group>
</Form.Item>
<Form.Item label="Button Shape">
<Radio.Group value={buttonShape} onChange={handleShapeButton}>
<Radio.Button value="default">Default</Radio.Button>
<Radio.Button value="square">Square</Radio.Button>
<Radio.Button value="round">Round</Radio.Button>
<Radio.Button value="circle">Circle</Radio.Button>
</Radio.Group>
</Form.Item>
<Form.Item label="Avatar Shape">
<Radio.Group value={avatarShape} onChange={handleAvatarShape}>
<Radio.Button value="square">Square</Radio.Button>
<Radio.Button value="circle">Circle</Radio.Button>
</Radio.Group>
</Form.Item>
</Form>
</>
);
};
export default App;
Ant Design, a design language
We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
TypeScript
JavaScript
import { Button, Skeleton } from 'antd';
import React, { useState } from 'react';
const App: React.FC = () => {
const [loading, setLoading] = useState(false);
const showSkeleton = () => {
setLoading(true);
setTimeout(() => {
setLoading(false);
}, 3000);
};
return (
<div className="article">
<Skeleton loading={loading}>
<div>
<h4>Ant Design, a design language</h4>
<p>
We supply a series of design principles, practical patterns and high quality design
resources (Sketch and Axure), to help people create their product prototypes beautifully
and efficiently.
</p>
</div>
</Skeleton>
<Button onClick={showSkeleton} disabled={loading}>
Show Skeleton
</Button>
</div>
);
};
export default App;
TypeScript
JavaScript
import type Icon from '@ant-design/icons';
import { LikeOutlined, MessageOutlined, StarOutlined } from '@ant-design/icons';
import { Avatar, List, Skeleton, Switch } from 'antd';
import React, { useState } from 'react';
interface IconTextProps {
icon: typeof Icon;
text: React.ReactNode;
}
const listData = Array.from({ length: 3 }).map((_, i) => ({
href: 'https://ant.design',
title: `ant design part ${i}`,
avatar: 'https://joeschmoe.io/api/v1/random',
description:
'Ant Design, a design language for background applications, is refined by Ant UED Team.',
content:
'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.',
}));
const IconText = ({ icon, text }: IconTextProps) => (
<span>
{React.createElement(icon, { style: { marginRight: 8 } })}
{text}
</span>
);
const App: React.FC = () => {
const [loading, setLoading] = useState(true);
const onChange = (checked: boolean) => {
setLoading(!checked);
};
return (
<>
<Switch checked={!loading} onChange={onChange} />
<List
itemLayout="vertical"
size="large"
dataSource={listData}
renderItem={item => (
<List.Item
key={item.title}
actions={
!loading
? [
<IconText icon={StarOutlined} text="156" key="list-vertical-star-o" />,
<IconText icon={LikeOutlined} text="156" key="list-vertical-like-o" />,
<IconText icon={MessageOutlined} text="2" key="list-vertical-message" />,
]
: undefined
}
extra={
!loading && (
<img
width={272}
alt="logo"
src="https://gw.alipayobjects.com/zos/rmsportal/mqaQswcyDLcXyDKnZfES.png"
/>
)
}
>
<Skeleton loading={loading} active avatar>
<List.Item.Meta
avatar={<Avatar src={item.avatar} />}
title={<a href={item.href}>{item.title}</a>}
description={item.description}
/>
{item.content}
</Skeleton>
</List.Item>
)}
/>
</>
);
};
export default App;
API#
Skeleton#
Property | Description | Type | Default |
---|---|---|---|
active | Show animation effect | boolean | false |
avatar | Show avatar placeholder | boolean | SkeletonAvatarProps | false |
loading | Display the skeleton when true | boolean | - |
paragraph | Show paragraph placeholder | boolean | SkeletonParagraphProps | true |
round | Show paragraph and title radius when true | boolean | false |
title | Show title placeholder | boolean | SkeletonTitleProps | true |
SkeletonAvatarProps#
Property | Description | Type | Default |
---|---|---|---|
active | Show animation effect, only valid when used avatar independently | boolean | false |
shape | Set the shape of avatar | circle | square | - |
size | Set the size of avatar | number | large | small | default | - |
SkeletonTitleProps#
Property | Description | Type | Default |
---|---|---|---|
width | Set the width of title | number | string | - |
SkeletonParagraphProps#
Property | Description | Type | Default |
---|---|---|---|
rows | Set the row count of paragraph | number | - |
width | Set the width of paragraph. When width is an Array, it can set the width of each row. Otherwise only set the last row width | number | string | Array<number | string> | - |
SkeletonButtonProps#
Property | Description | Type | Default | Version |
---|---|---|---|---|
active | Show animation effect | boolean | false | |
block | Option to fit button width to its parent width | boolean | false | 4.17.0 |
shape | Set the shape of button | circle | round | square | default | - | |
size | Set the size of button | large | small | default | - |
SkeletonInputProps#
Property | Description | Type | Default |
---|---|---|---|
active | Show animation effect | boolean | false |
size | Set the size of input | large | small | default | - |