Taiga UI 5.0 is out!

LineClamp KIT

Examples API GitHub

On this page

Component cuts overflown text with "..." and shows it by hover

Styles change

Daenerys of the House Targaryen, the First of Her Name, The Unburnt, Queen of the Andals, the Rhoynar and the First Men, Queen of Meereen, Khaleesi of the Great Grass Sea, Protector of the Realm, Lady Regent of the Seven Kingdoms, Breaker of Chains and Mother of Dragons
Use white-space: nowrap to expand to the right
Jorah Mormont of House Mormont, Lord of Bear Island
DRAFT Davis, Julia
Loading...
    
      
    
    
      <div class="island">
    <tui-line-clamp
        [content]="daenerys"
        [lineHeight]="20"
        [linesLimit]="2"
    />
</div>

<div
    tuiNotification
    class="tui-space_bottom-4"
>
    Use
    <code>white-space: nowrap</code>
    to expand to the right
</div>

<div class="island">
    <tui-line-clamp
        [content]="mormont"
        [lineHeight]="20"
        [linesLimit]="1"
    />
</div>
<ng-template #daenerys>
    <div class="hint">
        Daenerys of the House Targaryen, the First of Her Name, The Unburnt, Queen of the Andals, the Rhoynar and the
        First Men, Queen of Meereen, Khaleesi of the Great Grass Sea, Protector of the Realm, Lady Regent of the Seven
        Kingdoms, Breaker of Chains and Mother of Dragons
    </div>
</ng-template>
<ng-template #mormont>
    <div class="hint no-wrap">Jorah Mormont of House Mormont, Lord of Bear Island</div>
</ng-template>

<div class="island">
    <tui-line-clamp [content]="content" />

    <ng-template #content>
        <span
            appearance="negative"
            size="xxs"
            tuiChip
        >
            DRAFT
        </span>

        Davis, Julia
    </ng-template>
</div>

<div class="tui-space_bottom-4">
    <tui-line-clamp
        [content]="value()"
        [linesLimit]="2"
    />

    @if (!value()) {
        <button
            size="s"
            tuiButton
            type="button"
            (click)="update()"
        >
            Load dynamic value
        </button>
    }
</div>

@if (value$ | async; as value) {
    <div class="wrapper">
        <div class="result">
            <div class="content">
                <tui-line-clamp
                    [content]="value"
                    [lineHeight]="20"
                    [linesLimit]="1"
                />
            </div>
        </div>
    </div>
} @else {
    Loading...
}

    
    
      @import '@taiga-ui/styles/utils.less';

.island {
    inline-size: 20rem;
    margin-block-end: 1rem;
    padding: 1rem;
    border: 1px solid var(--tui-border-normal);
    border-radius: 1rem;
    box-sizing: border-box;
}

.hint {
    font: var(--tui-typography-body-s);
    line-height: inherit;
}

.no-wrap {
    white-space: nowrap;
}

.wrapper {
    position: relative;
    inset-block-start: 0;
    inset-inline-start: 0;
    inline-size: 100%;
    margin: 0 auto;
    border: 1px solid var(--tui-border-normal);
    background-color: var(--tui-background-base);
}

.result {
    display: flex;
    inline-size: 100%;
    block-size: 3.5rem;
    align-items: center;

    .content {
        padding: 0 1rem;
    }
}

    

Expanding

Daenerys of the House Targaryen, the First of Her Name, The Unburnt, Queen of the Andals, the Rhoynar and the First Men, Queen of Meereen, Khaleesi of the Great Grass Sea, Protector of the Realm, Lady Regent of the Seven Kingdoms, Breaker of Chains and Mother of Dragons
    
      
    
    
      <div class="island">
    <tui-line-clamp
        content="Daenerys of the House Targaryen, the First of Her Name, The Unburnt, Queen of the Andals, the Rhoynar and the First Men, Queen of Meereen, Khaleesi of the Great Grass Sea, Protector of the Realm, Lady Regent of the Seven Kingdoms, Breaker of Chains and Mother of Dragons"
        class="clamp"
        [linesLimit]="linesLimit"
    />
    <button
        tuiButton
        type="button"
        class="tui-space_top-4"
        (click)="toggle()"
    >
        Toggle
    </button>
</div>

    
    
      .island {
    max-inline-size: 20rem;
    padding: 1rem;
    border: 1px solid var(--tui-border-normal);
    border-radius: 1.75rem;
}

.clamp {
    pointer-events: none;
}

    

