Frontend Development 6 min read

Why a 0.5px Border Renders as 1px and How to Fix It

This article explains why CSS borders set to 0.5px often appear as 1px on various devices, discusses browser rendering and device pixel ratio issues, and provides five practical solutions—including pseudo‑elements, shadows, SVG, and container tricks—to achieve sub‑pixel borders in H5 layouts.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Why a 0.5px Border Renders as 1px and How to Fix It

Background

When developing an H5 page, the UI design provides borders as 1px solid for a 750px wide mockup, but the actual page width is 375px, so dimensions are halved and a 0.5px solid border is desired. In practice the browser still renders a 1px line.

Why the border becomes 1px

Browsers handle sub‑pixel values differently; many round 0.5px to 1px to ensure consistency, especially on low‑resolution screens that cannot display fractions of a pixel. High‑DPI (Retina) displays may render the line more clearly, while low‑DPI devices may enlarge or hide it.

Solutions

Method 1: Pseudo‑element and positioning

.active { color: rgba(250,100,0,1); font-size: 14px; position: relative; }
.active::after { content: ""; pointer-events: none; display: block; position: absolute; left: 0; top: 0; border: 1px #ff892e solid; box-sizing: border-box; width: 100%; height: 100%; }

This creates a 1px pseudo‑border that can be styled independently.

Method 2: Using box‑shadow

.active2 { margin-left: 10px; color: rgba(250,100,0,1); font-size: 14px; position: relative; box-shadow: 0 0 0 0.5px #ff892e; }

Box‑shadow simulates a thin border, though inspection tools may still show a 1px line.

Method 3: Inline SVG

<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
  <rect x="0" y="0" width="100" height="100" fill="none" stroke="#ff892e" stroke-width="0.5"></rect>
</svg>

SVG can render true sub‑pixel strokes on high‑DPI screens.

Method 4: SVG with absolute positioning

.active { color: rgba(250,100,0,1); font-size: 14px; position: relative; display: inline-block; }
.active svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; box-sizing: border-box; }
.active .content { position: relative; z-index: 1; }

Combines SVG overlay with positioned content.

Method 5: Parent container trick

<div class="border-container">
  <div class="active">active</div>
</div>

.border-container { display: inline-block; padding: 0.5px; background-color: #ff892e; }
.active { color: rgba(250,100,0,1); font-size: 14px; background-color: white; }

The container provides the visual thickness while the inner element keeps its original size.

Conclusion

In the author's company, Method 1 is preferred: the .active element and its siblings all have a content height of 14 px, and adding align-items: center to the parent makes the active item 14 px while other items remain 13 px, which can be adjusted based on design needs.

FrontendWeb DevelopmentCSSresponsive designbordersub-pixel
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.