Hộp linh hoạt

Podcast CSS – 010: Flexbox

Một mẫu thiết kế có thể phức tạp trong thiết kế thích ứng là thanh bên nằm cùng dòng với một số nội dung. Nơi có không gian khung nhìn, mẫu này hoạt động rất hiệu quả, nhưng ở nơi không gian được nén lại, bố cục cứng nhắc đó có thể trở thành vấn đề.

Mô hình bố cục hộp linh hoạt (flexbox) là một mô hình bố cục được thiết kế cho nội dung một chiều. Hiệu quả cao khi lấy nhiều đồ vật có kích thước khác nhau, và trả về bố cục phù hợp nhất cho các mục đó.

Đây là mô hình bố cục lý tưởng cho mẫu thanh bên này. Hộp linh hoạt không chỉ giúp bố trí thanh bên và nội dung cùng dòng, nhưng khi không còn đủ dung lượng, thanh bên sẽ ngắt trên một dòng mới. Thay vì đặt các kích thước cố định để trình duyệt tuân theo, với Flexbox, bạn có thể đưa ra các ranh giới linh hoạt để gợi ý cách hiển thị nội dung.

Bạn có thể làm gì với bố cục linh hoạt?

Bố cục của Flex có những tính năng sau, bạn sẽ có thể khám phá nội dung đó trong hướng dẫn này.

  • Chúng có thể hiển thị theo hàng hoặc cột.
  • Chúng tuân theo chế độ viết của tài liệu.
  • Theo mặc định, biểu trưng này là một dòng nhưng có thể cần gói lên nhiều dòng.
  • Bạn có thể sắp xếp lại các mục trong bố cục một cách trực quan, khỏi thứ tự của chúng trong DOM.
  • Không gian có thể được phân bổ bên trong các mục, để chúng lớn hơn và nhỏ hơn theo không gian có sẵn trong bố mẹ.
  • Bạn có thể phân bổ không gian xung quanh các mục và các đường linh hoạt trong một bố cục bao bọc, bằng cách sử dụng thuộc tính Căn chỉnh hộp.
  • Các mục có thể được căn chỉnh trên trục chéo.

Trục chính và trục chữ thập

Chìa khoá để tìm hiểu về flexbox là cần nắm được khái niệm về một trục chính và một trục chéo. Trục chính là trục do thuộc tính flex-direction đặt. Nếu đó là row, trục chính của bạn nằm dọc theo hàng, nếu là column, trục chính của bạn sẽ nằm dọc theo cột.

Ba hộp nằm cạnh nhau có một mũi tên, chỉ từ trái sang phải. Mũi tên được gắn nhãn Trục chính

Các mục linh hoạt di chuyển như một nhóm trên trục chính. Hãy nhớ rằng: chúng ta có rất nhiều thứ và đang cố gắng bố cục tốt nhất cho các thành phần đó trong một nhóm.

Trục chéo chạy theo hướng khác với trục chính, vì vậy, nếu flex-directionrow, trục chéo sẽ chạy dọc theo cột.

Ba hộp có chiều cao khác nhau, nằm cạnh nhau bằng một mũi tên, chỉ từ trái sang phải. Mũi tên có nhãn Trục chính. Có một mũi tên khác chỉ từ trên xuống dưới. Tham số này được gắn nhãn Trục chéo

Bạn có thể thực hiện hai việc trên trục chéo. Bạn có thể di chuyển các mục riêng lẻ hoặc theo nhóm để các mục này khớp với nhau và linh hoạt vùng chứa. Ngoài ra, nếu bạn đã gói các đường linh hoạt, bạn có thể coi những dòng đó là một nhóm để kiểm soát cách chỉ định không gian cho những dòng đó. Bạn sẽ thấy cách tất cả điều này hoạt động trong thực tế trong suốt hướng dẫn này, hiện tại, xin lưu ý rằng trục chính sẽ theo sau flex-direction.

Tạo vùng chứa linh hoạt

Hãy xem cách hoạt động của flexbox bằng cách lấy một nhóm các mục có kích thước khác nhau và dùng flexbox để xếp chúng.

<div class="container" id="container">
  <div>One</div>
  <div>Item two</div>
  <div>The item we will refer to as three</div>
</div>

