|

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

PropertyDescriptionCommon Values
text-combine-uprightCombines characters into a single upright glyphnone, all
text-underline-offsetSets the distance of the underlineauto, 2px, 0.2em, 10%
text-underline-positionSets the position of the underlineauto, under, left, right
text-overflowControls how hidden overflow is displayedclip, 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

ValueDescriptionExample
noneDefault — does not combine characterstext-combine-upright: none;
allCombines all characters in a word into one upright unittext-combine-upright: all;
digits <n>Combines up to N digitstext-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

ValueDescriptionExample
autoDefault — browser determines the offsettext-underline-offset: auto;
lengthFixed offset (px, em, rem)text-underline-offset: 2px;
percentagePercentage of font sizetext-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

ValueDescriptionExample
autoDefault — browser decidestext-underline-position: auto;
underPlaces underline below the text (avoids descenders)text-underline-position: under;
leftPlaces underline to the left (vertical writing)text-underline-position: left;
rightPlaces 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

ValueDescriptionExample
clipCuts off the text at the container edgetext-overflow: clip;
ellipsisShows “…” to indicate clipped texttext-overflow: ellipsis;
stringUses a custom string (e.g., “→”)text-overflow: "→";

Global Values (for all properties)

ValueDescription
inheritInherits the value from the parent element
initialSets the property to its default value
unsetInherits if possible, otherwise uses initial
revertReverts to the browser’s default styles
revert-layerReverts 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 &lt;n&gt;</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

PropertyDescriptionCommon Values
text-combine-uprightCombines characters into one upright glyphnone, all, digits <n>
text-underline-offsetDistance of the underlineauto, 2px, 0.3em
text-underline-positionPosition of the underlineauto, under, left, right
text-overflowHow hidden overflow is displayedclip, 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!