Back
Learn how to design a sleek, minimal outline button that fills with color on hover for a clean and modern user interface.
<div class="button-container">
<button class="outline-button">Learn More</button>
</div>
The button text can be customized to match your specific call-to-action.
.button-container {
display: flex;
justify-content: center;
align-items: center;
}
Next, we define the outline button with CSS variables for easy customization:
.outline-button {
--button-color: #3B82F6;
--button-hover-color: #2563EB;
--button-text-hover: white;
--button-padding-x: 24px;
--button-padding-y: 12px;
--button-font-size: 16px;
--button-radius: 6px;
--button-border-width: 2px;
--button-transition-time: 0.3s;
font-family: system-ui, -apple-system, sans-serif;
font-weight: 500;
font-size: var(--button-font-size);
color: var(--button-color);
background-color: transparent;
border: var(--button-border-width) solid var(--button-color);
border-radius: var(--button-radius);
padding: var(--button-padding-y) var(--button-padding-x);
cursor: pointer;
position: relative;
overflow: hidden;
z-index: 1;
transition: color var(--button-transition-time) ease;
}
The key properties here:
- We define a transparent background with a colored border for the outline look
- We set position: relative and z-index: 1 to prepare for our fill effect
- overflow: hidden ensures our fill animation stays within the button borders
- We only transition the text color, as the background will be handled by a pseudo-element
To create the fill effect on hover, we use a pseudo-element:
.outline-button::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: var(--button-color);
transform: translateY(100%);
transition: transform var(--button-transition-time) ease;
z-index: -1;
}
.outline-button:hover {
color: var(--button-text-hover);
}
.outline-button:hover::before {
transform: translateY(0);
}
This technique creates a smooth fill animation from bottom to top when hovering. The pseudo-element starts below the button (translateY(100%)) and moves up to fill it.
We also add an active state for better interaction feedback:
.outline-button:active {
transform: scale(0.98);
}
The active state slightly reduces the button size to create a subtle 'press' effect.
For accessibility, we add a focus state:
/* Focus state for accessibility */
.outline-button:focus-visible {
outline: 2px solid rgba(59, 130, 246, 0.5);
outline-offset: 2px;
}
Finally, we provide alternative color schemes and animation variations:
/* Alternative color schemes */
.outline-button.danger {
--button-color: #EF4444;
--button-hover-color: #DC2626;
}
.outline-button.success {
--button-color: #10B981;
--button-hover-color: #059669;
}
.outline-button.warning {
--button-color: #F59E0B;
--button-hover-color: #D97706;
}
/* Alternative fill animations */
.outline-button.slide-right::before {
transform: translateX(-100%);
width: 100%;
height: 100%;
}
.outline-button.slide-right:hover::before {
transform: translateX(0);
}
.outline-button.slide-center::before {
transform: translateX(-50%) scaleX(0);
width: 100%;
height: 100%;
}
.outline-button.slide-center:hover::before {
transform: translateX(-50%) scaleX(1);
}
The different animation classes provide alternative ways for the background to fill in, giving you multiple options for your interface:
- The default slides up from the bottom
- slide-right slides in from the left
- slide-center expands from the center outward
This outline button offers several advantages:
- Visual lightness: The minimal design works well in clean, modern interfaces.
- Clear interaction: The fill effect provides satisfying visual feedback on hover.
- Versatile styling: Works well for secondary actions alongside more prominent primary buttons.
- Animation options: Different fill animations add visual interest and can match the mood of your site.
- Accessible design: High contrast between the outline and fill states, with proper focus styling.
This button style is perfect for secondary actions, "learn more" links, or in interfaces where you want a more subtle button style that still provides clear interactive feedback.<div class="button-container">
<button class="outline-button">Learn More</button>
</div>
<style>
.button-container {
display: flex;
justify-content: center;
align-items: center;
}
.outline-button {
--button-color: #3B82F6;
--button-hover-color: #2563EB;
--button-text-hover: white;
--button-padding-x: 24px;
--button-padding-y: 12px;
--button-font-size: 16px;
--button-radius: 6px;
--button-border-width: 2px;
--button-transition-time: 0.3s;
font-family: system-ui, -apple-system, sans-serif;
font-weight: 500;
font-size: var(--button-font-size);
color: var(--button-color);
background-color: transparent;
border: var(--button-border-width) solid var(--button-color);
border-radius: var(--button-radius);
padding: var(--button-padding-y) var(--button-padding-x);
cursor: pointer;
position: relative;
overflow: hidden;
z-index: 1;
transition: color var(--button-transition-time) ease;
}
.outline-button::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: var(--button-color);
transform: translateY(100%);
transition: transform var(--button-transition-time) ease;
z-index: -1;
}
.outline-button:hover {
color: var(--button-text-hover);
}
.outline-button:hover::before {
transform: translateY(0);
}
.outline-button:active {
transform: scale(0.98);
}
/* Focus state for accessibility */
.outline-button:focus-visible {
outline: 2px solid rgba(59, 130, 246, 0.5);
outline-offset: 2px;
}
/* Alternative color schemes */
.outline-button.danger {
--button-color: #EF4444;
--button-hover-color: #DC2626;
}
.outline-button.success {
--button-color: #10B981;
--button-hover-color: #059669;
}
.outline-button.warning {
--button-color: #F59E0B;
--button-hover-color: #D97706;
}
/* Alternative fill animations */
.outline-button.slide-right::before {
transform: translateX(-100%);
width: 100%;
height: 100%;
}
.outline-button.slide-right:hover::before {
transform: translateX(0);
}
.outline-button.slide-center::before {
transform: translateX(-50%) scaleX(0);
width: 100%;
height: 100%;
}
.outline-button.slide-center:hover::before {
transform: translateX(-50%) scaleX(1);
}
</style>
Thank you for reading this article.
Comments
No comments yet. Be the first to comment!