Truncate
<quiet-truncate>
Truncates text at a configurable position, including start, center, end, and custom offsets.
This component shortens text that doesn't fit in its container by inserting an indicator at a configurable
position. Unlike CSS text-overflow: ellipsis, which can only truncate at the end, this
component can truncate at the start, center, or anywhere in between. This makes it ideal for for long
filenames, URLs, and other use cases where both the beginning and end of the string are meaningful.
Truncation is a block-level element that spans the full width of its container and doesn't wrap. Truncation
occurs when the container becomes too narrow to display the line of text. When truncated, the component will
include a title attribute containing the full text string.
Try resizing the container, changing the position, or entering your own text below.
<div id="truncate__overview"> <div class="container"> <quiet-truncate position="center" style="font-family: var(--quiet-font-family-mono);"> https://example.com/felines/orange/tabby/furball.jpg </quiet-truncate> </div> <quiet-text-field id="truncate__overview-input" label="Content" value="https://example.com/felines/orange/tabby/furball.jpg" ></quiet-text-field> <quiet-radio label="Position" value="center"> <quiet-radio-item value="start">start</quiet-radio-item> <quiet-radio-item value="center">center</quiet-radio-item> <quiet-radio-item value="end">end</quiet-radio-item> </quiet-radio> </div> <script> const overviewContainer = document.getElementById('truncate__overview'); const overviewInput = document.getElementById('truncate__overview-input'); const overviewTruncate = overviewContainer.querySelector('quiet-truncate'); const overviewRadio = overviewContainer.querySelector('quiet-radio'); overviewRadio.addEventListener('change', () => { overviewTruncate.position = overviewRadio.value; }); overviewInput.addEventListener('quiet-input', () => { overviewTruncate.textContent = overviewInput.value; }); </script> <style> #truncate__overview { display: flex; flex-direction: column; gap: 1rem; .container { resize: horizontal; overflow: hidden; width: 320px; min-width: 80px; max-width: 100%; min-height: calc(1lh + 1rem + 4px); border: dashed 2px var(--quiet-neutral-stroke-softer); border-radius: var(--quiet-border-radius-md); padding: 1rem 0.5rem; } } </style>
Truncation is grapheme-aware, meaning emoji and combined characters such as 👨👩👧👦 are never split apart. The component also re-measures automatically when its container resizes.
When truncation is active, the component sets the host element's title attribute to show the
full text on hover. If you set a custom title on the element, it will be overwritten whenever
the truncation state changes.
Examples Jump to heading
Providing content Jump to heading
Place text content directly inside the element. Leading and trailing whitespace is trimmed automatically, so
you can format your HTML across multiple lines without affecting the output. You can also update the content
programmatically by setting the element's textContent property.
<div style="max-width: 300px; display: flex; flex-direction: column; gap: 0.75rem;"> <quiet-truncate> https://cats.example.com/v3/activities/napping/schedules </quiet-truncate> </div>
This component only operates on plain text. If you place HTML elements inside it, they will be ignored and only the text content will be used.
Adjusting the position Jump to heading
Use the position attribute to control where the indicator appears. The position can be
start, center, or end.
<div id="truncate__position" style="max-width: 300px;"> <quiet-truncate position="center">https://cats.example.com/v3/cats/lady-pawington/projects/bookshelf-surveillance/reports</quiet-truncate> <quiet-radio label="Position" value="center" style="margin-block-start: 1.5rem;"> <quiet-radio-item value="start">start</quiet-radio-item> <quiet-radio-item value="center">center</quiet-radio-item> <quiet-radio-item value="end">end</quiet-radio-item> </quiet-radio> </div> <script> const positionContainer = document.getElementById('truncate__position'); const positionTruncate = positionContainer.querySelector('quiet-truncate'); const positionRadio = positionContainer.querySelector('quiet-radio'); positionRadio.addEventListener('change', () => { positionTruncate.position = positionRadio.value; }); </script>
You can also pass a number between 0 and 1 for fine-grained control. A value of
0.75 produces a
Finder-style truncation that keeps more of the beginning visible, which is useful for filenames where the
extension matters less than the name.
<div id="truncate__custom-position" style="max-width: 300px; display: flex; flex-direction: column; gap: 1rem;"> <quiet-truncate position="0.75"> 8f14e45f-ceea-367f-a27f-c790a516b650-captain-beans-treat-heist.log </quiet-truncate> <quiet-slider id="truncate__position-slider" min="0" max="1" step="0.05" value="0.75" with-tooltip tooltip-placement="bottom" style="max-width: 300px;" ></quiet-slider> </div> <script> const posContainer = document.getElementById('truncate__custom-position'); const posSlider = document.getElementById('truncate__position-slider'); const posTruncate = posContainer.querySelector('quiet-truncate'); posSlider.addEventListener('quiet-input', () => { posTruncate.position = posSlider.value; }); </script>
Custom indicator Jump to heading
Use the indicator attribute to change the truncation indicator from the default
… to any string you prefer.
<div style="max-width: 250px; display: flex; flex-direction: column; gap: 0.75rem;"> <quiet-truncate position="center" indicator=" [...] "> sir-whiskertons-knocks-everything-off-the-counter-with-zero-remorse.mp4 </quiet-truncate> <quiet-truncate position="center" indicator=" ✂️ "> sir-whiskertons-knocks-everything-off-the-counter-with-zero-remorse.mp4 </quiet-truncate> </div>
In a flexbox layout Jump to heading
This component uses display: block, so it naturally fills available space in flex containers.
This makes it easy to build file lists, navigation breadcrumbs, and similar layouts that utilize truncation.
<div id="truncate__flexbox"> <div class="file-row"> <quiet-icon name="file-text" class="file-icon"></quiet-icon> <quiet-truncate position="0.25"> chairman-meow-chief-napping-officer-quarterly-review.pdf </quiet-truncate> <quiet-badge variant="neutral" class="file-size">2.4 MB</quiet-badge> </div> <div class="file-row"> <quiet-icon name="photo" class="file-icon"></quiet-icon> <quiet-truncate position="0.25"> lady-pawington-sunny-windowsill-glamour-shots-panorama.jpg </quiet-truncate> <quiet-badge variant="neutral" class="file-size">8.1 MB</quiet-badge> </div> <div class="file-row"> <quiet-icon name="file-code" class="file-icon"></quiet-icon> <quiet-truncate position="0.25"> src/components/cat-dashboard/widgets/treat-consumption-chart.ts </quiet-truncate> <quiet-badge variant="neutral" class="file-size">12 KB</quiet-badge> </div> </div> <style> #truncate__flexbox { display: flex; flex-direction: column; gap: 0.5rem; max-width: 450px; .file-row { display: flex; align-items: center; gap: 0.5rem; } .file-icon { flex: none; color: var(--quiet-text-muted); } .file-size { flex: none; } } </style>
In a grid layout Jump to heading
Truncation works seamlessly in CSS grid, truncating when a column is too narrow to display the full text.
<div style="display: grid; grid-template-columns: 1fr 100px 80px; gap: 0.5rem 1rem; align-items: center; max-width: 450px;"> <strong>Filename</strong> <strong>Type</strong> <strong>Size</strong> <quiet-truncate position="center"> sir-whiskertons-daily-counter-clearing-incident-reports.md </quiet-truncate> <span>Markdown</span> <span>24 KB</span> <quiet-truncate position="center"> captain-beans-automatic-treat-dispenser-integration-tests.spec.ts </quiet-truncate> <span>TypeScript</span> <span>8.7 KB</span> <quiet-truncate position="center"> princess-mochi-optimal-nap-spot-configuration.yml </quiet-truncate> <span>YAML</span> <span>3.2 KB</span> </div>
In a table Jump to heading
Wrap cell content in <quiet-truncate> to keep tables tidy when columns are too narrow for
the full text.
| Name | Breed | Bio |
|---|---|---|
| Sir Whiskertons III | Maine Coon |
|
| Lady Pawington | Russian Blue |
|
| Captain Beans | Bombay |
|
| Princess Mochi | Ragdoll |
|
<table> <tr> <th>Name</th> <th>Breed</th> <th>Bio</th> </tr> <tr> <td>Sir Whiskertons III</td> <td>Maine Coon</td> <td><quiet-truncate>Gentle giant who follows you around like a furry shadow and demands belly rubs at 3 AM</quiet-truncate></td> </tr> <tr> <td>Lady Pawington</td> <td>Russian Blue</td> <td><quiet-truncate>Elegant silver princess who judges you silently from atop the tallest bookshelf in the house</quiet-truncate></td> </tr> <tr> <td>Captain Beans</td> <td>Bombay</td> <td><quiet-truncate>Mini panther with golden eyes who knocks everything off every counter with zero remorse</quiet-truncate></td> </tr> <tr> <td>Princess Mochi</td> <td>Ragdoll</td> <td><quiet-truncate>Goes completely limp when you pick her up, total sweetheart who lives for being carried around</quiet-truncate></td> </tr> </table>
API Jump to heading
Importing Jump to heading
The autoloader is the recommended way to import components but, if you prefer to do it manually, the following code snippets will be helpful.
To manually import <quiet-truncate> from the CDN, use the following code.
import 'https://cdn.quietui.org/v4.0.0/components/truncate/truncate.js';
To manually import <quiet-truncate> from a self-hosted distribution, use the
following code. Remember to replace /path/to/quiet with the appropriate local path.
import '/path/to/quiet/components/truncate/truncate.js';
Slots Jump to heading
Truncate supports the following slots. Learn more about using slots
| Name | Description |
|---|---|
| (default) | The text content to truncate. |
Properties Jump to heading
Truncate has the following properties that can be set with corresponding attributes. In many cases, the attribute's name is the same as the property's name. If an attribute is different, it will be displayed after the property. Learn more about attributes and properties
| Property | Description | Reflects | Type | Default |
|---|---|---|---|---|
position
|
Controls where the indicator appears. The position can be 'start',
'center', or 'end', or a numeric value representing the ratio of
characters to maintain before the indicator, between 0 (start) and
1 (end).
|
|
'start'
|
'end'
|
indicator
|
The string to insert where text has been truncated. Defaults to a single ellipsis character
….
|
|
string
|
'…'
|
CSS parts Jump to heading
Truncate exposes internal elements that can be styled with CSS using the selectors shown below. Learn more about CSS parts
| Name | Description | CSS selector |
|---|---|---|
content |
The visible truncated text container. |
::part(content)
|
Custom States Jump to heading
Truncate has the following custom states. You can target them with CSS using the selectors shown below. Learn more about custom states
| Name | Description | CSS selector |
|---|---|---|
truncated |
Applied only when the text is truncated. |
:state(truncated)
|