![]() |
VOOZH | about |
Normal buttons are rendered using the default browser styling. We can override this default styling using CSS.
👁 CSS Reference Guide: Button StylingThe basic CSS properties for styling buttons are: padding, margin, border-radius, and background. CSS frameworks like Material Design, Bootstrap, Tailwind CSS, and others use these to style their buttons to produce their own style classes.
In this guide, we will create our own button style classes from pure CSS. The following demo shows the results of our implementation:
See the Pen
buttons examples by Chidume David (@philipsz-davido)
on CodePen.
The Replay is a weekly newsletter for dev and engineering leaders.
Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.
Let’s create a base button style class with basic styling:
.button {
padding: 6px 12px;
margin-bottom: 0;
font-weight: 400;
cursor: pointer;
text-align: center;
white-space: nowrap;
display: inline-block;
background-image: none;
border-radius: 3px;
box-shadow: none;
border: 1px solid transparent;
}
All buttons in this guide will take the above styling by default. Let’s break down the styling properties:
padding: Pads the content of the button to 6px on the top and bottom, 12px on the left and rightmargin-bottom: Declares no margin at the bottom of the buttonfont-weight: Here, we’ve set the text content to be slightly boldercursor: The system cursor will convert to a hand icon on hovertext-align: Center-aligns the button textwhite-space: The button text will remain on the same line; it does not break on limited spacedisplay: Sets the button to wrap around its siblings, while making its height and width adjustablebackground-image: Toggles off any image set in the backgroundborder-radius: Set to be 3pxbox-shadow: Set to be removed around the buttonborder: Set to be 1px wide, solid, and transparentThis forms the base of our class and allows us to create child buttons from it. Simply set the .button to a button class attribute and our styling takes over:
<button class="button">Button</button>
We can then create variations of buttons from the .button base class. These variations will be buttons with different colors.
To create CSS buttons with different colors, we use the color, background-color, and border-color properties to create the variations.
.button .buttonRed {
color: #fff;
background-color: red;
border-color: #ac2925;
}
The color prop in hex is #fff; the background-color prop makes the button appear red in color. The border-color is set to be slightly darker than red to better define the button borders.
We can now set the .buttonRed class to .button buttons to create buttons with a tomato-red color.
<button class="button buttonRed">Red Button</button>
.button .buttonGreen {
color: #fff;
background-color: green;
border-color: #4cae4c;
}
The background-color prop here is set to green. Applying .buttonGreen to a button:
<button class="button buttonGreen">Green Button</button>
.button .buttonBlue {
color: #fff;
background-color: blue;
border-color: #2e6da4;
}
This will make any button with the .buttonBlue class appear blue in color. Applying .buttonBlue to a button:
<button class="button buttonBlue">Blue Button</button>
We can use the padding and font-size properties to increase the button sizes.
.buttonLarge {
padding: 10px 16px;
font-size: 18px;
}
.buttonSmall {
padding: 5px 10px;
font-size: 12px;
}
.buttonXSmall {
padding: 1px 5px;
font-size: 12px;
}
Notice how the padding and font-size values decreased from .buttonLarge to .buttonXSmall — especially the font-size because it sets the element’s text size.
Block buttons expand to fill the width of their parent container. This is done using the width property.
.buttonBlock {
width: 100%;
}
The width is set to 100%, so that it stretches to fill the entire length of its parent.
We can also use width to define our button length; it can be set to any percentage or to any unit.
.buttonBlock {
width: 50%;
}
.buttonBlock {
width: 10px;
}
.buttonBlock {
width: 10em;
}
We can simulate a disabled button by using the cursor and opacity properties.
.button.disabled {
cursor: not-allowed;
opacity: 0.65;
}
The system cursor will become a stop icon on hover based on the not-allowed value in the cursor property. This disables any clicking event or any other mouse-associated events on the button.
opacity defines the button visibility. Here, the value 0.65 makes it slightly dimmer to signify that the button is disabled.
We create round buttons in CSS by using the border-radius, height, and width properties.
.buttonRound {
border-radius: 50%;
height: 44px;
width: 44px;
}
To make a button round, we set the border-radius to 50%. height and width ultimately determine the size of the button. If they were not the same value, the button would appear oval; to make it a circle, they share the same value of 44px.
Creating elevated or raised buttons is accomplished with the box-shadow property. This property casts a shadow around an element’s border.
.buttonRaised {
box-shadow: 0 3px 8px 0 black;
}
This will give the button a 3D look. The first value of the box-shadow property sets the top part shadow to 0, the right side to 3px, the bottom to 8px, and the left to 0. We’ve also defined a black color. With these values, we will see black shadows cast on the bottom more than on the right sides.
We can add animated effects to buttons using CSS as well.
In particular, we’d like animated effects when a button is hovered over, when the mouse hovers way from the button, and when the button is clicked.
We use the :hover pseudo-class selector to set styling to a button when the mouse moves over it.
Let’s add a hover effect for each of our different button colors:
//red button
.buttonRed:hover {
color: #fff;
background-color: red;
border-color: #ac2925;
box-shadow: 1px 1px 1px 3px grey;
}
//green button
.buttonGreen:hover {
color: #fff;
background-color: green;
border-color: #398439;
box-shadow: 1px 1px 1px 3px grey;
}
//blue button
.buttonBlue:hover {
color: #fff;
background-color: blue;
border-color: #269abc;
box-shadow: 1px 1px 1px 3px grey;
}
The colors we’ve selected for the color, border-color, and background-color properties of our buttons have a respectively lighter opacity than their original state. The shadow cast by the elements is also set to be more defined using the box-shadow property on hover.
This provides a visual cue for the user when they hover the button. They will see a dim in the button’s color, background color, and a deeper shadow cast on hover.
To create a click effect, we use the :active pseudo-class selector.
//red button
.buttonRed:active {
color: #fff;
background-color: #3b0404;
border-color: #ac2925;
}
//green button
.buttonGreen:active {
color: #fff;
background-color: #022c02;
border-color: #398439;
}
//blue button
.buttonBlue:active {
color: #fff;
background-color: #020221;
border-color: #269abc;
}
Just like in the hover effect, we changed the color of the border, text, background when the button is clicked. In CSS, when the button is clicked the :active pseudo-selector is triggered.
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
👁 LogRocket Dashboard Free Trial BannerLogRocket lets you replay user sessions, eliminating guesswork around why bugs happen by showing exactly what users experienced. It captures console logs, errors, network requests, and pixel-perfect DOM recordings — compatible with all frameworks.
LogRocket's Galileo AI watches sessions for you, instantly identifying and explaining user struggles with automated monitoring of your entire product experience.
Modernize how you debug web and mobile apps — start monitoring for free.
Learn how to use Gemini CLI subagents to delegate frontend, backend, testing, and docs tasks to specialized agents with guardrails and clear ownership.
Learn how next-browser gives AI agents runtime context for debugging Next.js apps, including React props, hydration, PPR, forms, and performance.
Build dynamic LLM routing in Next.js with OpenRouter, TanStack AI, task classification, model fallbacks, and cost-aware routing.
TSRX adds first-class control flow, conditional hooks, and scoped styles to React via a TypeScript compiler extension — no new framework required.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up now