Hướng dẫn hoàn chỉnh về Flexbox - Thủ thuật CSS

Mục lục:

Anonim

Lý lịch

Các Flexbox Layout(Flexible Box) mô-đun (một W3C Candidate Khuyến nghị như của tháng 10 năm 2017) nhằm mục đích cung cấp một cách hiệu quả hơn để bố trí, class và phân phối không gian giữa các mục trong một container, ngay cả khi kích thước của chúng là không rõ và / hoặc động (do đó từ "flex").

Ý tưởng chính đằng sau bố cục flex là cung cấp cho vùng chứa khả năng thay đổi chiều rộng / chiều cao (và thứ tự) của các mặt hàng để lấp đầy không gian có sẵn một cách tốt nhất (chủ yếu là để phù hợp với tất cả các loại thiết bị hiển thị và kích thước màn hình). Hộp chứa linh hoạt mở rộng các mục để lấp đầy không gian trống có sẵn hoặc thu nhỏ chúng để ngăn tràn.

Quan trọng nhất, bố cục flexbox là bất khả tri theo hướng trái ngược với các bố cục thông thường (khối theo chiều dọc và nội tuyến dựa trên chiều ngang). Mặc dù chúng hoạt động tốt cho các trang, nhưng chúng thiếu tính linh hoạt (không có ý định chơi chữ) để hỗ trợ các ứng dụng lớn hoặc phức tạp (đặc biệt khi nói đến thay đổi hướng, thay đổi kích thước, kéo dài, thu nhỏ, v.v.).

Lưu ý: Bố cục Flexbox thích hợp nhất với các thành phần của ứng dụng và bố cục quy mô nhỏ, trong khi bố cục Grid dành cho bố cục quy mô lớn hơn.

Khái niệm cơ bản & thuật ngữ

Vì flexbox là một mô-đun toàn bộ chứ không phải một thuộc tính riêng lẻ, nó liên quan đến rất nhiều thứ bao gồm toàn bộ tập hợp các thuộc tính của nó. Một số trong số chúng có nghĩa là được đặt trên vùng chứa (phần tử mẹ, được gọi là “vùng chứa linh hoạt”) trong khi những người khác được thiết lập trên vùng chứa con (đã nói “các mục linh hoạt”).

Nếu bố cục "thông thường" dựa trên cả hướng khối và hướng dòng chảy nội tuyến, thì bố cục linh hoạt dựa trên "hướng dòng chảy linh hoạt". Vui lòng xem hình này từ thông số kỹ thuật, giải thích ý tưởng chính đằng sau bố cục flex.

Các mục sẽ được trình bày theo trục main axis(từ main-startđến main-end) hoặc trục chéo (từ cross-startđến cross-end).

  • trục chính - Trục chính của thùng chứa linh hoạt là trục chính mà dọc theo đó các mục linh hoạt được bố trí. Hãy coi chừng, nó không nhất thiết phải nằm ngang; nó phụ thuộc vào flex-directiontài sản (xem bên dưới).
  • main-start | main-end - Các mục linh hoạt được đặt trong vùng chứa bắt đầu từ main-start và đến main-end.
  • kích thước chính - Chiều rộng hoặc chiều cao của một mục linh hoạt, tùy theo kích thước chính, là kích thước chính của mục đó. Thuộc tính kích thước chính của mục flex là thuộc tính "width" hoặc "height", tùy theo kích thước chính.
  • trục chéo - Trục vuông góc với trục chính gọi là trục chéo. Hướng của nó phụ thuộc vào hướng trục chính.
  • bắt đầu chéo | cross-end - Dòng Flex chứa đầy các mặt hàng và được đặt vào thùng chứa bắt đầu từ phía đầu chéo của thùng flex và đi về phía chéo cuối.
  • kích thước chéo - Chiều rộng hoặc chiều cao của một mặt hàng linh hoạt, tùy theo kích thước chữ thập, là kích thước chéo của mặt hàng đó. Thuộc tính kích thước chéo là bất kỳ thuộc tính nào của 'chiều rộng' hoặc 'chiều cao' nằm trong kích thước chéo.

Nhận áp phích!

Tham khảo hướng dẫn này rất nhiều? Ghim một bản sao lên tường văn phòng.

Mua áp phích

Thuộc tính cho Parent
(flex container)

trưng bày

Điều này xác định một vùng chứa linh hoạt; nội dòng hoặc khối tùy thuộc vào giá trị đã cho. Nó cho phép một bối cảnh linh hoạt cho tất cả các con trực tiếp của nó.

.container ( display: flex; /* or inline-flex */ )

