Flexbox cho thanh công cụ có một phần tử linh hoạt
Bỏ giới hạn tối thiểu tự động ở lớp bọc tài liệu, kiểm tra nút còn trong khung và thêm cách xuống hàng cùng phần tên tệp đọc được bằng bàn phím.

Một tiêu đề tài liệu dài có thể đẩy các nút trên thanh công cụ ra khỏi vùng nhìn dù phần tử flex chứa tiêu đề đã có flex-shrink: 1. Phần tử ấy có thể dừng co tại kích thước tối thiểu tự động. Hãy đặt mức tối thiểu tường minh cho đúng phần tử tham gia bố cục flex, rồi quyết định người đọc sẽ xem phần chữ không còn vừa chỗ như thế nào.
Nếu bạn đã biết cách đặt chiều rộng cơ bản trong CSS, đây là một trường hợp tiếp theo để luyện tìm lỗi. Ví dụ là giao diện bản ghi giả định, gồm tên tệp và hai hành động. Nó dùng cách viết ngang và hướng hàng thông thường. Các nút minh họa bố cục và focus; ví dụ không triển khai thao tác đổi tên hay xuất tệp.
Xác định phần tử flex trực tiếp
Tên tệp nằm trong một lớp bọc .document. Lớp bọc ấy và .toolbar-actions là hai phần tử con trực tiếp của khối flex. Tiêu đề nằm trong lớp bọc không phải phần tử flex trực tiếp của .toolbar.
<section class="editor" aria-label="Điều khiển bản ghi">
<div class="toolbar">
<div class="document">
<h2 class="toolbar-title">quarterly-recording-review-with-a-very-long-filename.webm</h2>
</div>
<div class="toolbar-actions">
<button type="button">Đổi tên</button>
<button type="button">Xuất tệp</button>
</div>
</div>
<details class="file-name">
<summary>Đọc đầy đủ tên tệp</summary>
<p>quarterly-recording-review-with-a-very-long-filename.webm</p>
</details>
</section>
.editor {
max-inline-size: 40rem;
margin-inline: auto;
}
.toolbar {
display: flex;
align-items: center;
gap: 1rem;
}
.document {
flex: 1 1 auto;
min-inline-size: 0;
}
.toolbar-title {
margin: 0;
font-size: 1.125rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.toolbar-actions {
display: flex;
gap: 0.5rem;
flex: 0 0 auto;
}
.toolbar-actions button {
font: inherit;
padding: 0.625rem 0.875rem;
min-block-size: 44px;
}
.file-name {
margin-block-start: 1rem;
overflow-wrap: anywhere;
}
button:focus-visible,
summary:focus-visible {
outline: 3px solid #696d45;
outline-offset: 3px;
}
Ở đây min-inline-size điều khiển mức tối thiểu theo chiều ngang vì chế độ viết là ngang. Lớp bọc có thể giãn vào chỗ chưa dùng và co khi thiếu chỗ. Nhóm hành động không giãn cũng không co: hai nút cùng khoảng cách nội bộ quyết định chiều rộng của nó. Tiêu đề cắt phần chữ thừa bên trong chiều rộng được cấp cho lớp bọc.
Bỏ mức tối thiểu tường minh của lớp bọc thì giá trị mặc định auto có thể giữ mức tối thiểu dựa trên nội dung do tên tệp không xuống dòng đóng góp. Tăng flex-shrink không xóa giới hạn dưới ấy. Phần kích thước tối thiểu tự động của đặc tả Flexbox định nghĩa hành vi này, kể cả tác động của giá trị overflow trên phần tử flex. Tài liệu min-width của MDN cũng giải thích rằng mức tối thiểu tự động phụ thuộc ngữ cảnh bố cục.
Vị trí đặt quy tắc cắt nội dung có ý nghĩa. Trong ví dụ, overflow: hidden nằm ở tiêu đề bên trong. Nó không thay đổi giá trị overflow của chính lớp bọc. Cắt nội dung ngay trên phần tử flex trực tiếp có thể tác động đến mức tối thiểu tự động của phần tử đó, nhưng cắt một phần tử con không thay thế đáng tin cậy cho việc đặt ràng buộc mong muốn ở cha. Hãy kiểm tra ranh giới flex thực tế trước khi chuyển khai báo giữa các bộ chọn.
Hình tách việc cấp kích thước khỏi cách hiển thị chữ. Mức tối thiểu thấp hơn cho phép lớp bọc nhỏ hơn; quy tắc overflow của tiêu đề quyết định phần được vẽ bên trong.
So sánh mức tối thiểu tự động và tường minh
Đặt ví dụ trong khối chứa đủ rộng cho hai nút cộng khoảng cách bên ngoài, nhưng hẹp hơn tổng tên tệp đầy đủ và các nút. Chạy đoạn sau trong console. Mỗi hàng chỉ đổi mức tối thiểu của lớp bọc, ghi chiều rộng của nó và mép phải nhóm hành động so với thanh công cụ, rồi khôi phục style nội tuyến ban đầu.
const toolbar = document.querySelector(".toolbar");
const documentItem = document.querySelector(".document");
const actions = document.querySelector(".toolbar-actions");
const originalStyle = documentItem.style.cssText;
const rows = ["auto", "0px"].map((minimum) => {
documentItem.style.minInlineSize = minimum;
const bar = toolbar.getBoundingClientRect();
const item = documentItem.getBoundingClientRect();
const buttons = actions.getBoundingClientRect();
return {
minimum,
itemWidth: item.width,
actionsRight: buttons.right - bar.left,
available: bar.width,
};
});
documentItem.style.cssText = originalStyle;
console.table(rows);
Với auto, mép phải nhóm hành động có thể vượt chiều rộng có sẵn. Với mức tối thiểu bằng không, lớp bọc có thể nhường đủ chỗ để các hành động vừa trong điều kiện đã nêu. Số pixel chính xác phụ thuộc phông và nhãn, nên hãy so vị trí nằm trong khung thay vì chờ đúng chiều rộng nút của ảnh tiếng Anh. Chạy đoạn này trước khi thêm quy tắc xuống hàng ở phần sau; những quy tắc ấy chủ động đổi bố cục đang được chẩn đoán.
Console chỉ quan sát các hình chữ nhật. Nó không chứng minh tên tệp vẫn nhận diện được, menu hoạt động hay mọi nhãn dịch đều vừa. Một tiêu đề bị CSS cắt vẫn chứa đầy đủ văn bản trong DOM, nhưng riêng điều đó chưa giúp người nhìn màn hình đọc được tên đầy đủ.
Hệ số co không chia đều phần bị giảm
Hệ số co được tính trọng số theo kích thước cơ sở flex của phần tử. Xét một hàng đơn giản riêng, có hai phần tử với kích thước cơ sở 300 và 100 pixel, cùng hệ số co một, mức tối thiểu bằng không, không có gap, padding hay border. Trong hàng rộng 320 pixel, tổng kích thước cơ sở vượt chỗ có sẵn 80 pixel. Các hệ số đã nhân trọng số có tỷ lệ ba trên một, nên hai phần tử giảm 60 và 20 pixel. Chiều rộng kết quả là 240 và 80.
Ví dụ ấy tuân theo thuật toán giải quyết kích thước linh hoạt. Ràng buộc tối thiểu và tối đa có thể chặn kết quả rồi buộc phân phối lại, nên tỷ lệ tính từ kích thước cơ sở chưa phải toàn bộ thuật toán. Đổi sang flex: 1 1 0 làm thay đổi cơ sở; nó vẫn không xóa mức tối thiểu tự động.
Thanh công cụ của ta tránh chia phần co giữa lớp bọc và nhóm hành động bằng cách không cho nhóm sau co lại. Điều này thể hiện rõ ưu tiên mong muốn. Nó cũng tạo ra giới hạn cứng: nếu nhóm hành động cộng gap bên ngoài rộng hơn thanh công cụ, ngay cả lớp bọc tài liệu rộng 0 pixel cũng không làm một hàng ấy vừa chỗ.
Cho phép thành phần dùng nhiều hàng
Thêm các quy tắc sau phía sau stylesheet đầu tiên để bố cục phản ứng với chiều rộng thực sự được cấp. Kích thước cơ sở ưu tiên của tài liệu là lựa chọn thiết kế 14rem. Nó vẫn co được khi đứng riêng trên một hàng. Khối ngoài có thể đưa nhóm hành động xuống hàng khác; bản thân nhóm hành động cũng có thể cho các nút xuống hàng khi cần.
.toolbar {
flex-wrap: wrap;
}
.document {
flex-basis: 14rem;
}
.toolbar-actions {
flex: 0 1 auto;
min-inline-size: 0;
flex-wrap: wrap;
}
.toolbar-actions button {
max-inline-size: 100%;
white-space: normal;
overflow-wrap: anywhere;
}
Bước gom phần tử vào hàng flex xét kích thước ngoài giả định trước khi giải quyết kích thước linh hoạt trên từng hàng. Vì vậy, xuống hàng không chỉ là bước cứu hộ cuối cùng sau khi ép tên tệp còn bằng không. Một kích thước cơ sở ưu tiên có thể đưa hành động xuống hàng tiếp theo khi tiêu đề vẫn còn chỗ hữu ích. Quy tắc gom hàng của Flexbox mô tả thứ tự đó.
Các quy tắc dùng chỗ có sẵn của thành phần, nên cũng phản ứng khi thanh bên hẹp lại trong một vùng nhìn rộng. Chúng giữ thứ tự DOM thay vì chuyển vị trí bằng order hoặc đảo hướng flex. Tiêu đề tài liệu vẫn đứng trước các điều khiển, và Đổi tên vẫn đứng trước Xuất tệp khi hai nút nằm trên các hàng riêng.
Không kích thước cơ sở cố định nào bảo đảm bố cục dùng được ở mọi kích thước có thể tưởng tượng. Chữ rất lớn, padding nhiều hoặc khối chứa cực hẹp vẫn cần kiểm tra. Cho phép chiều cao tăng, thử nhãn đã dịch và tránh ẩn overflow của thanh công cụ chỉ để bỏ thanh cuộn trang. Mất hành động cuối là mất chức năng, không phải bố cục đã thành công.
Giữ tên đầy đủ và đường đi bàn phím
Dấu ba chấm là cách trình bày, không thay đổi tên tệp. Tài liệu text-overflow của MDN giải thích rằng thuộc tính ấy không tự tạo tràn; quy tắc cắt và không xuống dòng tạo ra tình huống đó. Ở chiều rộng quá nhỏ, ngay dấu ba chấm cũng có thể bị cắt. Nếu nhiệm vụ chính là so sánh tên tệp, cho tiêu đề xuống dòng có thể phù hợp hơn việc rút gọn.
Ví dụ có mục “Đọc đầy đủ tên tệp” tường minh bên dưới hàng. Văn bản đầy đủ trong đó được xuống dòng và chọn. Phần tử details gốc của HTML cho phép người dùng bàn phím focus vào summary rồi nhấn Space để mở. Tooltip chỉ xuất hiện khi rê chuột không cung cấp đường đi ấy. Trong ứng dụng, hãy lấy tiêu đề và phần tên đầy đủ từ cùng một giá trị tên tệp để thao tác đổi tên không chỉ cập nhật một bản sao.
Tên lớp CSS toolbar không tạo widget toolbar của ARIA. Hai nút này dùng cách chuyển focus bằng Tab thông thường. Mẫu toolbar của APG mô tả thêm cách quản lý focus và di chuyển bằng phím mũi tên cho widget tổng hợp ấy. Chỉ thêm role chưa triển khai những hành vi đó.
Ở lần kiểm tra cuối, thử cả tiêu đề ngắn lẫn tên dài đã cho, thu hẹp khối chứa độc lập với vùng nhìn và tăng cỡ chữ gấp đôi. Dùng Tab tới cả hai hành động rồi mở phần tên đầy đủ. Điều khiển đang focus cùng đường viền của nó cần còn nhìn thấy, và tên đầy đủ phải đọc được mà không cuộn ngang cả trang. Hãy lặp lại với nhãn hành động dịch dài hơn trước khi coi thành phần đã sẵn sàng.