Để sử dụng Flexbox, bạn cần khai báo rằng bạn muốn sử dụng ngữ cảnh định dạng linh hoạt và không thông thường bố cục khối và bố cục cùng dòng. Bạn có thể thực hiện việc này bằng cách thay đổi giá trị của thuộc tính display thành flex.

.container {
  display: flex;
}

Như bạn đã tìm hiểu trong hướng dẫn bố cục, tuỳ chọn này sẽ cung cấp cho bạn một hộp cấp khối, với thành phần con linh hoạt cho mục. Các mục linh hoạt ngay lập tức bắt đầu cho thấy một số hành vi của hộp linh hoạt, sử dụng giá trị ban đầu của chúng.

Các giá trị ban đầu có nghĩa là:

  • Các mục sẽ hiển thị theo hàng.
  • Chúng không xuống dòng tự động.
  • Chúng không lớn lên để lấp đầy vùng chứa.
  • Các tham số này xếp hàng ở đầu vùng chứa.

Kiểm soát hướng của mục

Mặc dù bạn chưa thêm thuộc tính flex-direction, các mục được hiển thị dưới dạng hàng vì giá trị ban đầu của flex-directionrow. Nếu muốn thêm một hàng, bạn không cần thêm tài sản. Để thay đổi hướng, hãy thêm thuộc tính và một trong 4 giá trị:

  • row: các mục được bố trí theo hàng.
  • row-reverse: các mục được bố trí dưới dạng hàng từ cuối vùng chứa linh hoạt.
  • column: các mục được bố trí dưới dạng cột.
  • column-reverse : các mục được bố trí dưới dạng cột từ cuối vùng chứa linh hoạt.

Bạn có thể thử tất cả các giá trị bằng cách sử dụng nhóm mục trong bản minh hoạ bên dưới.

Đảo ngược luồng mục và khả năng hỗ trợ tiếp cận

Bạn nên thận trọng khi sử dụng bất kỳ tài sản nào có thể sắp xếp lại giao diện trực quan khác với cách sắp xếp thứ tự trong tài liệu HTML, vì có thể tác động tiêu cực đến khả năng tiếp cận. Giá trị row-reversecolumn-reverse là một ví dụ điển hình cho trường hợp này. Việc sắp xếp lại chỉ xảy ra đối với thứ tự hình ảnh chứ không phải thứ tự logic. Bạn cần hiểu rõ điều này vì thứ tự logic là thứ tự mà trình đọc màn hình sẽ đọc nội dung, và bất kỳ ai điều hướng bằng bàn phím sẽ theo sau.

Bạn có thể xem trong video sau đây cách bố cục hàng đảo ngược, việc di chuyển giữa các đường liên kết bị ngắt kết nối vì việc điều hướng bằng bàn phím đi theo DOM chứ không phải hình ảnh màn hình.

Bất cứ thao tác nào có thể thay đổi thứ tự các mục trong hộp linh hoạt hoặc lưới đều có thể gây ra sự cố này. Do đó, bất kỳ việc sắp xếp lại nào cũng phải bao gồm việc kiểm tra kỹ lưỡng để đảm bảo rằng việc đó không làm cho trang web của bạn khó sử dụng đối với một số người.

Để biết thêm thông tin, hãy xem:

Chế độ và hướng viết

Theo mặc định, các mục Flex được bố trí dưới dạng hàng. Một hàng chạy theo hướng câu lệnh trong chế độ viết và hướng kịch bản. Điều này có nghĩa là nếu bạn làm việc bằng tiếng Ả Rập, có hướng tập lệnh từ phải sang trái (rtl), các mục sẽ thẳng hàng ở bên phải. Thứ tự phím tab cũng sẽ bắt đầu ở bên phải vì đây là cách đọc câu trong tiếng Ả Rập.

Nếu bạn đang dùng chế độ viết dọc, giống như một số kiểu chữ tiếng Nhật, thì một hàng sẽ chạy theo chiều dọc, từ trên xuống dưới. Hãy thử thay đổi flex-direction trong bản minh hoạ đang sử dụng chế độ viết dọc.

Do đó, theo mặc định, các mục linh hoạt hoạt động sẽ được liên kết với chế độ viết của tài liệu. Hầu hết các hướng dẫn được viết bằng tiếng Anh hoặc một ngôn ngữ ngang khác, từ trái sang phải. Điều này sẽ giúp bạn dễ dàng giả định rằng các mục linh hoạt xếp thẳng ở bên trái và chạy theo chiều ngang.