Lưu ý rằng các cột CSS không ảnh hưởng đến vùng chứa linh hoạt.

hướng uốn

Điều này thiết lập trục chính, do đó xác định hướng các mục flex được đặt trong vùng chứa flex. Flexbox là (ngoài gói tùy chọn) là một khái niệm bố cục một hướng. Hãy nghĩ về các mục linh hoạt chủ yếu được bố trí theo hàng ngang hoặc cột dọc.

.container ( flex-direction: row | row-reverse | column | column-reverse; )
  • row(mặc định): trái sang phải trong ltr; từ phải sang trái trongrtl
  • row-reverse: phải sang trái trong ltr; trái sang phải trongrtl
  • column: giống như rownhưng từ trên xuống dưới
  • column-reverse: giống như row-reversenhưng từ dưới lên trên

bọc uốn

Theo mặc định, tất cả các mục linh hoạt sẽ cố gắng vừa với một dòng. Bạn có thể thay đổi điều đó và cho phép các mục bọc lại nếu cần với thuộc tính này.

.container ( flex-wrap: nowrap | wrap | wrap-reverse; )
  • nowrap (mặc định): tất cả các mục linh hoạt sẽ nằm trên một dòng
  • wrap: các mục flex sẽ quấn thành nhiều dòng, từ trên xuống dưới.
  • wrap-reverse: các mục flex sẽ quấn thành nhiều dòng từ dưới lên trên.

Có một số bản demo trực quan flex-wrapở đây.

uốn cong

Đây là cách viết tắt của các thuộc tính flex-directionflex-wrap, chúng cùng xác định trục chính và trục chéo của vùng chứa flex. Giá trị mặc định là row nowrap.

.container ( flex-flow: column wrap; )

biện minh cho nội dung

Điều này xác định sự liên kết dọc theo trục chính. Nó giúp phân phối thêm không gian trống còn lại khi tất cả các mục linh hoạt trên một dòng là không linh hoạt hoặc linh hoạt nhưng đã đạt đến kích thước tối đa. Nó cũng thực hiện một số kiểm soát đối với việc căn chỉnh các mục khi chúng tràn dòng.

.container ( justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right… + safe | unsafe; )
  • flex-start (mặc định): các mục được đóng gói về phía bắt đầu của hướng uốn.
  • flex-end: các mặt hàng được đóng gói về phía cuối của hướng uốn.
  • start: các mặt hàng được đóng gói về phía bắt đầu của writing-modehướng.
  • end: các mặt hàng được đóng gói về cuối writing-modehướng.
  • left: các mặt hàng được đóng gói về phía cạnh trái của thùng chứa, trừ khi điều đó không có ý nghĩa với flex-direction, thì nó sẽ hoạt động như thế nào start.
  • right: các mặt hàng được đóng gói về phía bên phải của thùng chứa, trừ khi điều đó không hợp lý với flex-direction, thì nó sẽ hoạt động như thế nào end.
  • center: các mục được căn giữa dọc theo dòng
  • space-between: các mục được phân bố đều trong dòng; mục đầu tiên ở dòng bắt đầu, mục cuối cùng ở dòng cuối
  • space-around: các mục được phân bố đều trong dòng với khoảng trống xung quanh chúng bằng nhau. Lưu ý rằng trực quan các khoảng trống không bằng nhau, vì tất cả các mục đều có khoảng trống bằng nhau ở cả hai bên. Mục đầu tiên sẽ có một đơn vị không gian so với cạnh thùng chứa, nhưng hai đơn vị không gian giữa mục tiếp theo vì mục tiếp theo đó áp dụng khoảng cách riêng.
  • space-evenly: các mục được phân phối sao cho khoảng cách giữa hai mục bất kỳ (và khoảng trống đến các cạnh) là bằng nhau.

Lưu ý rằng hỗ trợ của trình duyệt cho các giá trị này là khác nhau. Ví dụ: space-betweenchưa bao giờ được hỗ trợ từ một số phiên bản Edge và start / end / left / right chưa có trong Chrome. MDN có các biểu đồ chi tiết. Các giá trị an toàn nhất là flex-start, flex-end, và center.

Ngoài ra còn có hai từ khóa bổ sung mà bạn có thể ghép nối với các giá trị này: safeunsafe. Việc sử dụng safeđảm bảo rằng dù bạn thực hiện kiểu định vị này, bạn không thể đẩy một phần tử để nó hiển thị ra ngoài màn hình (ví dụ như ở trên cùng) theo cách mà nội dung cũng không thể cuộn được (được gọi là "mất dữ liệu") .

căn chỉnh các mục

