iT邦幫忙

2025 iThome 鐵人賽

DAY 2
4
Modern Web

Angular 進階實務 30天系列 第 2

Day 2:常見UX實作 - 表格文字處理技巧

  • 分享至 

  • xImage
  •  

情境

每間公司、每個業務單位、每個產品,都會有不同的資料需要用表格展示,有時候欄位會多到懷疑人生跟眼睛,因為從10個到1、200個的情況都有,但實務上就要這麼多,又或是沒想到一個欄位裡面要塞這麼多的字,但螢幕根本沒這麼寬,以下分享一些處理的辦法,可以在會議時跟使用者還有設計師建議,程式碼實作上也可以參考。

網頁畫面參考:Day2


常見Table設計

表格內文字

💡提醒:建議一開始的時候,可以先確認最長文字長度的資料是多長,以利後續規劃跟討論

  • …省略符號設計,點擊後展開
    • 適用情境

      • 次等重要資料:不需要第一眼就核對到全部的資料,有需要的時候再展開即可
      • 超長文字內容:資料真的長到不可思議,使用者同意在多少長度後統一使用省略設計
      • 有限空間配置:表格欄位寬度受限,需要平衡資訊密度與可讀性
    • 舉例情境

      • 系統日誌
        https://ithelp.ithome.com.tw/upload/images/20250817/20162350q6LucWojYJ.png
    • 程式碼,常見方式如下,但是個人覺得最好用的是Directive,所以分享這個方式
      https://ithelp.ithome.com.tw/upload/images/20250817/20162350fhCZAG3SKa.png

      • ellipsis.directive.ts

        import { Directive, ElementRef, Input, OnInit, Renderer2, inject } from '@angular/core';
        
        @Directive({
            selector: '[appEllipsis]',
            standalone: true
        })
        export class EllipsisDirective implements OnInit {
            @Input() appEllipsis: number = 30;
            @Input() originalText: string = '';
        
            private isExpanded = false;
            private el = inject(ElementRef);
            private renderer = inject(Renderer2);
        
            ngOnInit() {
                this.setupEllipsis();
                this.addClickListener();
            }
        
            private setupEllipsis() {
                const text = this.originalText || this.el.nativeElement.textContent;
        
                if (text.length > this.appEllipsis) {
                    this.renderer.addClass(this.el.nativeElement, 'ellipsis-enabled');
                    this.renderer.setAttribute(this.el.nativeElement, 'title', text);
                    this.renderer.setStyle(this.el.nativeElement, 'cursor', 'pointer');
                    this.updateText(text);
                }
            }
        
            private addClickListener() {
                this.renderer.listen(this.el.nativeElement, 'click', () => {
                    this.toggleExpand();
                });
            }
        
            private toggleExpand() {
                this.isExpanded = !this.isExpanded;
                const fullText = this.originalText || this.el.nativeElement.title;
                this.updateText(fullText);
            }
        
            private updateText(fullText: string) {
                const displayText = this.isExpanded || fullText.length <= this.appEllipsis
                    ? fullText
                    : fullText.substring(0, this.appEllipsis) + '...';
        
                this.renderer.setProperty(this.el.nativeElement, 'textContent', displayText);
        
                if (this.isExpanded) {
                    this.renderer.addClass(this.el.nativeElement, 'expanded');
                    this.renderer.setStyle(this.el.nativeElement, 'white-space', 'normal');
                } else {
                    this.renderer.removeClass(this.el.nativeElement, 'expanded');
                    this.renderer.setStyle(this.el.nativeElement, 'white-space', 'nowrap');
                }
            }
        }
        
      • sample.coponent.html

          ...
           <td  [appEllipsis]="30"
                        [originalText]="'這是一段很長的文字內容,包含了詳細的說明和相關資訊,用戶可以看到完整的內容描述'">
           </td>
           ...
        
    • 示意圖

      收合狀態:
      ┌─────────────────────────────┐
      │ 這是一段很長的文字內容...    │ ← 滑鼠指標變成 pointer
      └─────────────────────────────┘
      
      展開狀態:
      ┌─────────────────────────────┐
      │ 這是一段很長的文字內容,包含  │
      │ 了詳細的說明和相關資訊,用戶  │
      │ 可以看到完整的內容描述       │
      └─────────────────────────────┘
      
    • 注意事項

      • 最好要讓人知道這可以點擊,所以指標換成 pointer
  • 折行
    • 適用情境

      • 用在文字長度較長,但重要性高,他必須一次展示在畫面上
    • 舉例情境:

      • 像是姓名、帳號或是訂單號碼,就我所知目前台灣人最長的名字有50個字,曾經遇過最長的帳號有24個字
    • 程式碼,可能會根據需求有一些變化,這裡提供基礎的用法展示

      • sample-table.component.html
      <td class="text-wrap">
        這是一段很長很長的重要文字內容,需要完整顯示給使用者看到每一個字
      </td>
      
      • sample-table.component.scss
      .text-wrap {
          max-width: 300px;
          white-space: normal;
          word-wrap: break-word;
          word-break: break-word;
          line-height: 1.5;
          padding: 12px;
        }
      
    • 示意圖

      一般表格 (可能會撐破版面):
      ┌──────────┬─────────────────────────────────────────────────────────┐
      │ 標題     │ 這是一段很長很長很長很長很長很長很長很長很長的文字內容...    │
      └──────────┴─────────────────────────────────────────────────────────┘
      
      折行設計:
      ┌──────────┬──────────────────────────┐
      │ 標題     │ 這是一段很長很長很長很長  │
      │          │ 很長很長很長很長很長的文  │
      │          │ 字內容,可以完整顯示所有  │
      │          │ 重要資訊                 │
      └──────────┴──────────────────────────┘
      
    • 不適用情境

      • 資料量極大的表格:過多折行會讓表格變得很長,影響整體瀏覽
      • 列印友善的報表:折行可能造成列印時的排版問題

小結

處理表格內的文字顯示問題,關鍵在於平衡資訊完整性與視覺體驗。省略號設計適合次要資訊,折行設計適合重要內容,選擇哪種方式要看業務需求和使用情境。

掌握了文字處理技巧後,接下來還有另一個挑戰:當表格欄位多到塞不下時該怎麼辦? 下一篇將分享如何透過固定欄滑動和明細彈窗設計,處理多欄位的表格佈局問題。

💡 記住:好的表格設計不是把所有資訊塞進去,而是讓使用者能輕鬆找到他們需要的資訊。


上一篇
Day 1:前端工程師的工作實況
下一篇
Day 3:常見UX實作 - 表格佈局設計策略
系列文
Angular 進階實務 30天18
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
yoyochang
iT邦新手 5 級 ‧ 2025-08-16 19:05:04

恭喜開賽!! 期待~

Zoe Wu iT邦新手 4 級 ‧ 2025-08-17 17:00:18 檢舉

一起加油!

我要留言

立即登入留言