Với trục chính và trục chéo cùng với chế độ viết cần xem xét, mà chúng ta nói về bắt đầukết thúc chứ không phải là trên, dưới, bên trái và bên phải trong flexbox có thể dễ hiểu hơn. Mỗi trục có điểm bắt đầu và kết thúc. Điểm bắt đầu của trục chính được gọi là khởi đầu chính. Vì vậy, các mục linh hoạt của chúng ta sẽ được sắp xếp từ đầu đến cuối. Điểm cuối của trục đó là phần đầu. Điểm bắt đầu của trục chéo là bắt đầu chéo và kết thúc kết thúc.

Biểu đồ được gắn nhãn của các thuật ngữ ở trên

Đóng gói các mục linh hoạt

Giá trị ban đầu của thuộc tính flex-wrapnowrap. Điều này có nghĩa là nếu không có đủ dung lượng trong vùng chứa thì các mục sẽ bị tràn.

Một vùng chứa linh hoạt có 9 mục bên trong, các mục đã thu nhỏ nên một từ nằm trên một dòng
nhưng không có đủ chỗ để hiển thị chúng cạnh nhau nên các mục linh hoạt đã mở rộng bên ngoài
hộp của vùng chứa.
Khi đạt đến kích thước nội dung tối thiểu, các mục linh hoạt sẽ bắt đầu tràn vùng chứa

Các mục được hiển thị bằng giá trị ban đầu sẽ thu nhỏ nhất có thể, giảm xuống kích thước min-content trước khi tràn.

Để gói các mục, hãy thêm flex-wrap: wrap vào vùng chứa linh hoạt.

.container {
  display: flex;
  flex-wrap: wrap;
}

Khi một vùng chứa linh hoạt bao bọc, nó sẽ tạo ra nhiều đường linh hoạt. Về mặt phân bổ theo không gian, mỗi dòng hoạt động như một vùng chứa linh hoạt mới. Do đó, nếu bạn đang gói hàng, không thể lấy mục nào đó ở hàng 2 để thẳng hàng với mục ở trên hàng 1. Điều này nghĩa là flexbox có một chiều. Bạn có thể kiểm soát việc căn chỉnh theo một trục, một hàng hoặc một cột, không thể thực hiện cùng nhau như trong lưới.

Viết tắt Flex-flow

Bạn có thể đặt thuộc tính flex-directionflex-wrap bằng cách sử dụng cách viết tắt flex-flow. Ví dụ: để đặt flex-direction thành column và cho phép các mục gói:

.container {
  display: flex;
  flex-flow: column wrap;
}

Kiểm soát không gian bên trong các mục linh hoạt

Giả sử vùng chứa của chúng ta có nhiều không gian hơn mức cần thiết để hiển thị các mục, các mục hiển thị ngay từ đầu và không tăng lên để lấp đầy chỗ trống. Kích thước nội dung của các video đó không còn tăng lên nữa. Điều này là do giá trị ban đầu của thuộc tính flex- là:

  • flex-grow: 0: các mục không tăng trưởng.
  • flex-shrink: 1: các mục có thể thu nhỏ hơn flex-basis.
  • flex-basis: auto: các mục có kích thước cơ sở là auto.

Giá trị này có thể được biểu thị bằng giá trị từ khoá là flex: initial. Thuộc tính viết tắt flex, hoặc các giá trị dài của flex-grow, flex-shrinkflex-basis được áp dụng cho phần tử con của vùng chứa linh hoạt.

Để các mục tăng lên, còn các mục lớn có nhiều không gian hơn các mục nhỏ thì sử dụng flex:auto. Bạn có thể thử cách này bằng bản minh hoạ ở trên. Thao tác này sẽ đặt các thuộc tính thành:

  • flex-grow: 1: các mục có thể lớn hơn flex-basis.
  • flex-shrink: 1: các mục có thể thu nhỏ hơn flex-basis.
  • flex-basis: auto: các mục có kích thước cơ sở là auto.

Việc sử dụng flex: auto có nghĩa là các mục sẽ có các kích thước khác nhau, vì không gian được chia sẻ giữa các mục được chia sẻ sau khi mỗi mục được bố trí dưới dạng kích thước nội dung tối đa. Vì vậy, một mục lớn sẽ có nhiều không gian hơn. Để buộc tất cả các mục có kích thước nhất quán và bỏ qua thay đổi về kích thước nội dung flex:auto thành flex: 1 trong bản minh hoạ.