Điều này xác định hành vi mặc định cho cách các mục linh hoạt được bố trí dọc theo trục chéo trên dòng hiện tại. Hãy coi nó như là justify-contentphiên bản cho trục chéo (vuông góc với trục chính).

.container ( align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end +… safe | unsafe; )
  • stretch (mặc định): kéo dài để lấp đầy vùng chứa (vẫn tuân theo chiều rộng tối thiểu / chiều rộng tối đa)
  • flex-start/ start/ self-start: Các sản phẩm được đặt vào lúc bắt đầu của trục chéo. Sự khác biệt giữa những điều này là tinh tế, và là về việc tôn trọng các flex-directionquy tắc hoặc các writing-modequy tắc.
  • flex-end/ end/ self-end: Các sản phẩm được đặt ở phần cuối của trục chéo. Sự khác biệt một lần nữa là tinh tế và là về việc tôn trọng flex-directioncác quy tắc so với writing-modecác quy tắc.
  • center: các mục được căn giữa theo trục chéo
  • baseline: các mục được căn chỉnh chẳng hạn như căn chỉnh đường cơ sở của chúng

Các từ khóa safevà công cụ unsafesửa đổi có thể được sử dụng cùng với tất cả các từ khóa còn lại này (mặc dù lưu ý hỗ trợ trình duyệt) và giải quyết việc giúp bạn ngăn việc căn chỉnh các phần tử khiến nội dung không thể truy cập được.

căn chỉnh nội dung

Điều này căn chỉnh các dòng của vùng chứa linh hoạt bên trong khi có thêm khoảng trống trong trục chéo, tương tự như cách justify-contentcăn chỉnh các mục riêng lẻ trong trục chính.

Lưu ý: Thuộc tính này chỉ có hiệu lực trên các vùng chứa linh hoạt nhiều dòng, trong đó flex-flowđược đặt thành wraphoặc wrap-reverse). Vùng chứa linh hoạt một dòng (tức là nơi flex-flowđược đặt thành giá trị mặc định của nó, no-wrap) sẽ không phản ánh align-content.

.container ( align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline +… safe | unsafe; )
  • normal (mặc định): các mục được đóng gói ở vị trí mặc định của chúng như thể không có giá trị nào được đặt.
  • flex-start/ start: các mặt hàng được đóng gói đến đầu container. (Được hỗ trợ nhiều hơn) flex-starttôn vinh flex-directiontrong khi starttôn vinh writing-modehướng.
  • flex-end/ end: các mặt hàng được đóng gói đến cuối container. Phần (hỗ trợ nhiều hơn) flex-endtôn vinh sự flex-directionkết thúc trong khi tôn vinh writing-modephương hướng.
  • center: các mục được căn giữa trong vùng chứa
  • space-between: các mặt hàng được phân bổ đồng đều; dòng đầu tiên ở đầu vùng chứa trong khi dòng cuối cùng ở cuối
  • space-around: các mục được phân bổ đồng đều với khoảng cách bằng nhau xung quanh mỗi dòng
  • space-evenly: các mục được phân bổ đều với không gian bằng nhau xung quanh chúng
  • stretch: dòng kéo dài để chiếm không gian còn lại

Các từ khóa safevà công cụ unsafesửa đổi có thể được sử dụng cùng với tất cả các từ khóa còn lại này (mặc dù lưu ý hỗ trợ trình duyệt) và giải quyết việc giúp bạn ngăn việc căn chỉnh các phần tử khiến nội dung không thể truy cập được.

Thuộc tính cho trẻ em
(các mục linh hoạt)

đặt hàng

Theo mặc định, các mục flex được sắp xếp theo thứ tự nguồn. Tuy nhiên, thuộc ordertính kiểm soát thứ tự mà chúng xuất hiện trong vùng chứa linh hoạt.

.item ( order: 5; /* default is 0 */ )

uốn cong

Điều này xác định khả năng cho một mục linh hoạt phát triển nếu cần thiết. Nó chấp nhận một giá trị không đơn vị đóng vai trò như một tỷ lệ. Nó chỉ định lượng không gian có sẵn bên trong hộp linh hoạt mà mặt hàng sẽ chiếm.

Nếu tất cả các mục được flex-growđặt thành 1, không gian còn lại trong hộp đựng sẽ được chia đều cho tất cả trẻ em. Nếu một trong các phần tử con có giá trị là 2, thì phần còn lại sẽ chiếm gấp đôi dung lượng so với các phần còn lại (hoặc ít nhất nó sẽ cố gắng như vậy).

.item ( flex-grow: 4; /* default 0 */ )

Số âm không hợp lệ.

uốn cong

