You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用省略号隐藏多余div?Angular标签输入框自适应布局问询

Hey there! Let's tackle your two questions together—hiding excess tags with an ellipsis, and programmatically managing tag visibility in your Angular simulated input container. Here's a practical, tailored solution:

Solution: Adaptive Tag Container with Ellipsis for Excess Content

1. Layout & CSS Foundation

First, let's set up the base structure to ensure your simulated input (.button div) behaves correctly. The core goals are: reserve space for the input field, let tags fill remaining space, and truncate with an ellipsis when tags overflow.

.button {
  display: flex;
  align-items: center;
  gap: 8px; /* Space between tags, input, and ellipsis */
  padding: 6px 10px;
  border: 1px solid #e0e0e0;
  border-radius: 6px;
  min-width: 300px;
  background-color: white;
}

.tag-list {
  display: flex;
  flex-wrap: nowrap;
  overflow: hidden;
  position: relative;
  flex-grow: 1;
}

.tag-item {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  background-color: #f0f0f0;
  border-radius: 4px;
  font-size: 14px;
}

.tag-close-btn {
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
}

.sr-input {
  flex-shrink: 0;
  min-width: 100px; /* Reserve fixed minimum space for input */
  border: none;
  outline: none;
  font-size: 14px;
}

.tag-ellipsis {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  background-color: white; /* Covers truncated tag content */
  padding-left: 4px;
  display: none; /* Hidden by default */
}

2. Angular Component Logic for Dynamic Tag Calculation

Next, we'll add Angular code to programmatically calculate which tags fit, show/hide the ellipsis, and handle tag additions/deletions.

Component Template (app.component.html)

<div class="button" #tagContainer>
  <div class="tag-list" #tagList>
    <div class="tag-item" *ngFor="let tag of visibleTags">
      {{ tag.label }}
      <span class="tag-close-btn" (click)="removeTag(tag)">×</span>
    </div>
    <div class="tag-ellipsis" #ellipsis>...</div>
  </div>
  <input 
    type="text" 
    class="sr-input" 
    #tagInput 
    (keydown.enter)="addTag(tagInput.value)"
    placeholder="Add tag..."
  >
</div>

Component Class (app.component.ts)

import { Component, ElementRef, ViewChild, AfterViewInit, OnInit } from '@angular/core';

interface Tag {
  id: string;
  label: string;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit, OnInit {
  @ViewChild('tagContainer') tagContainer!: ElementRef<HTMLDivElement>;
  @ViewChild('tagList') tagList!: ElementRef<HTMLDivElement>;
  @ViewChild('tagInput') tagInput!: ElementRef<HTMLInputElement>;
  @ViewChild('ellipsis') ellipsis!: ElementRef<HTMLDivElement>;

  allTags: Tag[] = [];
  visibleTags: Tag[] = [];

  ngOnInit() {
    // Example initial tags
    this.allTags = [
      { id: '1', label: 'Angular' },
      { id: '2', label: 'TypeScript' },
      { id: '3', label: 'CSS' },
      { id: '4', label: 'Flexbox' },
      { id: '5', label: 'Responsive' }
    ];
  }

  ngAfterViewInit() {
    this.calculateVisibleTags();
    // Recalculate on window resize for responsiveness
    window.addEventListener('resize', () => this.calculateVisibleTags());
  }

  addTag(label: string) {
    if (!label.trim()) return;
    const newTag: Tag = { id: Date.now().toString(), label: label.trim() };
    this.allTags.push(newTag);
    this.calculateVisibleTags();
    this.tagInput.nativeElement.value = '';
  }

  removeTag(tag: Tag) {
    this.allTags = this.allTags.filter(t => t.id !== tag.id);
    this.calculateVisibleTags();
  }

  calculateVisibleTags() {
    const containerWidth = this.tagContainer.nativeElement.offsetWidth;
    const inputWidth = this.tagInput.nativeElement.offsetWidth;
    const gap = parseInt(getComputedStyle(this.tagContainer.nativeElement).gap);
    const ellipsisWidth = this.ellipsis.nativeElement.offsetWidth;

    // Calculate available space for tags (subtract input, gaps, and ellipsis buffer)
    let availableWidth = containerWidth - inputWidth - (gap * 3);

    const tagElements = this.tagList.nativeElement.querySelectorAll('.tag-item');
    this.visibleTags = [];
    let totalTagWidth = 0;
    let showEllipsis = false;

    for (let i = 0; i < this.allTags.length; i++) {
      const tagWidth = (tagElements[i] as HTMLElement).offsetWidth;
      // Check if adding this tag (plus gap) fits in available space
      if (totalTagWidth + tagWidth <= availableWidth) {
        this.visibleTags.push(this.allTags[i]);
        totalTagWidth += tagWidth + gap; // Add gap between tags
      } else {
        showEllipsis = true;
        break;
      }
    }

    // Hide ellipsis if all tags fit
    if (this.visibleTags.length === this.allTags.length) {
      showEllipsis = false;
    }

    this.ellipsis.nativeElement.style.display = showEllipsis ? 'block' : 'none';
  }
}

3. Key Tips for Smooth Functionality

  • Input Space Reservation: Adjust the min-width on .sr-input to match your design's minimum input size requirement.
  • Responsive Updates: The resize listener ensures the layout adapts when the container size changes (e.g., window resizing, parent component layout shifts).
  • Variable Tag Sizes: This solution works even with tags of different lengths, since we measure each tag's actual rendered width.

内容的提问来源于stack exchange,提问作者Zlatko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:07:24