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