Thao tác này sẽ giải nén thành:

  • flex-grow: 1: các mục có thể lớn hơn flex-basis.
  • flex-shrink: 1: các mục có thể thu nhỏ hơn flex-basis.
  • flex-basis: 0: các mục có kích thước cơ sở là 0.

Việc sử dụng flex: 1 cho biết rằng tất cả các mục đều có kích thước bằng 0, do đó tất cả không gian trong vùng chứa linh hoạt đều có sẵn để phân phối. Vì tất cả các mục đều có hệ số flex-grow1, nên tất cả các mục đều phát triển như nhau và không gian được chia sẻ như nhau.

Cho phép mặt hàng tăng trưởng ở nhiều tốc độ

Bạn không cần phải cung cấp cho tất cả các mục hệ số flex-grow1. Bạn có thể cung cấp nhiều hệ số flex-grow cho các mục linh hoạt. Trong bản minh hoạ bên dưới mục đầu tiên có flex: 1, flex: 2 thứ hai và flex: 3 thứ ba. Khi các mục này phát triển từ 0, không gian có sẵn trong vùng chứa linh hoạt sẽ được chia sẻ thành 6. Một phần được gán cho mục đầu tiên, hai phần đến phần thứ hai, vào phần thứ ba.

Bạn có thể làm tương tự với flex-basis của auto, mặc dù bạn sẽ cần chỉ định ba thuộc tính giá trị. Giá trị đầu tiên là flex-grow, flex-shrink thứ hai, và flex-basis thứ ba.

.item1 {
  flex: 1 1 auto;
}

.item2 {
  flex: 2 1 auto;
}

Đây là một trường hợp sử dụng ít phổ biến hơn làm lý do để sử dụng flex-basis của auto là cho phép trình duyệt xác định sự phân phối theo không gian. Tuy nhiên, nếu bạn muốn làm cho mục tăng thêm một chút so với cách thuật toán quyết định, thì mục đó có thể hữu ích.

Sắp xếp lại các mục linh hoạt

Bạn có thể sắp xếp lại các mục trong vùng chứa linh hoạt bằng thuộc tính order. Tài sản này cho phép sắp xếp các mặt hàng theo các nhóm thứ tự. Các mục được bố trí theo hướng do flex-direction chỉ định, giá trị thấp nhất đầu tiên. Nếu nhiều mặt hàng có cùng giá trị, thì mặt hàng đó sẽ được hiển thị cùng với các mặt hàng khác cũng có giá trị đó.

Ví dụ bên dưới minh hoạ thứ tự này.

Kiểm tra kiến thức

Kiểm tra kiến thức về flexbox

Mặc định flex-direction

row
Theo mặc định, hộp linh hoạt sẽ đưa các mục vào một hàng và sắp xếp chúng ngay từ đầu. Khi tính năng xuống dòng tự động, tính năng này sẽ tiếp tục tạo các hàng để trẻ chèn vào.
column
Đặt hướng linh hoạt thành cột là một cách hay để xếp chồng các phần tử, nhưng đây không phải là giá trị mặc định.

Theo mặc định, một vùng chứa linh hoạt sẽ bao bọc các phần tử con.

đúng
Tính năng bao bọc phải được bật.
false
Sử dụng flex-wrap: wrap với display: flex để gói phần tử con

Một mục con linh hoạt có vẻ bị thu nhỏ, thuộc tính linh hoạt nào giúp giảm thiểu điều này?

flex-grow
Thuộc tính này mô tả liệu các phần tử có thể phát triển vượt quá kích thước cơ bản hay không, chứ không phải về cách phần tử sẽ hoạt động trên cơ sở đó.
flex-shrink
Có, thuộc tính này mô tả cách xử lý kích thước nếu chiều rộng giảm xuống dưới cơ sở.
flex-basis
Điều này cung cấp điểm bắt đầu của việc định kích thước, nhưng không cung cấp cách xử lý các trường hợp định kích thước trong đó chiều rộng giảm xuống dưới cơ sở, như trong tình huống rút kích thước.

Tổng quan về căn chỉnh hộp linh hoạt