Điều này xác định khả năng cho một mục uốn có thể co lại nếu cần thiết.

.item ( flex-shrink: 3; /* default 1 */ )

Số âm không hợp lệ.

cơ sở linh hoạt

Điều này xác định kích thước mặc định của một phần tử trước khi không gian còn lại được phân phối. Nó có thể là một độ dài (ví dụ: 20%, 5rem, v.v.) hoặc một từ khóa. Các autophương tiện từ khóa “nhìn vào bất động sản chiều rộng hoặc chiều cao của tôi” (được tạm thời thực hiện bởi các main-sizetừ khóa cho đến khi bị phản đối). Các contentphương tiện từ khóa “kích cỡ của nó dựa trên nội dung của mục” - từ khóa này không được hỗ trợ tốt, vì vậy thật khó để thử nghiệm và khó khăn hơn để biết những gì anh em của nó max-content, min-contentfit-contentlàm.

.item ( flex-basis: | auto; /* default auto */ )

Nếu được đặt thành 0, không gian thừa xung quanh nội dung sẽ không được tính vào. Nếu được đặt thành auto, không gian bổ sung được phân phối dựa trên flex-growgiá trị của nó . Xem hình ảnh này.

uốn dẻo

Đây là cách viết tắt của flex-grow, flex-shrinkflex-basiskết hợp. Tham số thứ hai và thứ ba ( flex-shrinkflex-basis) là tùy chọn. Giá trị mặc định là 0 1 auto, nhưng nếu bạn đặt nó với một giá trị số duy nhất, thì nó giống như vậy 1 0.

.item ( flex: none | ( ? || ) )

Bạn nên sử dụng thuộc tính viết tắt này hơn là đặt các thuộc tính riêng lẻ. Tốc ký đặt các giá trị khác một cách thông minh.

tự căn chỉnh

Điều này cho phép căn chỉnh mặc định (hoặc căn chỉnh được chỉ định bởi align-items) được ghi đè cho các mục linh hoạt riêng lẻ.

Vui lòng xem align-itemsgiải thích để hiểu các giá trị có sẵn.

.item ( align-self: auto | flex-start | flex-end | center | baseline | stretch; )

Lưu ý rằng float, clearvertical-alignkhông có tác dụng đối với một mục linh hoạt.

Ví dụ

Hãy bắt đầu với một ví dụ rất đơn giản, giải quyết một vấn đề gần như hàng ngày: căn giữa hoàn hảo. Không thể đơn giản hơn nếu bạn sử dụng flexbox.

.parent ( display: flex; height: 300px; /* Or whatever */ ) .child ( width: 100px; /* Or whatever */ height: 100px; /* Or whatever */ margin: auto; /* Magic! */ )

Điều này dựa trên thực tế là một ký quỹ được đặt autotrong một vùng chứa linh hoạt sẽ hấp thụ thêm không gian. Vì vậy, đặt lề dọc của autosẽ làm cho mục được căn giữa một cách hoàn hảo theo cả hai trục.

Bây giờ chúng ta hãy sử dụng thêm một số thuộc tính. Hãy xem xét danh sách gồm 6 mục, tất cả đều có kích thước cố định, nhưng có thể được đặt kích thước tự động. Chúng tôi muốn chúng được phân bổ đồng đều trên trục hoành để khi chúng tôi thay đổi kích thước trình duyệt, mọi thứ sẽ cân xứng và không có các truy vấn phương tiện.

.flex-container ( /* We first create a flex layout context */ display: flex; /* Then we define the flow direction and if we allow the items to wrap * Remember this is the same as: * flex-direction: row; * flex-wrap: wrap; */ flex-flow: row wrap; /* Then we define how is distributed the remaining space */ justify-content: space-around; )

Làm xong. Mọi thứ khác chỉ là một số mối quan tâm về kiểu dáng. Dưới đây là một cây bút mô tả ví dụ này. Hãy chắc chắn truy cập CodePen và thử thay đổi kích thước cửa sổ của bạn để xem điều gì sẽ xảy ra.

Hãy thử một cái gì đó khác. Hãy tưởng tượng chúng tôi có một phần tử điều hướng được căn phải trên đầu trang web của mình, nhưng chúng tôi muốn nó được tập trung trên màn hình cỡ trung bình và một cột trên các thiết bị nhỏ. Vừa đủ dễ.

/* Large */ .navigation ( display: flex; flex-flow: row wrap; /* This aligns items to the end line on main-axis */ justify-content: flex-end; ) /* Medium screens */ @media all and (max-width: 800px) ( .navigation ( /* When on medium sized screens, we center it by evenly distributing empty space around items */ justify-content: space-around; ) ) /* Small screens */ @media all and (max-width: 500px) ( .navigation ( /* On small screens, we are no longer using row direction but column */ flex-direction: column; ) )

