04 / 26
All 26 in 26 CSS Dividers
- 01SVG Wave Section Divider CSS
- 02Diagonal Slanted Section Divider CSS
- 03Gradient Horizontal Rule CSS
- 04Text with Lines on Sides Divider CSS ("OR" Divider)
- 05Curved Arch Section Divider CSS
- 06Zigzag Torn Paper Cut Divider CSS
- 07Blob Organic SVG Divider CSS
- 08Pure CSS Ornamental Divider with Pseudo-Elements
- 09Editorial Article Serif Divider CSS
- 10Neo-Brutalist Heavy Border Divider CSS
- 11Art Deco Geometric Gold Divider CSS
- 12Organic Leaf & Vine SVG Divider CSS
- 13Cyberpunk Neon Glow Divider CSS
- 14Luxury Minimalist Gold Accent HR Line CSS
- 15Data Dashboard Dotted Grid Divider CSS
- 16Wedding Heart Icon Divider CSS
- 17Editorial Thin Double-Line Divider CSS
- 18Medieval Fantasy Star Crest Divider CSS
- 19Subtle Faded Border-Bottom Divider CSS
- 208-Bit Retro Pixelated Divider CSS
- 21Multi-Column Newspaper Rule Divider CSS
- 22Bouncing Animated Dots Divider CSS
- 23Audio Waveform SVG Divider CSS
- 24Confetti & Sparkle SVG Divider CSS
- 25Vertical Flexbox Divider Line CSS
- 26Hand-Drawn Doodle SVG Divider CSS
Text with Lines on Sides Divider CSS ("OR" Divider)
The divider every auth screen and pricing card needs: a centred word flanked by rules that fill whatever space is left. Shown three ways — the flexbox pseudo-element classic, the two-line grid version that needs no pseudo-elements at all, and a border-image one-liner — inside a real sign-in card, with the accessibility answer for whether the word should be announced.
Build UI like this from scratch: Flexbox, Grid, animations & responsive CSS
ZTM · The CSS Bootcamp · 30‑day money-back guarantee · Affiliate link
The code
<section class="div-04" aria-label="Text with lines on sides OR divider demo">
<div class="div-04__stage">
<div class="div-04__card">
<h2 class="div-04__title">Sign in to Codefronts</h2>
<button class="div-04__oauth" type="button">
<svg viewBox="0 0 18 18" width="17" height="17" aria-hidden="true"><path fill="#4285F4" d="M17.6 9.2c0-.6-.1-1.2-.2-1.8H9v3.5h4.8a4.1 4.1 0 0 1-1.8 2.7v2.2h2.9c1.7-1.6 2.7-3.9 2.7-6.6z"/><path fill="#34A853" d="M9 18c2.4 0 4.5-.8 6-2.2l-2.9-2.2c-.8.5-1.8.9-3.1.9-2.4 0-4.4-1.6-5.1-3.8H.9v2.3A9 9 0 0 0 9 18z"/><path fill="#FBBC05" d="M3.9 10.7a5.4 5.4 0 0 1 0-3.4V5H.9a9 9 0 0 0 0 8l3-2.3z"/><path fill="#EA4335" d="M9 3.6c1.3 0 2.5.5 3.4 1.3l2.6-2.6A9 9 0 0 0 .9 5l3 2.3C4.6 5.2 6.6 3.6 9 3.6z"/></svg>
Continue with Google
</button>
<div class="div-04__or" role="separator" aria-label="or">or</div>
<button class="div-04__email" type="button">Continue with email</button>
<div class="div-04__variants">
<div class="div-04__grid" role="separator" aria-label="grid variant"><span class="div-04__rule"></span><span class="div-04__word">grid 1fr auto 1fr</span><span class="div-04__rule"></span></div>
<div class="div-04__bimg" role="separator" aria-label="border-image variant"><span>border-image</span></div>
</div>
</div>
<p class="div-04__chip">flex:1 1 0 pseudo-rules · role="separator" · aria-label carries the word</p>
</div>
</section><section class="div-04" aria-label="Text with lines on sides OR divider demo">
<div class="div-04__stage">
<div class="div-04__card">
<h2 class="div-04__title">Sign in to Codefronts</h2>
<button class="div-04__oauth" type="button">
<svg viewBox="0 0 18 18" width="17" height="17" aria-hidden="true"><path fill="#4285F4" d="M17.6 9.2c0-.6-.1-1.2-.2-1.8H9v3.5h4.8a4.1 4.1 0 0 1-1.8 2.7v2.2h2.9c1.7-1.6 2.7-3.9 2.7-6.6z"/><path fill="#34A853" d="M9 18c2.4 0 4.5-.8 6-2.2l-2.9-2.2c-.8.5-1.8.9-3.1.9-2.4 0-4.4-1.6-5.1-3.8H.9v2.3A9 9 0 0 0 9 18z"/><path fill="#FBBC05" d="M3.9 10.7a5.4 5.4 0 0 1 0-3.4V5H.9a9 9 0 0 0 0 8l3-2.3z"/><path fill="#EA4335" d="M9 3.6c1.3 0 2.5.5 3.4 1.3l2.6-2.6A9 9 0 0 0 .9 5l3 2.3C4.6 5.2 6.6 3.6 9 3.6z"/></svg>
Continue with Google
</button>
<div class="div-04__or" role="separator" aria-label="or">or</div>
<button class="div-04__email" type="button">Continue with email</button>
<div class="div-04__variants">
<div class="div-04__grid" role="separator" aria-label="grid variant"><span class="div-04__rule"></span><span class="div-04__word">grid 1fr auto 1fr</span><span class="div-04__rule"></span></div>
<div class="div-04__bimg" role="separator" aria-label="border-image variant"><span>border-image</span></div>
</div>
</div>
<p class="div-04__chip">flex:1 1 0 pseudo-rules · role="separator" · aria-label carries the word</p>
</div>
</section>.div-04 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--div-04-bg);
--div-04-bg: oklch(0.965 0.006 250);
--div-04-card: oklch(1 0 0);
--div-04-ink: oklch(0.24 0.02 260);
--div-04-mut: oklch(0.58 0.018 260);
--div-04-line: oklch(0.24 0.02 260/.14);
--div-04-acc: oklch(0.52 0.17 268);
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
color: var(--div-04-ink);
}
.div-04 *,
.div-04 *::before,
.div-04 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.div-04__stage {
min-height: 100svh;
display: grid;
place-content: center;
justify-items: center;
gap: 22px;
padding: clamp(24px,5vw,60px) clamp(20px,5vw,56px);
background: radial-gradient(90% 70% at 50% 0%,oklch(1 0 0),transparent);
}
.div-04__card {
width: min(92vw,392px);
background: var(--div-04-card);
border: 1px solid var(--div-04-line);
border-radius: 18px;
padding: clamp(24px,4vw,32px);
box-shadow: 0 18px 44px oklch(0.24 0.02 260/.09);
display: grid;
gap: 16px;
}
.div-04__title {
font-size: 21px;
font-weight: 680;
letter-spacing: -.02em;
text-align: center;
margin-bottom: 2px;
}
.div-04__oauth,
.div-04__email {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
min-height: 46px;
width: 100%;
border-radius: 11px;
font-size: 14.5px;
font-weight: 600;
cursor: pointer;
font-family: inherit;
transition: background .18s ease,border-color .18s ease,transform .18s ease;
}
.div-04__oauth {
background: var(--div-04-card);
border: 1px solid var(--div-04-line);
color: var(--div-04-ink);
}
.div-04__oauth:hover {
background: oklch(0.97 0.004 260);
}
.div-04__email {
background: var(--div-04-acc);
border: 1px solid transparent;
color: oklch(0.99 0.01 268);
}
.div-04__email:hover {
background: oklch(0.46 0.17 268);
}
.div-04__oauth:active,
.div-04__email:active {
transform: translateY(1px);
}
.div-04__oauth:focus-visible,
.div-04__email:focus-visible {
outline: 2px solid var(--div-04-acc);
outline-offset: 2px;
}
.div-04__or {
display: flex;
align-items: center;
gap: 14px;
font-size: 11.5px;
font-weight: 650;
letter-spacing: .16em;
text-transform: uppercase;
color: var(--div-04-mut);
}
.div-04__or::before,
.div-04__or::after {
content: '';
flex: 1 1 0;
height: 1px;
background: var(--div-04-line);
}
.div-04__variants {
display: grid;
gap: 14px;
margin-top: 6px;
padding-top: 16px;
border-top: 1px dashed var(--div-04-line);
}
.div-04__grid {
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
gap: 12px;
}
.div-04__rule {
height: 1px;
background: linear-gradient(90deg,transparent,var(--div-04-line));
}
.div-04__grid .div-04__rule:last-child {
background: linear-gradient(90deg,var(--div-04-line),transparent);
}
.div-04__word {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 10.5px;
color: var(--div-04-mut);
letter-spacing: .04em;
}
.div-04__bimg {
display: flex;
justify-content: center;
border-top: 1px solid transparent;
border-image: linear-gradient(90deg,transparent,var(--div-04-acc),transparent) 1;
padding-top: 12px;
}
.div-04__bimg span {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 10.5px;
color: var(--div-04-mut);
}
.div-04__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11px;
color: var(--div-04-mut);
padding: 8px 14px;
border: 1px solid var(--div-04-line);
border-radius: 99px;
text-align: center;
max-width: 92vw;
}
@media (prefers-reduced-motion: reduce) {
.div-04 * {
transition-duration: .01ms !important;
}
}.div-04 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--div-04-bg);
--div-04-bg: oklch(0.965 0.006 250);
--div-04-card: oklch(1 0 0);
--div-04-ink: oklch(0.24 0.02 260);
--div-04-mut: oklch(0.58 0.018 260);
--div-04-line: oklch(0.24 0.02 260/.14);
--div-04-acc: oklch(0.52 0.17 268);
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
color: var(--div-04-ink);
}
.div-04 *,
.div-04 *::before,
.div-04 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.div-04__stage {
min-height: 100svh;
display: grid;
place-content: center;
justify-items: center;
gap: 22px;
padding: clamp(24px,5vw,60px) clamp(20px,5vw,56px);
background: radial-gradient(90% 70% at 50% 0%,oklch(1 0 0),transparent);
}
.div-04__card {
width: min(92vw,392px);
background: var(--div-04-card);
border: 1px solid var(--div-04-line);
border-radius: 18px;
padding: clamp(24px,4vw,32px);
box-shadow: 0 18px 44px oklch(0.24 0.02 260/.09);
display: grid;
gap: 16px;
}
.div-04__title {
font-size: 21px;
font-weight: 680;
letter-spacing: -.02em;
text-align: center;
margin-bottom: 2px;
}
.div-04__oauth,
.div-04__email {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
min-height: 46px;
width: 100%;
border-radius: 11px;
font-size: 14.5px;
font-weight: 600;
cursor: pointer;
font-family: inherit;
transition: background .18s ease,border-color .18s ease,transform .18s ease;
}
.div-04__oauth {
background: var(--div-04-card);
border: 1px solid var(--div-04-line);
color: var(--div-04-ink);
}
.div-04__oauth:hover {
background: oklch(0.97 0.004 260);
}
.div-04__email {
background: var(--div-04-acc);
border: 1px solid transparent;
color: oklch(0.99 0.01 268);
}
.div-04__email:hover {
background: oklch(0.46 0.17 268);
}
.div-04__oauth:active,
.div-04__email:active {
transform: translateY(1px);
}
.div-04__oauth:focus-visible,
.div-04__email:focus-visible {
outline: 2px solid var(--div-04-acc);
outline-offset: 2px;
}
.div-04__or {
display: flex;
align-items: center;
gap: 14px;
font-size: 11.5px;
font-weight: 650;
letter-spacing: .16em;
text-transform: uppercase;
color: var(--div-04-mut);
}
.div-04__or::before,
.div-04__or::after {
content: '';
flex: 1 1 0;
height: 1px;
background: var(--div-04-line);
}
.div-04__variants {
display: grid;
gap: 14px;
margin-top: 6px;
padding-top: 16px;
border-top: 1px dashed var(--div-04-line);
}
.div-04__grid {
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
gap: 12px;
}
.div-04__rule {
height: 1px;
background: linear-gradient(90deg,transparent,var(--div-04-line));
}
.div-04__grid .div-04__rule:last-child {
background: linear-gradient(90deg,var(--div-04-line),transparent);
}
.div-04__word {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 10.5px;
color: var(--div-04-mut);
letter-spacing: .04em;
}
.div-04__bimg {
display: flex;
justify-content: center;
border-top: 1px solid transparent;
border-image: linear-gradient(90deg,transparent,var(--div-04-acc),transparent) 1;
padding-top: 12px;
}
.div-04__bimg span {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 10.5px;
color: var(--div-04-mut);
}
.div-04__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11px;
color: var(--div-04-mut);
padding: 8px 14px;
border: 1px solid var(--div-04-line);
border-radius: 99px;
text-align: center;
max-width: 92vw;
}
@media (prefers-reduced-motion: reduce) {
.div-04 * {
transition-duration: .01ms !important;
}
}Here's a working CSS Divider from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Text with Lines on Sides Divider CSS ("OR" Divider)
Source: https://codefronts.com/snippets/css-dividers/text-with-lines-on-sides-divider-css-or-divider/
The divider every auth screen and pricing card needs: a centred word flanked by rules that fill whatever space is left. Shown three ways — the flexbox pseudo-element classic, the two-line grid version that needs no pseudo-elements at all, and a border-image one-liner — inside a real sign-in card, with the accessibility answer for whether the word should be announced.
## HTML
```html
<section class="div-04" aria-label="Text with lines on sides OR divider demo">
<div class="div-04__stage">
<div class="div-04__card">
<h2 class="div-04__title">Sign in to Codefronts</h2>
<button class="div-04__oauth" type="button">
<svg viewBox="0 0 18 18" width="17" height="17" aria-hidden="true"><path fill="#4285F4" d="M17.6 9.2c0-.6-.1-1.2-.2-1.8H9v3.5h4.8a4.1 4.1 0 0 1-1.8 2.7v2.2h2.9c1.7-1.6 2.7-3.9 2.7-6.6z"/><path fill="#34A853" d="M9 18c2.4 0 4.5-.8 6-2.2l-2.9-2.2c-.8.5-1.8.9-3.1.9-2.4 0-4.4-1.6-5.1-3.8H.9v2.3A9 9 0 0 0 9 18z"/><path fill="#FBBC05" d="M3.9 10.7a5.4 5.4 0 0 1 0-3.4V5H.9a9 9 0 0 0 0 8l3-2.3z"/><path fill="#EA4335" d="M9 3.6c1.3 0 2.5.5 3.4 1.3l2.6-2.6A9 9 0 0 0 .9 5l3 2.3C4.6 5.2 6.6 3.6 9 3.6z"/></svg>
Continue with Google
</button>
<div class="div-04__or" role="separator" aria-label="or">or</div>
<button class="div-04__email" type="button">Continue with email</button>
<div class="div-04__variants">
<div class="div-04__grid" role="separator" aria-label="grid variant"><span class="div-04__rule"></span><span class="div-04__word">grid 1fr auto 1fr</span><span class="div-04__rule"></span></div>
<div class="div-04__bimg" role="separator" aria-label="border-image variant"><span>border-image</span></div>
</div>
</div>
<p class="div-04__chip">flex:1 1 0 pseudo-rules · role="separator" · aria-label carries the word</p>
</div>
</section>
```
## CSS
```css
.div-04 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--div-04-bg);
--div-04-bg: oklch(0.965 0.006 250);
--div-04-card: oklch(1 0 0);
--div-04-ink: oklch(0.24 0.02 260);
--div-04-mut: oklch(0.58 0.018 260);
--div-04-line: oklch(0.24 0.02 260/.14);
--div-04-acc: oklch(0.52 0.17 268);
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
color: var(--div-04-ink);
}
.div-04 *,
.div-04 *::before,
.div-04 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.div-04__stage {
min-height: 100svh;
display: grid;
place-content: center;
justify-items: center;
gap: 22px;
padding: clamp(24px,5vw,60px) clamp(20px,5vw,56px);
background: radial-gradient(90% 70% at 50% 0%,oklch(1 0 0),transparent);
}
.div-04__card {
width: min(92vw,392px);
background: var(--div-04-card);
border: 1px solid var(--div-04-line);
border-radius: 18px;
padding: clamp(24px,4vw,32px);
box-shadow: 0 18px 44px oklch(0.24 0.02 260/.09);
display: grid;
gap: 16px;
}
.div-04__title {
font-size: 21px;
font-weight: 680;
letter-spacing: -.02em;
text-align: center;
margin-bottom: 2px;
}
.div-04__oauth,
.div-04__email {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
min-height: 46px;
width: 100%;
border-radius: 11px;
font-size: 14.5px;
font-weight: 600;
cursor: pointer;
font-family: inherit;
transition: background .18s ease,border-color .18s ease,transform .18s ease;
}
.div-04__oauth {
background: var(--div-04-card);
border: 1px solid var(--div-04-line);
color: var(--div-04-ink);
}
.div-04__oauth:hover {
background: oklch(0.97 0.004 260);
}
.div-04__email {
background: var(--div-04-acc);
border: 1px solid transparent;
color: oklch(0.99 0.01 268);
}
.div-04__email:hover {
background: oklch(0.46 0.17 268);
}
.div-04__oauth:active,
.div-04__email:active {
transform: translateY(1px);
}
.div-04__oauth:focus-visible,
.div-04__email:focus-visible {
outline: 2px solid var(--div-04-acc);
outline-offset: 2px;
}
.div-04__or {
display: flex;
align-items: center;
gap: 14px;
font-size: 11.5px;
font-weight: 650;
letter-spacing: .16em;
text-transform: uppercase;
color: var(--div-04-mut);
}
.div-04__or::before,
.div-04__or::after {
content: '';
flex: 1 1 0;
height: 1px;
background: var(--div-04-line);
}
.div-04__variants {
display: grid;
gap: 14px;
margin-top: 6px;
padding-top: 16px;
border-top: 1px dashed var(--div-04-line);
}
.div-04__grid {
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
gap: 12px;
}
.div-04__rule {
height: 1px;
background: linear-gradient(90deg,transparent,var(--div-04-line));
}
.div-04__grid .div-04__rule:last-child {
background: linear-gradient(90deg,var(--div-04-line),transparent);
}
.div-04__word {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 10.5px;
color: var(--div-04-mut);
letter-spacing: .04em;
}
.div-04__bimg {
display: flex;
justify-content: center;
border-top: 1px solid transparent;
border-image: linear-gradient(90deg,transparent,var(--div-04-acc),transparent) 1;
padding-top: 12px;
}
.div-04__bimg span {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 10.5px;
color: var(--div-04-mut);
}
.div-04__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11px;
color: var(--div-04-mut);
padding: 8px 14px;
border: 1px solid var(--div-04-line);
border-radius: 99px;
text-align: center;
max-width: 92vw;
}
@media (prefers-reduced-motion: reduce) {
.div-04 * {
transition-duration: .01ms !important;
}
}
```Here's a working CSS Divider from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Text with Lines on Sides Divider CSS ("OR" Divider)
Source: https://codefronts.com/snippets/css-dividers/text-with-lines-on-sides-divider-css-or-divider/
The divider every auth screen and pricing card needs: a centred word flanked by rules that fill whatever space is left. Shown three ways — the flexbox pseudo-element classic, the two-line grid version that needs no pseudo-elements at all, and a border-image one-liner — inside a real sign-in card, with the accessibility answer for whether the word should be announced.
## HTML
```html
<section class="div-04" aria-label="Text with lines on sides OR divider demo">
<div class="div-04__stage">
<div class="div-04__card">
<h2 class="div-04__title">Sign in to Codefronts</h2>
<button class="div-04__oauth" type="button">
<svg viewBox="0 0 18 18" width="17" height="17" aria-hidden="true"><path fill="#4285F4" d="M17.6 9.2c0-.6-.1-1.2-.2-1.8H9v3.5h4.8a4.1 4.1 0 0 1-1.8 2.7v2.2h2.9c1.7-1.6 2.7-3.9 2.7-6.6z"/><path fill="#34A853" d="M9 18c2.4 0 4.5-.8 6-2.2l-2.9-2.2c-.8.5-1.8.9-3.1.9-2.4 0-4.4-1.6-5.1-3.8H.9v2.3A9 9 0 0 0 9 18z"/><path fill="#FBBC05" d="M3.9 10.7a5.4 5.4 0 0 1 0-3.4V5H.9a9 9 0 0 0 0 8l3-2.3z"/><path fill="#EA4335" d="M9 3.6c1.3 0 2.5.5 3.4 1.3l2.6-2.6A9 9 0 0 0 .9 5l3 2.3C4.6 5.2 6.6 3.6 9 3.6z"/></svg>
Continue with Google
</button>
<div class="div-04__or" role="separator" aria-label="or">or</div>
<button class="div-04__email" type="button">Continue with email</button>
<div class="div-04__variants">
<div class="div-04__grid" role="separator" aria-label="grid variant"><span class="div-04__rule"></span><span class="div-04__word">grid 1fr auto 1fr</span><span class="div-04__rule"></span></div>
<div class="div-04__bimg" role="separator" aria-label="border-image variant"><span>border-image</span></div>
</div>
</div>
<p class="div-04__chip">flex:1 1 0 pseudo-rules · role="separator" · aria-label carries the word</p>
</div>
</section>
```
## CSS
```css
.div-04 {
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: var(--div-04-bg);
--div-04-bg: oklch(0.965 0.006 250);
--div-04-card: oklch(1 0 0);
--div-04-ink: oklch(0.24 0.02 260);
--div-04-mut: oklch(0.58 0.018 260);
--div-04-line: oklch(0.24 0.02 260/.14);
--div-04-acc: oklch(0.52 0.17 268);
font-family: 'Segoe UI',system-ui,-apple-system,sans-serif;
color: var(--div-04-ink);
}
.div-04 *,
.div-04 *::before,
.div-04 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.div-04__stage {
min-height: 100svh;
display: grid;
place-content: center;
justify-items: center;
gap: 22px;
padding: clamp(24px,5vw,60px) clamp(20px,5vw,56px);
background: radial-gradient(90% 70% at 50% 0%,oklch(1 0 0),transparent);
}
.div-04__card {
width: min(92vw,392px);
background: var(--div-04-card);
border: 1px solid var(--div-04-line);
border-radius: 18px;
padding: clamp(24px,4vw,32px);
box-shadow: 0 18px 44px oklch(0.24 0.02 260/.09);
display: grid;
gap: 16px;
}
.div-04__title {
font-size: 21px;
font-weight: 680;
letter-spacing: -.02em;
text-align: center;
margin-bottom: 2px;
}
.div-04__oauth,
.div-04__email {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
min-height: 46px;
width: 100%;
border-radius: 11px;
font-size: 14.5px;
font-weight: 600;
cursor: pointer;
font-family: inherit;
transition: background .18s ease,border-color .18s ease,transform .18s ease;
}
.div-04__oauth {
background: var(--div-04-card);
border: 1px solid var(--div-04-line);
color: var(--div-04-ink);
}
.div-04__oauth:hover {
background: oklch(0.97 0.004 260);
}
.div-04__email {
background: var(--div-04-acc);
border: 1px solid transparent;
color: oklch(0.99 0.01 268);
}
.div-04__email:hover {
background: oklch(0.46 0.17 268);
}
.div-04__oauth:active,
.div-04__email:active {
transform: translateY(1px);
}
.div-04__oauth:focus-visible,
.div-04__email:focus-visible {
outline: 2px solid var(--div-04-acc);
outline-offset: 2px;
}
.div-04__or {
display: flex;
align-items: center;
gap: 14px;
font-size: 11.5px;
font-weight: 650;
letter-spacing: .16em;
text-transform: uppercase;
color: var(--div-04-mut);
}
.div-04__or::before,
.div-04__or::after {
content: '';
flex: 1 1 0;
height: 1px;
background: var(--div-04-line);
}
.div-04__variants {
display: grid;
gap: 14px;
margin-top: 6px;
padding-top: 16px;
border-top: 1px dashed var(--div-04-line);
}
.div-04__grid {
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
gap: 12px;
}
.div-04__rule {
height: 1px;
background: linear-gradient(90deg,transparent,var(--div-04-line));
}
.div-04__grid .div-04__rule:last-child {
background: linear-gradient(90deg,var(--div-04-line),transparent);
}
.div-04__word {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 10.5px;
color: var(--div-04-mut);
letter-spacing: .04em;
}
.div-04__bimg {
display: flex;
justify-content: center;
border-top: 1px solid transparent;
border-image: linear-gradient(90deg,transparent,var(--div-04-acc),transparent) 1;
padding-top: 12px;
}
.div-04__bimg span {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 10.5px;
color: var(--div-04-mut);
}
.div-04__chip {
font-family: ui-monospace,Menlo,Consolas,monospace;
font-size: 11px;
color: var(--div-04-mut);
padding: 8px 14px;
border: 1px solid var(--div-04-line);
border-radius: 99px;
text-align: center;
max-width: 92vw;
}
@media (prefers-reduced-motion: reduce) {
.div-04 * {
transition-duration: .01ms !important;
}
}
```How this works
The flexbox version is the one to memorise, because it needs no wrapper spans:
.or{ display:flex; align-items:center; gap:14px;
color:var(--mut); font-size:12px; letter-spacing:.14em; }
.or::before, .or::after{ content:''; flex:1 1 0; height:1px;
background:var(--line); }flex:1 1 0 is doing the real work: both rules take an equal share of the remaining space, so the word stays optically centred no matter how long it is, at any container width, with no measurement. Setting height:1px plus a background beats border-top here because a background can be a gradient — swap it for linear-gradient(90deg,transparent,var(--line)) and the rules fade away from the word.
The grid version replaces the pseudo-elements with real children: grid-template-columns:1fr auto 1fr plus align-items:center. It is a better fit when the divider is a component whose middle slot might hold an icon or a button rather than text. The third form, border-image, fits the whole thing on one property and is the terse choice inside design-system utilities.
Semantically, this is a real separator: role="separator" on the wrapper with the word as its accessible name tells a screen-reader user "OR, separator" — which is exactly what a sighted user perceives.
Make it yours
- Asymmetric rules: give
::beforeflex:0 0 48pxand::afterflex:1for a left-anchored section label — the classic 'chapter heading' divider. - Fading rules:
background:linear-gradient(90deg,transparent,var(--line))on ::before and the mirrored angle on ::after keeps the ends soft. - Pill in the middle: give the text a background, padding and border-radius; the flex gap keeps the rules clear of it automatically.
- Thicker on dark UI: 1px hairlines disappear on dark backgrounds. Use
height:1pxwith acolor-mix(in oklch, var(--ink) 18%, transparent)line rather than a solid grey.
Gotchas — read before shipping
- The old
overflow:hidden+width:50%pseudo-element hack breaks with long words and RTL text. Flex or grid handles both for free. flex:1alone (which means1 1 0%) is correct;flex-grow:1without a zero basis lets differing intrinsic widths push the word off-centre.- Don't build this from a real
<hr>pair — two thematic breaks around one word is nonsense to assistive tech. One wrapper with role="separator" is right. - If the word is decorative chrome (a bullet, a dot), add aria-hidden instead; announcing 'dot separator' between every card is noise.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 15.4+ | 113+ | 111+ |
Flexbox pseudo-element dividers work back to IE11 with minor syntax changes. The floor here is only oklch()/color-mix(); gap on flex containers needs Safari 14.1+.