CSS 12 💻 text combine upright, text underline offset, text underline position and text overflow pro
These CSS properties control character combination, underline positioning, and overflow handling for text, offering fine-grained control over typography and layout.
Overview of Properties
| Property | Description | Common Values |
|---|---|---|
text-combine-upright | Combines characters into a single upright glyph | none, all |
text-underline-offset | Sets the distance of the underline | auto, 2px, 0.2em, 10% |
text-underline-position | Sets the position of the underline | auto, under, left, right |
text-overflow | Controls how hidden overflow is displayed | clip, ellipsis |
1. text-combine-upright
The text-combine-upright property controls how characters are combined into a single upright glyph — primarily used in vertical writing modes (e.g., for CJK text or numbers).
.text-combine-upright-none {
text-combine-upright: none; /* Default — no combining */
}
.text-combine-upright-all {
text-combine-upright: all; /* Combines all characters into one upright unit */
}
Values
| Value | Description | Example |
|---|---|---|
none | Default — does not combine characters | text-combine-upright: none; |
all | Combines all characters in a word into one upright unit | text-combine-upright: all; |
digits <n> | Combines up to N digits | text-combine-upright: digits 4; |
Use case: In vertical Japanese text, numbers like “2024” can be combined into a single upright block instead of being rotated.
2. text-underline-offset
The text-underline-offset property sets the distance between the text and its underline.
.text-underline-offset-auto {
text-decoration: underline;
text-underline-offset: auto; /* Default — browser decides */
}
.text-underline-offset-2px {
text-decoration: underline;
text-underline-offset: 2px; /* Moves underline down by 2px */
}
.text-underline-offset-relative {
text-decoration: underline;
text-underline-offset: 0.2em; /* Relative to font size */
}
.text-underline-offset-percent {
text-decoration: underline;
text-underline-offset: 10%; /* Percentage of font size */
}
Values
| Value | Description | Example |
|---|---|---|
auto | Default — browser determines the offset | text-underline-offset: auto; |
length | Fixed offset (px, em, rem) | text-underline-offset: 2px; |
percentage | Percentage of font size | text-underline-offset: 10%; |
3. text-underline-position
The text-underline-position property specifies where the underline should appear.
.text-underline-position-auto {
text-decoration: underline;
text-underline-position: auto; /* Default — browser decides */
}
.text-underline-position-under {
text-decoration: underline;
text-underline-position: under; /* Below the text (avoids descenders) */
}
.text-underline-position-left {
text-decoration: underline;
text-underline-position: left; /* Left of the text (vertical writing) */
}
.text-underline-position-right {
text-decoration: underline;
text-underline-position: right; /* Right of the text (vertical writing) */
}
Values
| Value | Description | Example |
|---|---|---|
auto | Default — browser decides | text-underline-position: auto; |
under | Places underline below the text (avoids descenders) | text-underline-position: under; |
left | Places underline to the left (vertical writing) | text-underline-position: left; |
right | Places underline to the right (vertical writing) | text-underline-position: right; |
4. text-overflow
The text-overflow property controls how hidden content is displayed when it overflows its container. It only works with white-space: nowrap and a constrained width.
.overflow-clip {
width: 100px;
white-space: nowrap;
overflow: hidden;
text-overflow: clip; /* Cuts off the text */
}
.overflow-ellipsis {
width: 100px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; /* Shows "..." */
}
Values
| Value | Description | Example |
|---|---|---|
clip | Cuts off the text at the container edge | text-overflow: clip; |
ellipsis | Shows “…” to indicate clipped text | text-overflow: ellipsis; |
string | Uses a custom string (e.g., “→”) | text-overflow: "→"; |
Global Values (for all properties)
| Value | Description |
|---|---|
inherit | Inherits the value from the parent element |
initial | Sets the property to its default value |
unset | Inherits if possible, otherwise uses initial |
revert | Reverts to the browser’s default styles |
revert-layer | Reverts to the value in the previous cascade layer |
Complete Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>text-combine-upright, text-underline-offset, text-underline-position, text-overflow</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background: #f8f9fa;
line-height: 1.8;
}
h1 {
color: #007bff;
border-bottom: 3px solid #007bff;
padding-bottom: 10px;
}
h2 {
color: #28a745;
border-left: 4px solid #28a745;
padding-left: 15px;
margin-top: 30px;
}
section {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
margin: 20px 0;
}
.demo-box {
padding: 15px;
border-radius: 8px;
margin: 10px 0;
border: 2px solid #ddd;
background: #f8f9fa;
}
.grid-2 {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
.code-block {
background: #1e1e1e;
color: #d4d4d4;
padding: 15px;
border-radius: 8px;
overflow-x: auto;
font-family: 'Courier New', monospace;
font-size: 0.9rem;
line-height: 1.8;
margin: 10px 0;
}
.reference-table {
width: 100%;
border-collapse: collapse;
margin: 15px 0;
}
.reference-table th,
.reference-table td {
padding: 10px;
border: 1px solid #ddd;
text-align: left;
}
.reference-table th {
background: #007bff;
color: white;
}
.reference-table tr:nth-child(even) {
background: #f8f9fa;
}
/* ====== TEXT COMBINE UPRIGHT ====== */
.tcu-none {
text-combine-upright: none;
writing-mode: vertical-rl;
height: 200px;
border: 1px solid #ddd;
padding: 10px;
}
.tcu-all {
text-combine-upright: all;
writing-mode: vertical-rl;
height: 200px;
border: 1px solid #ddd;
padding: 10px;
}
/* ====== UNDERLINE OFFSET ====== */
.tuo-auto {
text-decoration: underline;
text-underline-offset: auto;
}
.tuo-2px {
text-decoration: underline;
text-underline-offset: 2px;
}
.tuo-6px {
text-decoration: underline;
text-underline-offset: 6px;
}
.tuo-em {
text-decoration: underline;
text-underline-offset: 0.3em;
}
/* ====== UNDERLINE POSITION ====== */
.tup-auto {
text-decoration: underline;
text-underline-position: auto;
}
.tup-under {
text-decoration: underline;
text-underline-position: under;
}
.tup-left {
text-decoration: underline;
text-underline-position: left;
writing-mode: vertical-rl;
height: 150px;
border: 1px solid #ddd;
padding: 10px;
}
.tup-right {
text-decoration: underline;
text-underline-position: right;
writing-mode: vertical-rl;
height: 150px;
border: 1px solid #ddd;
padding: 10px;
}
/* ====== TEXT OVERFLOW ====== */
.to-clip {
width: 180px;
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
border: 1px solid #ddd;
padding: 5px;
background: #f8f9fa;
border-radius: 4px;
}
.to-ellipsis {
width: 180px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
border: 1px solid #ddd;
padding: 5px;
background: #f8f9fa;
border-radius: 4px;
}
.to-string {
width: 180px;
white-space: nowrap;
overflow: hidden;
text-overflow: "→";
border: 1px solid #ddd;
padding: 5px;
background: #f8f9fa;
border-radius: 4px;
}
.note {
font-size: 0.85rem;
color: #6c757d;
margin-top: 5px;
}
</style>
</head>
<body>
<h1>text-combine-upright, text-underline-offset, text-underline-position, text-overflow</h1>
<!-- ====== 1. TEXT COMBINE UPRIGHT ====== -->
<section>
<h2>1. text-combine-upright</h2>
<p>These examples use <code>writing-mode: vertical-rl</code> to demonstrate how characters can be combined in vertical text.</p>
<div class="grid-2">
<div>
<div class="demo-box tcu-none">
<strong>text-combine-upright: none</strong><br>
<span style="font-size: 1.2rem;">2024</span> 年
</div>
<p class="note">Characters are not combined — each digit is separate.</p>
</div>
<div>
<div class="demo-box tcu-all">
<strong>text-combine-upright: all</strong><br>
<span style="font-size: 1.2rem;">2024</span> 年
</div>
<p class="note">All characters combined into a single upright unit.</p>
</div>
</div>
<div class="code-block">
text-combine-upright: none; /* Default — no combining */
text-combine-upright: all; /* Combines all characters */
text-combine-upright: digits 4; /* Combines up to 4 digits */
</div>
</section>
<!-- ====== 2. TEXT UNDERLINE OFFSET ====== -->
<section>
<h2>2. text-underline-offset</h2>
<div class="grid-2">
<div class="demo-box tuo-auto">
<strong>text-underline-offset: auto</strong><br>
This is a sample text with an automatically placed underline below it.
</div>
<div class="demo-box tuo-2px">
<strong>text-underline-offset: 2px</strong><br>
This is a sample text with the underline offset down by 2 pixels.
</div>
<div class="demo-box tuo-6px">
<strong>text-underline-offset: 6px</strong><br>
This is a sample text with the underline offset down by 6 pixels.
</div>
<div class="demo-box tuo-em">
<strong>text-underline-offset: 0.3em</strong><br>
This is a sample text with the underline offset relative to the font size.
</div>
</div>
<div class="code-block">
text-underline-offset: auto; /* Default — browser decides */
text-underline-offset: 2px; /* Moves underline down by 2px */
text-underline-offset: 6px; /* Moves underline down by 6px */
text-underline-offset: 0.3em; /* Relative to font size */
</div>
</section>
<!-- ====== 3. TEXT UNDERLINE POSITION ====== -->
<section>
<h2>3. text-underline-position</h2>
<div class="grid-2">
<div class="demo-box tup-auto">
<strong>text-underline-position: auto</strong><br>
This is a sample text with an automatically placed underline.
</div>
<div class="demo-box tup-under">
<strong>text-underline-position: under</strong><br>
This is a sample text with the underline below the text, avoiding descenders like g, j, p, q, y.
</div>
</div>
<h3>Vertical Writing Modes</h3>
<div class="grid-2">
<div>
<div class="demo-box tup-left">
<strong>text-underline-position: left</strong><br>
This text is in vertical writing mode with underline on the left.
</div>
<p class="note">Underline appears to the left of vertical text.</p>
</div>
<div>
<div class="demo-box tup-right">
<strong>text-underline-position: right</strong><br>
This text is in vertical writing mode with underline on the right.
</div>
<p class="note">Underline appears to the right of vertical text.</p>
</div>
</div>
<div class="code-block">
text-underline-position: auto; /* Default — browser decides */
text-underline-position: under; /* Below the text (avoids descenders) */
text-underline-position: left; /* Left of text (vertical writing) */
text-underline-position: right; /* Right of text (vertical writing) */
</div>
</section>
<!-- ====== 4. TEXT OVERFLOW ====== -->
<section>
<h2>4. text-overflow</h2>
<p><code>text-overflow</code> only works with <code>white-space: nowrap</code> and <code>overflow: hidden</code>.</p>
<div class="grid-2">
<div>
<div class="to-clip">
<strong>text-overflow: clip</strong> — This text will be clipped.
</div>
<p class="note">Cuts off the text at the container edge.</p>
</div>
<div>
<div class="to-ellipsis">
<strong>text-overflow: ellipsis</strong> — This text will show an ellipsis.
</div>
<p class="note">Shows "..." to indicate clipped text.</p>
</div>
<div>
<div class="to-string">
<strong>text-overflow: "→"</strong> — This text will show an arrow.
</div>
<p class="note">Uses a custom string to indicate clipped text.</p>
</div>
</div>
<div class="code-block">
/* text-overflow only works with these conditions */
.container {
width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: clip; /* Cuts off the text */
text-overflow: ellipsis; /* Shows "..." */
text-overflow: "→"; /* Custom string */
}
</div>
</section>
<!-- ====== 5. COMBINED EXAMPLE ====== -->
<section>
<h2>5. Combined Example</h2>
<div class="demo-box" style="text-decoration: underline; text-underline-offset: 4px; text-underline-position: under;">
<strong>Combined: underline + offset + position</strong><br>
This text has an underline that is offset 4px below the text and positioned under (avoiding descenders).
</div>
<div class="demo-box" style="width: 250px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border: 1px solid #ddd; padding: 8px; border-radius: 4px;">
This is a long text that will be truncated with an ellipsis when it exceeds the container width.
</div>
<div class="code-block">
/* Combined underline styling */
text-decoration: underline;
text-underline-offset: 4px;
text-underline-position: under;
/* Overflow with ellipsis */
width: 250px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
</div>
</section>
<!-- ====== REFERENCE TABLES ====== -->
<section>
<h2>6. Reference Tables</h2>
<h3>text-combine-upright Values</h3>
<table class="reference-table">
<tr>
<th>Value</th>
<th>Description</th>
<th>Example</th>
</tr>
<tr>
<td><code>none</code></td>
<td>Default — does not combine characters</td>
<td><code>text-combine-upright: none;</code></td>
</tr>
<tr>
<td><code>all</code></td>
<td>Combines all characters into one upright unit</td>
<td><code>text-combine-upright: all;</code></td>
</tr>
<tr>
<td><code>digits <n></code></td>
<td>Combines up to N digits</td>
<td><code>text-combine-upright: digits 4;</code></td>
</tr>
</table>
<h3>text-underline-offset Values</h3>
<table class="reference-table">
<tr>
<th>Value</th>
<th>Description</th>
<th>Example</th>
</tr>
<tr>
<td><code>auto</code></td>
<td>Default — browser determines the offset</td>
<td><code>text-underline-offset: auto;</code></td>
</tr>
<tr>
<td><code>length</code></td>
<td>Fixed offset (px, em, rem)</td>
<td><code>text-underline-offset: 2px;</code></td>
</tr>
<tr>
<td><code>percentage</code></td>
<td>Percentage of font size</td>
<td><code>text-underline-offset: 10%;</code></td>
</tr>
</table>
<h3>text-underline-position Values</h3>
<table class="reference-table">
<tr>
<th>Value</th>
<th>Description</th>
<th>Example</th>
</tr>
<tr>
<td><code>auto</code></td>
<td>Default — browser decides</td>
<td><code>text-underline-position: auto;</code></td>
</tr>
<tr>
<td><code>under</code></td>
<td>Places underline below the text (avoids descenders)</td>
<td><code>text-underline-position: under;</code></td>
</tr>
<tr>
<td><code>left</code></td>
<td>Places underline to the left (vertical writing)</td>
<td><code>text-underline-position: left;</code></td>
</tr>
<tr>
<td><code>right</code></td>
<td>Places underline to the right (vertical writing)</td>
<td><code>text-underline-position: right;</code></td>
</tr>
</table>
<h3>text-overflow Values</h3>
<table class="reference-table">
<tr>
<th>Value</th>
<th>Description</th>
<th>Example</th>
</tr>
<tr>
<td><code>clip</code></td>
<td>Cuts off the text at the container edge</td>
<td><code>text-overflow: clip;</code></td>
</tr>
<tr>
<td><code>ellipsis</code></td>
<td>Shows "..." to indicate clipped text</td>
<td><code>text-overflow: ellipsis;</code></td>
</tr>
<tr>
<td><code>string</code></td>
<td>Uses a custom string</td>
<td><code>text-overflow: "→";</code></td>
</tr>
</table>
<h3>Global Values</h3>
<table class="reference-table">
<tr>
<th>Value</th>
<th>Description</th>
</tr>
<tr>
<td><code>inherit</code></td>
<td>Inherits the value from the parent element</td>
</tr>
<tr>
<td><code>initial</code></td>
<td>Sets the property to its default value</td>
</tr>
<tr>
<td><code>unset</code></td>
<td>Inherits if possible, otherwise uses initial</td>
</tr>
<tr>
<td><code>revert</code></td>
<td>Reverts to the browser's default styles</td>
</tr>
<tr>
<td><code>revert-layer</code></td>
<td>Reverts to the value in the previous cascade layer</td>
</tr>
</table>
</section>
</body>
</html>
Quick Reference
| Property | Description | Common Values |
|---|---|---|
text-combine-upright | Combines characters into one upright glyph | none, all, digits <n> |
text-underline-offset | Distance of the underline | auto, 2px, 0.3em |
text-underline-position | Position of the underline | auto, under, left, right |
text-overflow | How hidden overflow is displayed | clip, ellipsis, "→" |
Best Practices
✅ Do This:
/* Use text-overflow: ellipsis for truncated content */
.truncate {
width: 200px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Use text-underline-offset for better readability */
a {
text-decoration: underline;
text-underline-offset: 3px;
}
/* Use text-underline-position: under for links with descenders */
a {
text-decoration: underline;
text-underline-position: under;
}
❌ Don’t Do This:
/* Don't use text-overflow without white-space: nowrap */
.container {
text-overflow: ellipsis; /* Won't work without nowrap */
/* Add white-space: nowrap and overflow: hidden */
}
/* Don't use text-combine-upright without vertical writing mode */
.text {
text-combine-upright: all; /* Only works in vertical writing modes */
}
Pro Tip: Use text-overflow: ellipsis for truncating long text in tables, cards, or navigation. Use text-underline-offset and text-underline-position: under for better readability of underlined links, especially those with descenders (g, j, p, q, y). text-combine-upright is primarily for CJK vertical text — use it when numbers or Latin characters need to fit into a single character space!
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!