Flexbox có một tập hợp các thuộc tính để căn chỉnh các mục và phân phối không gian giữa các mục. Các thuộc tính này rất hữu ích nên giờ đây đã được chuyển vào quy cách riêng, bạn cũng sẽ gặp chúng trong Bố cục lưới. Tại đây, bạn có thể tìm hiểu cách hoạt động của các thành phần này khi sử dụng Flexbox.

Có thể đặt một tập hợp các tài sản thành hai nhóm. Thuộc tính cho việc phân phối không gian và thuộc tính cho việc căn chỉnh. Các thuộc tính phân phối không gian là:

  • justify-content: phân phối không gian trên trục chính.
  • align-content: phân phối không gian trên trục chéo.
  • place-content: viết tắt để đặt cả hai thuộc tính ở trên.

Các thuộc tính dùng để căn chỉnh trong hộp linh hoạt:

  • align-self: căn chỉnh một mục trên trục chéo.
  • align-items: căn chỉnh tất cả mục thành một nhóm trên trục chéo.

Nếu bạn đang làm việc trên trục chính, thì các thuộc tính sẽ bắt đầu bằng justify-. Trên trục chéo, chúng bắt đầu bằng align-.

Phân bổ không gian trên trục chính

Với HTML được sử dụng trước đó, các mục linh hoạt được bố trí dưới dạng hàng, có khoảng trống trên trục chính. Các mục không đủ lớn để lấp đầy hoàn toàn vùng chứa linh hoạt. Các mục được xếp hàng ở đầu vùng chứa linh hoạt vì giá trị ban đầu của justify-contentflex-start. Các mục được sắp xếp ở đầu và mọi khoảng trống thừa sẽ nằm ở cuối.

Thêm thuộc tính justify-content vào vùng chứa linh hoạt, hãy gán giá trị flex-end cho nó và các mặt hàng được xếp thành hàng ở cuối thùng chứa và không gian trống được đặt ở đầu thùng.

.container {
  display: flex;
  justify-content: flex-end;
}

Bạn cũng có thể phân phối không gian giữa các mục bằng justify-content: space-between.

Hãy thử một số giá trị trong bản minh hoạ, và xem MDN để biết toàn bộ các giá trị có thể có.

Thông qua flex-direction: column

Nếu bạn đã thay đổi flex-direction thành column thì justify-content sẽ hoạt động trên cột. Để có không gian dự phòng trong vùng chứa khi làm việc dưới dạng cột, bạn cần cung cấp cho vùng chứa của mình height hoặc block-size. Nếu không, bạn sẽ không còn không gian để phân phối ứng dụng.

Hãy thử các giá trị khác nhau, lần này với bố cục cột hộp linh hoạt.

Phân bổ không gian giữa các đường linh hoạt

Với vùng chứa linh hoạt được bao bọc, bạn có thể có khoảng trống để phân phối trên trục chéo. Trong trường hợp này, bạn có thể sử dụng thuộc tính align-content có cùng giá trị với justify-content. Không giống như justify-content (được căn chỉnh các mục với flex-start theo mặc định), giá trị ban đầu của align-contentstretch. Thêm thuộc tính align-content vào vùng chứa linh hoạt để thay đổi hành vi mặc định đó.

.container {
  align-content: center;
}

Hãy thử tính năng này trong bản minh hoạ. Ví dụ này có các dòng bao bọc của các mục linh hoạt, và vùng chứa có block-size để chúng ta có không gian dự phòng.

Viết tắt place-content

Để đặt cả justify-contentalign-content, bạn có thể dùng place-content với một hoặc hai giá trị. Một giá trị sẽ được sử dụng cho cả hai trục, nếu bạn chỉ định cả URL đầu tiên sẽ dùng cho align-content và mã thứ hai cho justify-content.

.container {
  place-content: space-between;
  /* sets both to space-between */
}

.container {
  place-content: center flex-end;
  /* wrapped lines on the cross axis are centered,
  on the main axis items are aligned to the end of the flex container */
}

Căn chỉnh các mục trên trục chéo

Trên trục chéo, bạn cũng có thể căn chỉnh các mục của mình trong đường linh hoạt bằng cách sử dụng align-itemsalign-self. Không gian có sẵn cho việc căn chỉnh này sẽ phụ thuộc vào chiều cao của vùng chứa linh hoạt, hoặc đường cong trong trường hợp một tập hợp các mục được gói.

