Anatomy of a Bearblog toast button
A little starter for styling toast buttons:1
- The default toast button — walkthrough of the default design
- Toast button CSS, the parts — breakdown of common customizations
- Mixing it all together — examples of how the parts come together for a custom button design
The default toast button
The toast button's HTML is:
<button class="upvote-button" title="Toast this post">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1">
<polyline points="17 11 12 6 7 11"></polyline>
<polyline points="17 18 12 13 7 18"></polyline>
</svg>
<small class="upvote-count">10</small>
</button>
And the default CSS that defines its appearance is:
.upvote-button {
padding: 0;
margin: 0;
border: 0;
background-color: inherit;
color: inherit;
display: flex;
flex-direction: column;
align-items: center;
}
.upvote-button.upvoted {
color: salmon;
}
.upvote-count {
margin-top: -3px;
}
Untoasted
Toasted
The button displays as a centered column, with the svg icon above the upvote count. It has no margin, padding, or border. It inherits the theme's body text and background colors. When toasted, it turns a salmon color. The negative margin reduces the space between the icon and upvote count. It has no hover style.
Some themes have additional button CSS:
button {
margin: 0;
cursor: pointer;
}
On hover, the cursor changes to a pointer to indicate the button is clickable. When toasted, the button becomes disabled, but the cursor is still a pointer.
Toast button CSS, the parts
The most common toast button customizations are a mix of the following parts:
1. Hide the svg icon
.upvote-button svg {
display: none;
}
2. Hide the upvote count
.upvote-count {
display: none;
}
Untoasted
Toasted
3. Add content after the button
.upvote-button::after {
content: 'After 🧁';
}
Untoasted
Toasted
4. Add content before the button
.upvote-button::before {
content: 'Before 🍥';
}
Untoasted
Toasted
5. Add a border, padding, and color to make the button look more buttony
.upvote-button {
border: 1px solid ButtonBorder;
border-radius: .5em;
padding: .5em;
background-color: ButtonFace;
color: ButtonText;
}
6. Change the font family, size, and color
.upvote-button {
font-family: 'Nimbus Mono PS', 'Courier New', monospace;
font-size: 3rem;
color: MediumOrchid;
}
Untoasted
Toasted
7. Change from vertical to horizontal
.upvote-button {
flex-direction: row;
}
Untoasted
Toasted
8. Add styles for different button states
.upvote-button { /* Untoasted */
background-color: Orchid;
}
.upvote-button:hover { /* Hover */
background-color: MediumSlateBlue;
cursor: pointer;
}
.upvote-button[disabled] { /* Toasted */
background-color: DarkSlateBlue;
cursor: default;
}
(Use [disabled]
instead of .upvoted
so that the style changes immediately after toasting.)
Untoasted
Toasted
Mixing it all together
A few examples of how the parts can add together (purposely minimal to demonstrate the essential CSS only):
1. Replace default icon with an emoji =
- hide the svg icon +
- add content before the button +
- change the font size
.upvote-button svg {
display: none;
}
.upvote-button::before {
content: '🌮';
font-size: 1.5rem;
}
.upvote-count {
margin: initial; /* Reset the negative margin (it's not needed anymore) */
}
Untoasted
Toasted
2. Replace the default entirely with something buttony =
- hide the svg icon +
- hide the upvote count +
- add content before the button +
- add a border, padding, and color
.upvote-button svg,
.upvote-count {
display: none;
}
.upvote-button::before {
content: 'My button (ノ◕ヮ◕)ノ*:・゚✧';
border: 1px solid ButtonBorder;
border-radius: .5em;
padding: .5em;
background-color: ButtonFace;
color: ButtonText;
}
Untoasted
Toasted
3. Change the content for different button states =
- hide the svg icon +
- hide the upvote count +
- add content before the button +
- add styles for different button states
.upvote-button svg,
.upvote-count {
display: none;
}
.upvote-button::before { /* Untoasted */
content: 'I am a seed. 🌱';
}
.upvote-button:hover::before { /* Hover */
content: 'Give me attention! 🌿';
cursor: pointer;
}
.upvote-button[disabled]::before { /* Toasted */
content: 'I am a tree. 🌳';
cursor: default;
color: GrayText; /* To change the salmon color */
}
Untoasted
Toasted
4. Replace icon with button, show upvote count on right =
- hide the svg icon +
- add content before the button +
- add a border, padding, and color +
- add styles for different button states +
- change from vertical to horizontal +
- add content after the button (more specifically, the upvote count)
.upvote-button svg {
display: none;
}
.upvote-button::before { /* Untoasted */
content: '🐽 Boop!';
border: 1px solid ButtonBorder;
border-radius: .5em;
padding: .5em;
background-color: ButtonFace;
color: ButtonText;
}
.upvote-button:hover::before { /* Hover */
content: '🐽 Boop back?';
cursor: pointer;
}
.upvote-button[disabled]::before { /* Toasted */
content: '🐈 Booped';
cursor: default;
color: GrayText; /* To change the salmon color */
}
.upvote-button {
flex-direction: row;
gap: .75em; /* Add space between button and upvote count */
}
.upvote-count {
margin: initial; /* Reset the negative margin (it's not needed anymore) */
color: GrayText; /* To change the salmon color */
}
.upvote-count::after {
content: ' booped';
}
Untoasted
Toasted
5. Explain button on hover =
- hide the svg icon +
- hide the upvote count +
- add content before the button +
- add styles for different button states +
- change the font size +
- add content after the button +
- change from vertical to horizontal
.upvote-button svg,
.upvote-count {
display: none;
}
.upvote-button::before { /* Untoasted */
content: '🌹';
font-size: 1.5rem;
}
.upvote-button:hover::before { /* Hover */
cursor: pointer;
}
.upvote-button[disabled]::before { /* Toasted */
content: '🥀';
font-size: 1.5rem;
cursor: default;
}
.upvote-button:hover::after { /* Hover */
content: 'Give a rose'; /* Explain the button */
}
.upvote-button[disabled]::after { /* Toasted */
content: 'Oh no'; /* Something else, can be blank */
color: GrayText; /* To change the salmon color */
}
.upvote-button {
flex-direction: row;
gap: .5em; /* Add space between emoji & text */
align-items: baseline; /* Align text */
}
Untoasted
Toasted
Toast buttons are fun! There are so many possibilities. I hope you enjoy playing with it.
I saw Ruth's Bearblog Toast Button CSS last night before sleeping and saved a note to share some toast button CSS. ↩