Resize parent container

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    
      
    
    
      <div class="example">
    <div
        #parent
        class="line-clamp-box"
        (waResizeObserver)="onResize(parent)"
    >
        <tui-line-clamp
            [content]="content"
            [lineHeight]="lineHeight || getDynamicLineHeight(parent)"
            [linesLimit]="lineLimit || getDynamicLineLimit(parent)"
        />

        <ng-template #content>
            Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the
            industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and
            scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into
            electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of
            Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like
            Aldus PageMaker including versions of Lorem Ipsum.
        </ng-template>
    </div>
</div>

    
    
      .example {
    min-block-size: 15rem;
    max-block-size: 15rem;
}

.line-clamp-box {
    block-size: 5.75rem;
    min-block-size: 1.5rem;
    resize: both;
    overflow: auto;
    padding: 0.5rem;
    border-radius: var(--tui-radius-l);
    border: 1px solid var(--tui-border-normal);
}

    

Clamp inside dropdown

Dropdown —

    
      
    
    
      <h3 class="header">
    Dropdown&nbsp;&mdash;

    <button
        tuiChevron
        tuiDropdownAlign="start"
        tuiDropdownLimitWidth="auto"
        tuiLink
        type="button"
        [tuiDropdown]="template"
        [(tuiDropdownOpen)]="open"
    >
        Open
    </button>
</h3>

<ng-template #template>
    <tui-data-list>
        @for (text of texts; track text) {
            <button
                tuiOption
                type="button"
                class="dropdown-button"
            >
                <tui-line-clamp
                    [content]="text"
                    [linesLimit]="2"
                />
            </button>
        }
    </tui-data-list>
</ng-template>

    
    
      .dropdown-button {
    inline-size: 16rem;
}

    

Custom content workaround

1. Display only the first line, in a popup display remaining lines.

extremely.long.information@example.com

User ID: 5a006cb3-2b69-4b23

First Name: John

Last Name: Doe

2. Do not use `tui-line-clamp`, use `text-overflow: ellipsis` instead.

    
      
    
    
      <p>1. Display only the first line, in a popup display remaining lines.</p>

<div class="island">
    <tui-line-clamp
        [content]="userAdditionalInfo"
        [linesLimit]="1"
    />
</div>

<p>2. Do not use `tui-line-clamp`, use `text-overflow: ellipsis` instead.</p>

<div class="island">
    <p
        class="email"
        [tuiHint]="userAdditionalInfo"
    >
        {{ user.email }}
    </p>
</div>

<ng-template #userAdditionalInfo>
    <span>{{ user.email }}</span>

    <p>User ID: {{ user.id }}</p>
    <p>First Name: {{ user.firstName }}</p>
    <p>Last Name: {{ user.lastName }}</p>
</ng-template>

    
    
      .island {
    inline-size: 20rem;
    margin-block-end: 1rem;
    box-sizing: border-box;
    padding: 1rem;
    border: 1px solid var(--tui-border-normal);
    border-radius: 1rem;
}

.email {
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

    

Virtual content

    
      
    
    
      <tui-scrollbar>
    <cdk-virtual-scroll-viewport
        appendOnly
        itemSize="50"
        tuiScrollable
        class="tui-zero-scrollbar"
    >
        <div *cdkVirtualFor="let user of users; templateCacheSize: 0">
            <tui-line-clamp
                [content]="info"
                [lineHeight]="24"
                [linesLimit]="1"
            />

            <ng-template #info>
                <span>#{{ user.id }}:</span>
                <span>{{ user.email }}</span>
                <br />

                <p>User ID: {{ user.id }}</p>
                <p>First Name: {{ user.firstName }}</p>
                <p>Last Name: {{ user.lastName }}</p>
            </ng-template>
        </div>
    </cdk-virtual-scroll-viewport>
</tui-scrollbar>

    
    
      cdk-virtual-scroll-viewport {
    block-size: 12.5rem;
    border: 1px solid;
    overscroll-behavior: none;
}

div {
    block-size: 3.125rem;
    padding: 0.625rem;
    box-sizing: border-box;
    overscroll-behavior: none;
}

    

Custom font-size and line-height

Daenerys of the House Targaryen, the First of Her Name, The Unburnt, Queen of the Andals, the Rhoynar and the First Men, Queen of Meereen, Khaleesi
    
      
    
    
      <button
    tuiButton
    type="button"
    class="tui-space_bottom-4"
    (click)="toggle()"
>
    Toggle is overflown: {{ hasOverflownContent() }}
</button>

<tui-line-clamp
    [content]="content"
    [lineHeight]="33"
    [linesLimit]="linesLimit"
    (overflownChange)="hasOverflownContent.set($event)"
/>

<ng-template #content>
    <div
        [style.font-size.px]="24"
        [style.line-height.px]="33"
    >
        Daenerys of the House Targaryen, the First of Her Name, The Unburnt, Queen of the Andals, the Rhoynar and the
        First Men, Queen of Meereen, Khaleesi
    </div>
</ng-template>