Changing the color of an hr element
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
To change the color of an <hr> element, remove the default border with border: none, set an explicit height, and apply background-color. This is the most reliable cross-browser approach. Using color or border-color alone produces inconsistent results because browsers render the <hr> element differently by default.
Why <hr> Styling Is Tricky
The <hr> element is unusual in HTML. It is a replaced, void element that browsers render with user-agent stylesheets that vary significantly. Chrome renders it as a 1px border-top with no height. Firefox uses a 2px border with an inset style. Safari applies yet another variation. This means a simple color: red declaration will not work consistently across browsers.
Here is what the default user-agent styles typically look like:
Because the visible "line" comes from the border, not the background, you need to understand which property actually controls the appearance.
The Reliable Cross-Browser Approach
Reset the default styling and treat the <hr> as a simple colored box:
This works in every modern browser because you are removing the browser's default border rendering and replacing it with an explicit background color and height.
Alternative Approaches
Using border-color Only
If you want to keep the border-based rendering (for example, to maintain a 1px hairline), you can override just the border:
This produces a crisp 1px line. The key is to set border: none first to clear the browser defaults, then apply only the border you want.
Using the color Property
The color property affects <hr> in some browsers (notably older versions of Internet Explorer and Edge Legacy) because they treat the element's foreground color as the line color. In modern browsers, color alone does nothing visible on an <hr>.
Avoid relying on color alone. It is unreliable and confusing.
Gradient and Decorative Dividers
For more visual impact, use CSS gradients to create colored dividers that fade at the edges:
Responsive Divider with Width Control
Semi-Transparent Dividers
Use rgba() or hsla() for dividers that blend with varying background colors:
CSS Custom Properties for Theming
For design systems where divider colors need to match a theme:
Property Comparison Table
| Property | Cross-browser | What it affects | Best for |
background-color | Yes (with border: none) | Fill color of the element box | Solid colored dividers |
border-top | Yes (with border: none reset first) | Top edge line | 1px hairline dividers |
border-color | Partial (must reset other borders) | All four borders | Not recommended alone |
color | No (legacy IE/Edge only) | Foreground color | Avoid |
background (gradient) | Yes (with border: none) | Gradient fill | Decorative dividers |
opacity | Yes | Overall transparency | Fading the entire element |
Complete Reset Stylesheet
Here is a minimal reset you can include in any project to normalize <hr> behavior:
This matches what popular CSS resets like Normalize.css and modern-normalize do. From this baseline, you can safely apply colors and styles without worrying about browser inconsistencies.
Accessibility Considerations
The <hr> element has an implicit ARIA role of separator. Screen readers announce it as a content divider. If you style an <hr> to be purely decorative (no semantic separation), set role="presentation" to suppress the announcement:
Keep the <hr> element's color contrast sufficient for users who rely on visual dividers to understand content grouping. A contrast ratio of at least 3:1 against the background is recommended by WCAG for non-text elements.
Common Pitfalls
Setting color and expecting it to work everywhere. The color property only affects <hr> in legacy Internet Explorer and Edge Legacy. In Chrome, Firefox, and Safari, it has no visible effect. Always use background-color or border-color instead.
Forgetting to reset the default border. If you set background-color without first applying border: none, the browser's default border renders on top of your background color. You see the old gray border overlaid on your intended color, producing an ugly double-line effect.
Setting height without border: none. Adding height: 2px without removing the border creates a 2px tall box with a 1px border inside it. The result is a thick, oddly-styled line that does not match your intent.
Using unitless height values. height: 2 without a unit is invalid CSS and is silently ignored by the browser. Always include the unit: height: 2px.
Inconsistent margins. Different browsers apply different default margins to <hr>. Explicitly set margin in your stylesheet to ensure consistent spacing across browsers.
Summary
The reliable way to color an <hr> element is to reset the browser's default border with border: none, set an explicit height, and apply background-color. For 1px hairline dividers, use border: none followed by border-top: 1px solid <color>. Avoid relying on the color property, which only works in legacy browsers. For decorative dividers, CSS gradients and custom properties give you full control. Always include border: none as the first declaration in any <hr> style rule to neutralize browser defaults before applying your own design.

