Dùng CSS xử lý triệt để vấn đề tràn văn bản

Sử dụng các thuộc tính CSS thế nào để ngắt văn bản hiệu quả? Bài viết này sẽ tổng hợp các tình huống sử dụng và mẹo hữu ích giúp lập trình viên đưa ra lựa chọn chính xác hơn.

Tràn văn bản là một vấn đề phổ biến khi thiết kế giao diện, đặc biệt với các nội dung dài như bài blog hoặc bình luận. Nếu không được xử lý, điều này có thể ảnh hưởng đến trải nghiệm người dùng vì văn bản có thể chồng lấn lên các thành phần khác, gây rối mắt và khó đọc. Ngoài ra, các từ quá dài không được tự động ngắt dòng có thể làm vỡ bố cục, gia tăng chỉ số dịch chuyển bố cục (CLS – Cumulative Layout Shift), khiến giao diện trở nên kém ổn định.

Upload image

Mặc dù các trình duyệt hiện nay đều hỗ trợ tự động ngắt dòng khi văn bản vượt quá kích thước cho phép, hay còn gọi là cơ chế ngắt dòng mềm (soft line break), nhưng cơ chế mặc định này vẫn chưa đủ để xử lý triệt để các tình huống tràn văn bản.

Chính vì vậy, các thuộc tính CSS như overflow-wrap, word-breakhyphens ra đời nhằm giúp lập trình viên kiểm soát việc ngắt dòng một cách hiệu quả và linh hoạt hơn. Trong bài viết này, hãy cùng mình tìm hiểu sâu hơn về chức năng, cách sử dụng và sự khác biệt giữa 3 thuộc tính này nhé.

Upload image

overflow-wrap

Thuộc tính overflow-wrap giúp kiểm soát cách ngắt dòng của văn bản bằng cách cố gắng giữ nguyên toàn vẹn của một từ. Khi một từ không đủ chỗ trên dòng hiện tại, trình duyệt sẽ ưu tiên đưa toàn bộ từ đó xuống dòng tiếp theo. Tuy nhiên, nếu từ vẫn vượt quá kích thước của dòng mới, trình duyệt sẽ tự động ngắt từ tại vị trí bị tràn để tránh phá vỡ bố cục.

Upload image

Thuộc tính này hỗ trợ 3 giá trị:

  • overflow-wrap: normal
  • overflow-wrap: anywhere
  • overflow-wrap: break-word

Trong đó:

  • normal: Không thay đổi cách ngắt dòng, trình duyệt sẽ tuân theo quy tắc mặc định.
  • anywherebreak-word: Cả hai giá trị này hoạt động tương tự nhau và chỉ khác nhau ở một điểm.

anywhere vs. break-word

Cả anywherebreak-word đều giúp trình duyệt tự động ngắt từ khi không thể hiển thị đầy đủ trên dòng hiện tại. Nếu vẫn không đủ chỗ ở dòng mới, trình duyệt tiếp tục ngắt tại vị trí kí tự bị tràn.

Upload image

Sự khác biệt giữa hai giá trị này nằm ở cách chúng ảnh hưởng đến kích thước nội tại (intrinsic size) của phần tử (element) khi sử dụng với width: min-content hay trong layout flex. Khi tính kích thước nội tại tối thiểu (min-content intrinsic size), hành vi ngắt dòng sẽ không được xem xét để tính vào khi sử dụng giá trị break-word nhưng anywhere thì lại được.

Trong trường hợp width: min-content, anywhere đã ngắt dòng sau chỉ 1 hoặc 2 kí tự. Mặc dù hành vi này có vẻ bất thường, nhưng nó phản ánh đúng cách anywhere hoạt động. Khi sử dụng với width: min-content, mục tiêu là đạt kích thước nhỏ nhất có thể mà không làm tràn nội dung. Do đó, anywhere sẽ cố gắng ngắt nhiều nhất có thể để đáp ứng yêu cầu này. Nhưng đối với break-word, văn bản bị tràn sẽ không được ngắt vì giá trị này đã bị phớt lờ đi.

Upload image

Tương tự, trong bố cục flex, trình duyệt cũng dựa trên kích thước nội tại tối thiểu để phân bố không gian. Do đó, break-word không có ảnh hưởng trong trường hợp này, trong khi anywhere vẫn có thể giúp ngắt từ linh hoạt. Mình sẽ để đường dẫn đến bài viết giải thích đầy đủ hơn ở đây.

Upload image

Lưu ý khi dùng overflow-wrap

