HTML
CSS
Web Design
Web Development
Front-End Development

Changing the color of an hr element

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

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:

css
1/* Chrome's default (approximate) */
2hr {
3  border-style: inset;
4  border-width: 1px;
5  margin: 0.5em auto;
6  overflow: hidden;
7}
8
9/* Firefox's default (approximate) */
10hr {
11  border: 1px inset;
12  margin-block: 0.5em;
13}

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:

css
1hr {
2  border: none;
3  height: 2px;
4  background-color: #e53e3e;
5}

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.

html
<p>Section one content.</p>
<hr />
<p>Section two content.</p>

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:

css
1hr {
2  border: none;
3  border-top: 1px solid #3182ce;
4}

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>.

css
1/* Not recommended - inconsistent across browsers */
2hr {
3  color: red;
4}

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:

css
1/* Gradient fade from transparent to color to transparent */
2hr.fade {
3  border: none;
4  height: 2px;
5  background: linear-gradient(
6    to right,
7    transparent,
8    #805ad5 20%,
9    #805ad5 80%,
10    transparent
11  );
12}
13
14/* Rainbow divider */
15hr.rainbow {
16  border: none;
17  height: 3px;
18  background: linear-gradient(
19    to right,
20    #e53e3e,
21    #dd6b20,
22    #d69e2e,
23    #38a169,
24    #3182ce,
25    #805ad5
26  );
27}
28
29/* Centered dot pattern */
30hr.dots {
31  border: none;
32  height: 1px;
33  background: none;
34  border-top: 3px dotted #a0aec0;
35}

Responsive Divider with Width Control

css
1hr.centered {
2  border: none;
3  height: 3px;
4  background-color: #2d3748;
5  width: 60%;
6  margin: 2rem auto;
7  border-radius: 2px;
8}
9
10/* Narrower on mobile */
11@media (max-width: 640px) {
12  hr.centered {
13    width: 80%;
14  }
15}

Semi-Transparent Dividers

Use rgba() or hsla() for dividers that blend with varying background colors:

css
1/* Works on any background color */
2hr.subtle {
3  border: none;
4  height: 1px;
5  background-color: rgba(0, 0, 0, 0.12);
6}
7
8/* Dark mode variant */
9@media (prefers-color-scheme: dark) {
10  hr.subtle {
11    background-color: rgba(255, 255, 255, 0.12);
12  }
13}

CSS Custom Properties for Theming

For design systems where divider colors need to match a theme:

css
1:root {
2  --divider-color: #e2e8f0;
3  --divider-thickness: 1px;
4}
5
6[data-theme="dark"] {
7  --divider-color: #2d3748;
8}
9
10hr {
11  border: none;
12  height: var(--divider-thickness);
13  background-color: var(--divider-color);
14  margin: 1.5rem 0;
15}

Property Comparison Table

PropertyCross-browserWhat it affectsBest for
background-colorYes (with border: none)Fill color of the element boxSolid colored dividers
border-topYes (with border: none reset first)Top edge line1px hairline dividers
border-colorPartial (must reset other borders)All four bordersNot recommended alone
colorNo (legacy IE/Edge only)Foreground colorAvoid
background (gradient)Yes (with border: none)Gradient fillDecorative dividers
opacityYesOverall transparencyFading the entire element

Complete Reset Stylesheet

Here is a minimal reset you can include in any project to normalize <hr> behavior:

css
1/* Normalize hr across all browsers */
2hr {
3  box-sizing: content-box;
4  height: 0;
5  overflow: visible;
6  border: none;
7  border-top: 1px solid #e2e8f0;
8  margin: 1rem 0;
9}

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:

html
1<!-- Semantic divider (default) -->
2<hr />
3
4<!-- Decorative only - no screen reader announcement -->
5<hr role="presentation" />

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.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.