Skip to content

Commit 418529f

Browse files
committed
New avatar component
1 parent 65a4072 commit 418529f

4 files changed

Lines changed: 368 additions & 0 deletions

File tree

scss/_avatar.scss

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
@use "variables" as *;
2+
@use "theme" as *;
3+
@use "mixins/border-radius" as *;
4+
5+
// scss-docs-start avatar-variables
6+
$avatar-size: 2.5rem !default;
7+
$avatar-size-xs: 1.5rem !default;
8+
$avatar-size-sm: 2rem !default;
9+
$avatar-size-lg: 3rem !default;
10+
$avatar-size-xl: 4rem !default;
11+
$avatar-border-radius: 50% !default;
12+
$avatar-border-width: 2px !default;
13+
$avatar-border-color: var(--bg-body) !default;
14+
$avatar-bg: var(--bg-2) !default;
15+
$avatar-color: var(--color-body) !default;
16+
17+
$avatar-status-size: .75rem !default;
18+
$avatar-status-border-width: 2px !default;
19+
$avatar-status-border-color: var(--bg-body) !default;
20+
21+
$avatar-stack-spacing: -.3 !default; // Percentage of avatar size (negative for overlap)
22+
// scss-docs-end avatar-variables
23+
24+
@layer components {
25+
.avatar {
26+
// scss-docs-start avatar-css-vars
27+
--avatar-border-radius: #{$avatar-border-radius};
28+
--avatar-border-width: #{$avatar-border-width};
29+
--avatar-border-color: #{$avatar-border-color};
30+
--avatar-bg: #{$avatar-bg};
31+
--avatar-color: #{$avatar-color};
32+
--avatar-status-size: #{$avatar-status-size};
33+
--avatar-status-border-width: #{$avatar-status-border-width};
34+
--avatar-status-border-color: #{$avatar-status-border-color};
35+
// scss-docs-end avatar-css-vars
36+
37+
position: relative;
38+
display: inline-flex;
39+
align-items: center;
40+
justify-content: center;
41+
width: var(--avatar-size, #{$avatar-size});
42+
height: var(--avatar-size, #{$avatar-size});
43+
font-size: calc(var(--avatar-size) * .4);
44+
font-weight: $font-weight-medium;
45+
line-height: 1;
46+
color: var(--theme-contrast, var(--avatar-color));
47+
text-transform: uppercase;
48+
vertical-align: middle;
49+
background-color: var(--theme-bg, var(--avatar-bg));
50+
@include border-radius(var(--avatar-border-radius));
51+
}
52+
53+
.avatar-subtle {
54+
color: var(--theme-text, var(--avatar-color));
55+
background-color: var(--theme-bg-subtle, var(--avatar-bg));
56+
}
57+
58+
.avatar-img {
59+
width: 100%;
60+
height: 100%;
61+
object-fit: cover;
62+
@include border-radius(inherit);
63+
}
64+
65+
.avatar-status {
66+
position: absolute;
67+
right: calc(var(--avatar-status-border-width) * -1);
68+
bottom: calc(var(--avatar-status-border-width) * -1);
69+
width: var(--avatar-status-size);
70+
height: var(--avatar-status-size);
71+
background-color: var(--gray-400);
72+
border: var(--avatar-status-border-width) solid var(--avatar-status-border-color);
73+
@include border-radius(50%);
74+
75+
&.status-online {
76+
background-color: var(--green-500);
77+
}
78+
79+
&.status-offline {
80+
background-color: var(--gray-400);
81+
@include border-radius(20%);
82+
}
83+
84+
&.status-busy {
85+
background-color: var(--red-500);
86+
@include border-radius(20%);
87+
}
88+
89+
&.status-away {
90+
background-color: var(--yellow-500);
91+
}
92+
}
93+
94+
.avatar-stack {
95+
display: inline-flex;
96+
flex-direction: row-reverse;
97+
98+
.avatar {
99+
// Stack spacing is calculated as a percentage of avatar size
100+
margin-left: calc(var(--avatar-size, #{$avatar-size}) * #{$avatar-stack-spacing});
101+
border: var(--avatar-border-width) solid var(--avatar-border-color);
102+
mask-image: none;
103+
104+
&:last-child {
105+
margin-left: 0;
106+
}
107+
108+
&:hover {
109+
z-index: 1;
110+
transform: translateY(-2px);
111+
}
112+
}
113+
}
114+
115+
.avatar-xs,
116+
.avatar-stack-xs {
117+
--avatar-size: #{$avatar-size-xs};
118+
--avatar-status-size: .625rem;
119+
}
120+
121+
.avatar-sm,
122+
.avatar-stack-sm {
123+
--avatar-size: #{$avatar-size-sm};
124+
}
125+
126+
.avatar-lg,
127+
.avatar-stack-lg {
128+
--avatar-size: #{$avatar-size-lg};
129+
--avatar-status-size: 1rem;
130+
}
131+
132+
.avatar-xl,
133+
.avatar-stack-xl {
134+
--avatar-size: #{$avatar-size-xl};
135+
--avatar-status-size: 1.25rem;
136+
}
137+
}

scss/bootstrap.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// Components
1414
@forward "accordion";
1515
@forward "alert";
16+
@forward "avatar";
1617
@forward "badge";
1718
@forward "breadcrumb";
1819
@forward "card";

site/data/sidebar.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
pages:
8686
- title: Accordion
8787
- title: Alert
88+
- title: Avatar
8889
- title: Badge
8990
- title: Breadcrumb
9091
- title: Buttons
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
---
2+
title: Avatar
3+
description: Documentation and examples for avatars, including image avatars, initials, status indicators, and avatar stacks.
4+
toc: true
5+
---
6+
7+
## Examples
8+
9+
Avatars are used to represent users or entities. They can display an image or initials as a fallback.
10+
11+
### Image
12+
13+
Use `.avatar` with an `.avatar-img` for image-based avatars. The parent `.avatar` element provides an easy wrapper for additional avatar features like status indicators and stacks. You're welcome to use the `.avatar-img` class on its own if you only need a single HTML element.
14+
15+
<Example code={`<span class="avatar">
16+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
17+
</span>`} />
18+
19+
### Initials
20+
21+
Use text content inside `.avatar` for initials-based avatars.
22+
23+
<Example code={`<span class="avatar">AB</span>
24+
<span class="avatar theme-primary">CD</span>
25+
<span class="avatar theme-accent">EF</span>
26+
<span class="avatar theme-success">GG</span>
27+
<span class="avatar theme-danger">GH</span>
28+
<span class="avatar theme-warning">IJ</span>
29+
<span class="avatar theme-info">KL</span>
30+
<span class="avatar theme-inverse">MN</span>
31+
<span class="avatar theme-secondary">OP</span>`} />
32+
33+
Use `.avatar-subtle` to create a subtle avatar.
34+
35+
<Example code={`<span class="avatar">AB</span>
36+
<span class="avatar avatar-subtle theme-primary">CD</span>
37+
<span class="avatar avatar-subtle theme-accent">EF</span>
38+
<span class="avatar avatar-subtle theme-success">GG</span>
39+
<span class="avatar avatar-subtle theme-danger">GH</span>
40+
<span class="avatar avatar-subtle theme-warning">IJ</span>
41+
<span class="avatar avatar-subtle theme-info">KL</span>
42+
<span class="avatar avatar-subtle theme-inverse">MN</span>
43+
<span class="avatar avatar-subtle theme-secondary">OP</span>`} />
44+
45+
## Sizes
46+
47+
Avatars come in multiple sizes: extra small, small, default, large, and extra large.
48+
49+
<Example code={`<span class="avatar avatar-xs">
50+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
51+
</span>
52+
<span class="avatar avatar-sm">
53+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
54+
</span>
55+
<span class="avatar">
56+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
57+
</span>
58+
<span class="avatar avatar-lg">
59+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
60+
</span>
61+
<span class="avatar avatar-xl">
62+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
63+
</span>`} />
64+
65+
## Status indicator
66+
67+
Add a `.avatar-status` element inside the avatar to show a status indicator. Each status has a distinct shape and color:
68+
69+
- `.status-online` — green circle
70+
- `.status-offline` — gray rounded square
71+
- `.status-busy` — red rounded square
72+
- `.status-away` — yellow circle
73+
74+
<Example code={`<span class="avatar">
75+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
76+
<span class="avatar-status status-online"></span>
77+
</span>
78+
<span class="avatar">
79+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
80+
<span class="avatar-status status-offline"></span>
81+
</span>
82+
<span class="avatar">
83+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
84+
<span class="avatar-status status-busy"></span>
85+
</span>
86+
<span class="avatar">
87+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
88+
<span class="avatar-status status-away"></span>
89+
</span>`} />
90+
91+
### Status with sizes
92+
93+
The status indicator scales with the avatar size.
94+
95+
<Example code={`<span class="avatar avatar-xs">
96+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
97+
<span class="avatar-status status-online"></span>
98+
</span>
99+
<span class="avatar avatar-sm">
100+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
101+
<span class="avatar-status status-online"></span>
102+
</span>
103+
<span class="avatar">
104+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
105+
<span class="avatar-status status-online"></span>
106+
</span>
107+
<span class="avatar avatar-lg">
108+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
109+
<span class="avatar-status status-online"></span>
110+
</span>
111+
<span class="avatar avatar-xl">
112+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
113+
<span class="avatar-status status-online"></span>
114+
</span>`} />
115+
116+
## Avatar stack
117+
118+
Use `.avatar-stack` to group multiple avatars together with overlapping effect. Avatars are rendered in reverse order so the first avatar appears on top. Stacks use a percentage of the avatar size to determine how much to overlap stacked avatars.
119+
120+
<Example code={`<div class="avatar-stack">
121+
<span class="avatar">
122+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
123+
</span>
124+
<span class="avatar">
125+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
126+
</span>
127+
<span class="avatar">
128+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
129+
</span>
130+
<span class="avatar">
131+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
132+
</span>
133+
<span class="avatar">
134+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
135+
</span>
136+
</div>`} />
137+
138+
### Stack with sizes
139+
140+
As a shorthand, size classes are available for `.avatar-stack` and `.avatar`.
141+
142+
<Example class="vstack align-items-start gap-3" code={`<div class="avatar-stack avatar-stack-xs">
143+
<span class="avatar">
144+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
145+
</span>
146+
<span class="avatar">
147+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
148+
</span>
149+
<span class="avatar">
150+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
151+
</span>
152+
</div>
153+
154+
<div class="avatar-stack avatar-stack-sm">
155+
<span class="avatar">
156+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
157+
</span>
158+
<span class="avatar">
159+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
160+
</span>
161+
<span class="avatar">
162+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
163+
</span>
164+
</div>
165+
166+
<div class="avatar-stack">
167+
<span class="avatar">
168+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
169+
</span>
170+
<span class="avatar">
171+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
172+
</span>
173+
<span class="avatar">
174+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
175+
</span>
176+
</div>
177+
178+
<div class="avatar-stack avatar-stack-lg">
179+
<span class="avatar">
180+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
181+
</span>
182+
<span class="avatar">
183+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
184+
</span>
185+
<span class="avatar">
186+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
187+
</span>
188+
</div>
189+
190+
<div class="avatar-stack avatar-stack-xl">
191+
<span class="avatar">
192+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
193+
</span>
194+
<span class="avatar">
195+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
196+
</span>
197+
<span class="avatar">
198+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
199+
</span>
200+
</div>`} />
201+
202+
### Stack with count
203+
204+
Combine with initials to show a count of additional users.
205+
206+
<Example code={`<div class="avatar-stack">
207+
<span class="avatar">
208+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
209+
</span>
210+
<span class="avatar">
211+
<img class="avatar-img" src="https://github.com/mdo.png" alt="mdo">
212+
</span>
213+
<span class="avatar">
214+
<img class="avatar-img" src="https://i.pravatar.cc/150?img=34" alt="User avatar">
215+
</span>
216+
<span class="avatar theme-secondary">+5</span>
217+
</div>`} />
218+
219+
## CSS
220+
221+
### Variables
222+
223+
<CSSVariables component="Avatar" className="avatar" />
224+
225+
<ScssDocs name="avatar-css-vars" file="scss/_avatar.scss" />
226+
227+
### Sass variables
228+
229+
<ScssDocs name="avatar-variables" file="scss/_avatar.scss" />

0 commit comments

Comments
 (0)