Tóm lại, thuộc tính overflow-wrap đặc biệt phù hợp trong các trường hợp cần ưu tiên khả năng đọc của người dùng, chẳng hạn như bài blog, truyện chữ, mô tả sản phẩm,... Đây là những nơi chứa lượng lớn văn bản, đòi hỏi người dùng phải đọc liên tục, nên việc giữ nguyên cấu trúc từ giúp việc theo dõi nội dung trở nên dễ dàng hơn.

Bên cạnh đó, khi sử dụng overflow-wrap với các giá trị anywherebreak-word, cần lưu ý đến sự khác biệt giữa chúng, nhất là khi kết hợp với các thuộc tính ảnh hưởng đến kích thước nội tại tối thiểu như flex hoặc width: min-content. Giá trị anywhere sẽ được trình duyệt tính đến trong quá trình xác định kích thước tối thiểu, trong khi break-wordthì không. Điều này có thể dẫn đến một số hành vi ngoài ý muốn trong bố cục nếu không chú ý kỹ.

word-break

Khác với overflow-wrap, thuộc tính word-break sẽ ngắt dòng ngay tại kí tự gây tràn, thay vì cố gắng bảo toàn toàn bộ từ. Điều này đặc biệt hữu ích trong những trường hợp không muốn xuất hiện khoảng trống quá lớn giữa các từ hoặc phần tử, chẳng hạn như khi hiển thị nhãn cho các radio button dưới đây.

Upload image

Ngoài ra, word-break cũng được thiết kế để hỗ trợ cho các ngôn ngữ thuộc nhóm CJK (Trung, Nhật, Hàn), vốn có cách ngắt dòng khác biệt so với các ngôn ngữ dùng bảng chữ cái Latinh.

Thuộc tính này có ba giá trị chính:

  • word-break: normal
  • word-break: break-all
  • word-break: keep-all

Với normal, trình duyệt sẽ dùng cơ chế mặc định. Ở đây mình sẽ chỉ nói về 2 giá trị là break-allkeep-all. Ngoài ra, word-break cũng có một giá trị khác đó là break-word nhưng nó đã bị lỗi thời.

break-all

break-all cho phép trình duyệt ngắt từ ngay tại bất kỳ kí tự nào bị tràn. Tuy nhiên, giá trị này chỉ ảnh hưởng đến các kí tự không thuộc nhóm CJK. Đối với văn bản CJK, trình duyệt vẫn áp dụng quy tắc ngắt dòng mặc định.

Upload image

keep-all

keep-all có tác động ngược lại, chỉ ảnh hưởng đến các kí tự thuộc nhóm CJK, đảm bảo chúng luôn được giữ nguyên trên cùng một dòng, ngay cả khi gây tràn nội dung. Còn với các kí tự không thuộc nhóm này, chúng sẽ được xử lý theo giá trị normal, tức là ngắt dòng dựa trên quy tắc mặc định của trình duyệt.

Upload image

Lưu ý khi dùng word-break

Như vậy, so với thuộc tính overflow-wrap, word-break không quan tâm tính toàn vẹn mà sẽ ngắt từ ngay tại vị trí bị tràn. Cách xử lý này phù hợp trong các tình huống mà việc bảo toàn từ không quá quan trọng, nơi cần tiết kiệm không gian và tránh khoảng trống lớn giữa các từ, chẳng hạn như hiển thị các chuỗi không thể đọc được như ID, đường dẫn URL, nút (button) nhỏ có kèm biểu tượng, …

Khi sử dụng hai giá trị break-allkeep-all, cần lưu ý đến nhóm ngôn ngữ mà chúng ảnh hưởng đến. Cụ thể, break-all chỉ tác động đến các ngôn ngữ không thuộc nhóm CJK, còn keep-all chỉ có hiệu lực đối với ngôn ngữ thuộc nhóm CJK. Đối với các ngôn ngữ không bị ảnh hưởng, trình duyệt sẽ quay về sử dụng quy tắc ngắt dòng mặc định của nó.

hyphens

Đây là thuộc tính cuối cùng có thể dùng để trình duyệt thực hiện ngắt dòng bằng cách dựa vào kí tự dấu nối (mặc định là -). Một điểm quan trọng của hyphenshỗ trợ nhiều ngôn ngữ khác nhau, dựa trên thuộc tính lang của phần tử.

Các giá trị chính của hyphens bao gồm:

  • hyphens: auto
  • hyphens: manual

auto

