Background
Using avatars, often a circular image of a user, to show relationships between the user and data or features adds visual interest to the UI. You often see avatars in headers depicting the logged-in user or adjacent to information where different users may be collaborating and you want to show what belongs to who. Unlikely though, the user image used for the avatar is a required field. Therefore, a fallback is needed for users who haven't uploaded an image.
HTML
<div class="avatar-container">
<button class="avatar" type="button">
<span data-letters="AB"></span>
</button>
<button class="avatar" type="button">
<span data-letters="AB"></span>
</button>
<button class="avatar" type="button">
<span data-letters="AB"></span>
</button>
<button class="avatar" type="button">
<span data-letters="AB"></span>
</button>
</div>
Here we have a handful of button elements with a class "avatar", a child span element with a data-<label> attribute, and a value for the data attribute representing our example user's initials. I added a couple variations within the "avatar-container" to demonstrate different gradient possibilities. Rather than just supplying a single "fallback," consider offering a handful of color/gradient choices to allow the user greater personalization.
For my purposes, I'm starting with button elements for my avatars given my most common use case is a nav button that displays a dropdown with options like, "profile," "log out," and so on. If I was only using an avatar to indicate possession or relation to a record or action, such as with a data table, I would use a different element. I just need something that respects "width" and "height" properties since the circle's size is fixed.
With the attribute "data-letters," we're passing the user's initials to be later injected as content with css. The syntax for this is "data-<lable>." I'm choosing the "letters" part. You can call it "initials," "foo," "bar," or whatever you'd like.
CSS
.avatar {
/* button */
/* button reset */
border: none;
font-family: inherit;
cursor: pointer;
outline: inherit;
height: 4rem;
width: 4rem;
border-radius: 50%;
color: #fff;
/* center the data within */
display: flex;
align-items: center;
justify-content: center;
/* transform for the demo */
transform: scale(1.5);
transition: all 200ms ease-in;
}
/* initials */
.avatar > span[data-letters]::before {
content: attr(data-letters);
font-size: 1.3rem;
}
/* background gradients */
.avatar:nth-child(1) {
background: linear-gradient(to right top, #4b31a1, #b32993);
}
.avatar:nth-child(2) {
background: linear-gradient(to right top, #970008, #ff6f91);
}
.avatar:nth-child(3) {
background: linear-gradient(to right top, #008b72, #54fbdd);
}
.avatar:nth-child(4) {
background: linear-gradient(to right top, #2e3192, #1bffff);
}
.avatar:hover {
transform: scale(1.6);
margin: 0 1.25rem;
}
The CSS to accomplish this is relatively simple. First, I adjust a couple of properties to prevent default button styles from interfering. Next, I'm styling the avatar with fixed width and height properties as well as a "border-radius" property of 50% to accomplish the circle shape. Then, I establish the avatar as a flexbox with vertical and horizontal center alignment to position the content in the center of the shape.
As an alternative to flexbox, don't forget we have absolute positioning in the toolbox.
.avatar {
/* alternative positioning */
display: relative;
}
.avatar > span {
position: absolute;
top: 50%;
left: 50;
transform: translate(-50%, -50%);
}
To capture the initials and then inject them into view, I use the "content" property of the pseudo element ::before. In CSS, there exists a function attr() that retrieves an attribute's value. I use this function to grab the initials and then pass them to the "content" property.
Note, when setting the initials to the content property, the selector "span[data-letters]::before" can be used without "[data-letters]." For example ".avatar > span::before" would also work. The "[data-letters]" component adds an additional layer of specificity to the selector where direct child spans to parent with class "avatar" will only be selected if the span contains the "data-letters" attribute.
Last, I add a background gradient to make the shape a little more visually interesting. I'm using the nth-child selector to apply the different gradients in this example. In practice, I would assign each gradient to its own class and conditionally inject the class dependent on a stored user preference. That way, you allow a user to choose their own default avatar.
Result
See the Pen default-avatars by Ian Waldron (@Ian-Waldron) on CodePen.
Final Thoughts
The above is a simple and easy way to give users a default option for a user avatar. Please note, the shapes are much larger than I would actually use in production. I sized them up to 4rem for presentation purposes. Something around "2rem" to start and adjusting for screen size might be more appropriate. Enjoy.
Here's the Codepen for the project.