Giá trị ban đầu của align-selfstretch, đó là lý do tại sao các mục linh hoạt trong một hàng kéo dài đến chiều cao của mục cao nhất theo mặc định. Để thay đổi giá trị này, hãy thêm thuộc tính align-self vào bất kỳ mục linh hoạt nào của bạn.

.container {
  display: flex;
}

.item1 {
  align-self: flex-start;
}

Sử dụng bất kỳ giá trị nào sau đây để căn chỉnh mục:

  • flex-start
  • flex-end
  • center
  • stretch
  • baseline

Xem danh sách đầy đủ các giá trị trên MDN.

Bản minh hoạ tiếp theo có một dòng mục linh hoạt với flex-direction: row. Mục cuối cùng xác định chiều cao của vùng chứa linh hoạt. Mục đầu tiên có thuộc tính align-self với giá trị là flex-start. Hãy thử thay đổi giá trị trên thuộc tính đó để xem giá trị này di chuyển như thế nào trong không gian trên trục chéo.

Thuộc tính align-self được áp dụng cho từng mục. Bạn có thể áp dụng thuộc tính align-items cho vùng chứa linh hoạt để đặt tất cả tài sản align-self riêng lẻ thành một nhóm.

.container {
  display: flex;
  align-items: flex-start;
}

Trong bản minh hoạ tiếp theo, hãy thử thay đổi giá trị của align-items để căn chỉnh tất cả các mục trên chữ thập Trục dưới dạng một nhóm.

Tại sao không có lời tự chứng minh trong hộp linh hoạt?

Các mục linh hoạt hoạt động như một nhóm trên trục chính. Vì vậy, không có khái niệm về việc tách một mục riêng lẻ ra khỏi nhóm đó.

Trong bố cục lưới, các thuộc tính justify-selfjustify-items hoạt động trên trục cùng dòng để căn chỉnh các mục trên trục đó trong khu vực lưới của chúng. Do cách bố cục linh hoạt xem các mục là một nhóm, các thuộc tính này không được triển khai trong ngữ cảnh linh hoạt.

Cần phải biết rằng flexbox hoạt động rất tốt với lề tự động. Nếu bạn muốn tách một mục khỏi nhóm, hoặc tách nhóm thành hai nhóm, bạn có thể áp dụng lề để thực hiện việc này. Trong ví dụ bên dưới, mục cuối cùng có lề trái là auto. Lề tự động sẽ hấp thụ mọi không gian theo hướng được áp dụng. Tức là thao tác này sẽ đẩy mục sang bên phải, dẫn đến việc chia nhóm.

Cách căn giữa một mục theo chiều dọc và chiều ngang

Bạn có thể dùng thuộc tính căn chỉnh để căn giữa một mục bên trong một hộp khác. Thuộc tính justify-content căn chỉnh mục trên trục chính, chính là hàng. Thuộc tính align-items trên trục chéo.

.container {
  width: 400px;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

Kiểm tra kiến thức

Kiểm tra kiến thức về flexbox

.container {
  display: flex;
  direction: ltr;
}

Để căn chỉnh theo chiều dọc với Flexbox, hãy sử dụng

căn chỉnh từ khoá
Rất tốt
căn đều từ khoá
Rất tiếc
.container {
  display: flex;
  direction: ltr;
}

Để căn chỉnh theo chiều ngang với hộp linh hoạt, hãy sử dụng

căn chỉnh từ khoá
Rất tiếc
căn đều từ khoá
Rất tốt
.container {
  display: flex;
  direction: ltr;
}

Theo mặc định, các mục linh hoạt sẽ được căn chỉnh theo stretch. Nếu bạn muốn xem nội dung kích thước dùng cho các mặt hàng con, bạn sẽ sử dụng kiểu nào sau đây?

justify-content: flex-start
Thuộc tính căn đều là để căn chỉnh ngang, không phải theo chiều dọc.
align-content: start
content căn chỉnh các đường linh hoạt, chứ không căn chỉnh mục con.
height: auto
Việc này sẽ không có hiệu lực.
align-items: flex-start
Có, chúng ta muốn căn chỉnh dọc theo 'trên cùng' hoặc bắt đầu để xoá giá trị kéo giãn mặc định và thay vào đó sử dụng chiều cao của nội dung.

Tài nguyên