Khi sử dụng hyphens: auto, trình duyệt sẽ dựa vào thuộc tính lang để tự động xác định quy tắc ngắt từ và vị trí thêm dấu nối (còn gọi là hyphenation character). Mỗi ngôn ngữ có bộ quy tắc ngắt từ riêng, vì vậy kết quả hiển thị sẽ khác nhau tùy theo ngôn ngữ được khai báo. Ví dụ, với lang="en" (tiếng Anh) và lang="de" (tiếng Đức), cùng một từ có thể được ngắt tại các vị trí khác nhau do sự khác biệt trong bộ quy tắc ngắt từ của từng ngôn ngữ.

Upload image

manual

Giá trị hyphens: manual cho phép người dùng tự xác định vị trí ngắt từ bằng cách chèn các kí tự đặc biệt. Khi từ bị tràn, trình duyệt sẽ kiểm tra và sử dụng các điểm ngắt đã được chỉ định. Ngược lại, nếu không có chỉ định nào, từ sẽ không bị tách dù có tràn ra ngoài vùng hiển thị. Có hai loại kí tự dấu nối có thể sử dụng:

  • Dấu nối mềm (soft hyphen, ký hiệu là ­): Chỉ hiển thị dấu nối khi từ được ngắt xuống dòng
  • Dấu nối cứng (hard hyphen, ký hiệu là -): Luôn hiển thị dấu nối, bất kể có xảy ra ngắt dòng hay không

Ví dụ minh họa giúp làm rõ cách hoạt động của hyphens: manual thông qua 3 trường hợp: không sử dụng dấu nối, sử dụng dấu nối mềm và sử dụng dấu nối cứng.

Upload image

Lưu ý khi dùng hyphens

Không nên kết hợp hyphens với word-break: break-all, vì giá trị break-all sẽ ghi đè cơ chế ngắt từ của hyphens, khiến thuộc tính này không còn hiệu lực.

Ngoài ra, theo kinh nghiệm cá nhân của mình, khi sử dụng hyphens: auto, nên kết hợp với overflow-wrap: break-word (tránh sử dụng word-break vì lí do nêu trên) để đảm bảo khả năng ngắt dòng vẫn được duy trì trong trường hợp auto không tự động xử lý. Điều này là do hyphens tuân theo quy tắc ngôn ngữ: trong một số trường hợp, chẳng hạn như danh từ riêng trong tiếng Anh, dù từ bị tràn thì trình duyệt vẫn có thể không thực hiện ngắt dòng.

Upload image

Bảng tổng hợp

Ba thuộc tính overflow-wrap, word-breakhyphens đóng vai trò quan trọng trong việc kiểm soát cách văn bản được ngắt dòng trên trình duyệt. Việc lựa chọn thuộc tính phù hợp cần dựa trên trường hợp sử dụng cụ thể cũng như mục tiêu hiển thị.

Bảng dưới đây sẽ tổng hợp các tình huống nên dùng và các lưu ý quan trọng cho từng thuộc tính, nhằm giúp các lập trình viên có thể đưa ra những lựa chọn chính xác hơn.

Thuộc tínhoverflow-wrapword-breakhyphens
Trường hợp nên dùngPhù hợp với các đoạn văn bản dài như bài blog, truyện chữ cần người dùng đọc liên tụcPhù hợp với các chỗ cần tiết kiệm không gian và không có khoảng trống lớn giữa các từ hoặc component với nhauPhù hợp khi cần cơ chế ngắt dòng cho nhiều ngôn ngữ khác nhau
Lợi ích chínhNgười dùng dễ theo dõi nội dung hơnGiữ bố cục hài hòa, không tạo các khoảng trống thừaHỗ trợ ngắt dòng thông minh với nhiều bộ quy tắc cho từng ngôn ngữ khác nhau
Lưu ýCần thử nghiệm, kiểm thử khi sử dụng anywhere hoặc break-word chung với các thuộc tính có liên quan đến kích thước nội tại tối thiểu như flex hay width: min-content để tránh xảy ra các hành vi ngoài ý muốnbreak-all chỉ ảnh hưởng đến các ngôn ngữ không thuộc nhóm CJK. Ngược lại, keep-all chỉ tác động lên các nhóm thuộc CJKCần phải xác định ngôn ngữ thông qua thuộc tính lang
Không nên sử dụng chung với thuộc tính word-break vì sẽ bị ghi đè
Với auto thì nên dùng chung với overflow-wrap để tránh một số trường hợp từ bị tràn nhưng không được ngắt bởi auto
Atekco - Home for Authentic Technical Consultants
Atekco on Apple Podcast