Hãy thử điều gì đó tốt hơn nữa bằng cách chơi với các vật phẩm linh hoạt! Điều gì về bố cục 3 cột trên thiết bị di động với đầu trang và chân trang có chiều rộng đầy đủ. Và độc lập với thứ tự nguồn.

.wrapper ( display: flex; flex-flow: row wrap; ) /* We tell all items to be 100% width, via flex-basis */ .wrapper> * ( flex: 1 100%; ) /* We rely on source order for mobile-first approach * in this case: * 1. header * 2. article * 3. aside 1 * 4. aside 2 * 5. footer */ /* Medium screens */ @media all and (min-width: 600px) ( /* We tell both sidebars to share a row */ .aside ( flex: 1 auto; ) ) /* Large screens */ @media all and (min-width: 800px) ( /* We invert order of first sidebar and main * And tell the main element to take twice as much width as the other two sidebars */ .main ( flex: 2 0px; ) .aside-1 ( order: 1; ) .main ( order: 2; ) .aside-2 ( order: 3; ) .footer ( order: 4; ) )

Tiền tố Flexbox

Flexbox yêu cầu một số tiền tố của nhà cung cấp để hỗ trợ nhiều trình duyệt nhất có thể. Nó không chỉ bao gồm các thuộc tính trước với tiền tố của nhà cung cấp, mà còn có các tên thuộc tính và giá trị hoàn toàn khác nhau. Điều này là do thông số kỹ thuật của Flexbox đã thay đổi theo thời gian, tạo ra các phiên bản “cũ”, “tweener” và “mới”.

Có lẽ cách tốt nhất để xử lý điều này là viết theo cú pháp mới (và cuối cùng) và chạy CSS của bạn thông qua Autoprefixer, công cụ này xử lý rất tốt các dự phòng.

Ngoài ra, đây là một Sass @mixinđể trợ giúp một số tiền tố, điều này cũng cung cấp cho bạn ý tưởng về những việc cần phải được thực hiện:

@mixin flexbox() ( display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; ) @mixin flex($values) ( -webkit-box-flex: $values; -moz-box-flex: $values; -webkit-flex: $values; -ms-flex: $values; flex: $values; ) @mixin order($val) ( -webkit-box-ordinal-group: $val; -moz-box-ordinal-group: $val; -ms-flex-order: $val; -webkit-order: $val; order: $val; ) .wrapper ( @include flexbox(); ) .item ( @include flex(1 200px); @include order(2); )

Thuộc tính liên quan

  • Hướng dẫn hoàn chỉnh về lưới
  • Các mục nhập nhật ký trên thuộc tính Lưới, như lưới-hàng / cột-lưới

Các nguồn lực khác

  • Flexbox trong thông số kỹ thuật CSS
  • Flexbox tại MDN
  • Flexbox tại Opera
  • Lặn vào Flexbox của Bocoup
  • Kết hợp các cú pháp để hỗ trợ trình duyệt tốt nhất trên CSS-Tricks
  • Flexbox của Raphael Goetter (FR)
  • Flexplorer của Bennett Feely

Lỗi

Flexbox chắc chắn không phải là không có lỗi của nó. Bộ sưu tập tốt nhất trong số chúng mà tôi đã thấy là Flexbugs của Philip Walton và Greg Whitworth. Đó là một nơi mã nguồn mở để theo dõi tất cả chúng, vì vậy tôi nghĩ tốt nhất là chỉ liên kết đến đó.

Hỗ trợ trình duyệt

Bị phá vỡ bởi "phiên bản" của flexbox:

  • (mới) có nghĩa là cú pháp gần đây từ đặc tả (ví dụ display: flex;)
  • (tweener) có nghĩa là một cú pháp không chính thức kỳ lạ từ năm 2011 (ví dụ display: flexbox;:)
  • (cũ) có nghĩa là cú pháp cũ từ năm 2009 (ví dụ display: box;)
Trình duyệt Chrome Safari Firefox Opera I E Cạnh Android iOS
20- (cũ)
21+ (mới)
3.1+ (cũ)
6.1+ (mới)
2-21 (cũ)
22+ (mới)
12.1+ (mới) 10 (tweener)
11+ (mới)
17+ (mới) 2.1+ (cũ)
4.4+ (mới)
3.2+ (cũ)
7.1+ (mới)

Trình duyệt Blackberry 10+ hỗ trợ cú pháp mới.