10 bố cục hiện đại trong một dòng CSS

Bài đăng này nêu bật một số dòng CSS mạnh mẽ giúp bạn thực hiện những việc nặng nhọc và xây dựng bố cục hiện đại, mạnh mẽ.

Bố cục CSS hiện đại giúp nhà phát triển viết các quy tắc tạo kiểu thực sự có ý nghĩa và mạnh mẽ chỉ bằng một vài lần nhấn phím. Cuộc trò chuyện ở trên và bài đăng tiếp theo này sẽ xem xét 10 dòng CSS mạnh mẽ có khả năng xử lý nhiều tác vụ nặng.

Để theo dõi hoặc tự mình thử các bản minh hoạ này, hãy xem phần nhúng trang web ở trên hoặc truy cập vào 1linelayouts.com.

01. Super Centered: place-items: center

Đối với bố cục "một dòng" đầu tiên, hãy giải quyết bí ẩn lớn nhất trong tất cả các CSS: căn giữa mọi thứ. Tôi muốn bạn biết rằng việc này dễ hơn bạn nghĩ khi sử dụng place-items: center.

Trước tiên, hãy chỉ định grid làm phương thức display, sau đó viết place-items: center trên cùng một phần tử. place-items là một cách viết tắt để đặt cả align-itemsjustify-items cùng một lúc. Khi bạn đặt thành center, cả align-itemsjustify-items đều được đặt thành center.

.parent {
  display: grid;
  place-items: center;
}

Điều này cho phép nội dung được căn giữa hoàn hảo trong phần tử mẹ, bất kể kích thước vốn có.

02. Bánh kếp được tách riêng: flex: <grow> <shrink> <baseWidth>

Tiếp theo là món bánh pancake được tách riêng! Đây là bố cục thường thấy cho các trang web tiếp thị, ví dụ: có thể có một hàng gồm 3 mục, thường có hình ảnh, tiêu đề và sau đó là một số văn bản mô tả một số tính năng của sản phẩm. Trên thiết bị di động, chúng ta muốn các thành phần đó xếp chồng lên nhau một cách gọn gàng và mở rộng khi tăng kích thước màn hình.

Bằng cách sử dụng Flexbox cho hiệu ứng này, bạn sẽ không cần truy vấn nội dung nghe nhìn để điều chỉnh vị trí của các phần tử này khi màn hình thay đổi kích thước.

Ký hiệu viết tắt flex có nghĩa là: flex: <flex-grow> <flex-shrink> <flex-basis>.

Vì lý do này, nếu bạn muốn các hộp có kích thước <flex-basis>, thu nhỏ khi có kích thước nhỏ hơn nhưng không kéo giãn để lấp đầy mọi khoảng trống bổ sung, hãy viết: flex: 0 1 <flex-basis>. Trong trường hợp này, <flex-basis> của bạn là 150px nên sẽ có dạng như sau:

.parent {
  display: flex;
}

.child {
  flex: 0 1 150px;
}

Nếu bạn muốn các hộp kéo giãn và lấp đầy khoảng trống khi chúng chuyển sang dòng tiếp theo, hãy đặt <flex-grow> thành 1, để có dạng như sau:

.parent {
  display: flex;
}

.child {
  flex: 1 1 150px;
}

Giờ đây, khi bạn tăng hoặc giảm kích thước màn hình, cả hai mục linh hoạt này đều thu nhỏ và tăng kích thước.

03. Thanh bên cho biết: grid-template-columns: minmax(<min>, <max>) …)

Bản minh hoạ này tận dụng hàm minmax cho bố cục lưới. Ở đây, chúng ta sẽ đặt kích thước tối thiểu của thanh bên là 150px, nhưng trên màn hình lớn hơn, chúng ta sẽ cho phép kích thước này kéo dài đến 25%. Thanh bên sẽ luôn chiếm 25% không gian ngang của thành phần mẹ cho đến khi 25% nhỏ hơn 150px.

Thêm giá trị này làm giá trị của grid-template-columns với giá trị sau: minmax(150px, 25%) 1fr. Mục trong cột đầu tiên (thanh bên trong trường hợp này) nhận được minmax150px tại 25% và mục thứ hai (phần main ở đây) chiếm phần còn lại của không gian dưới dạng một bản nhạc 1fr duy nhất.

.parent {
  display: grid;
  grid-template-columns: minmax(150px, 25%) 1fr;
}

04. Pancake Stack: grid-template-rows: auto 1fr auto

Không giống như ví dụ về Deconstructed Pancake (Bánh kếp tách lớp), ví dụ này không bao bọc các thành phần con khi kích thước màn hình thay đổi. Thường được gọi là chân trang cố định, bố cục này thường được dùng cho cả trang web và ứng dụng, trên các ứng dụng di động (chân trang thường là một thanh công cụ) và trang web (các ứng dụng một trang thường dùng bố cục chung này).

Việc thêm display: grid vào thành phần sẽ cung cấp cho bạn một lưới gồm một cột, tuy nhiên, vùng chính sẽ chỉ cao bằng nội dung có chân trang bên dưới.

Để chân trang cố định ở dưới cùng, hãy thêm:

.parent {
  display: grid;
  grid-template-rows: auto 1fr auto;
}

Thao tác này sẽ đặt nội dung tiêu đề và chân trang tự động lấy kích thước của các thành phần con, đồng thời áp dụng khoảng trống còn lại (1fr) cho vùng chính, trong khi hàng có kích thước auto sẽ lấy kích thước nội dung tối thiểu của các thành phần con. Do đó, khi nội dung tăng kích thước, hàng đó sẽ tự động tăng kích thước để điều chỉnh.

05. Bố cục Chén Thánh cổ điển: grid-template: auto 1fr auto / auto 1fr auto

Đối với bố cục kinh điển này, sẽ có tiêu đề, chân trang, thanh bên trái, thanh bên phải và nội dung chính. Bố cục này tương tự như bố cục trước, nhưng giờ đây có thêm thanh bên!

Để viết toàn bộ lưới này bằng một dòng mã duy nhất, hãy sử dụng thuộc tính grid-template. Nhờ đó, bạn có thể đặt cả hàng và cột cùng một lúc.

Cặp thuộc tính và giá trị là: grid-template: auto 1fr auto / auto 1fr auto. Dấu gạch chéo ở giữa danh sách đầu tiên và danh sách thứ hai được phân tách bằng dấu cách là dấu ngắt giữa các hàng và cột.

.parent {
  display: grid;
  grid-template: auto 1fr auto / auto 1fr auto;
}

Như trong ví dụ cuối cùng, nơi tiêu đề và chân trang có nội dung được định kích thước tự động, ở đây, thanh bên trái và bên phải được định kích thước tự động dựa trên kích thước nội tại của các thành phần con. Tuy nhiên, lần này là kích thước ngang (chiều rộng) thay vì kích thước dọc (chiều cao).

06. Lưới 12 cột: grid-template-columns: repeat(12, 1fr)

Tiếp theo là một lưới cổ điển khác: lưới 12 cột. Bạn có thể nhanh chóng viết lưới trong CSS bằng hàm repeat(). Sử dụng: repeat(12, 1fr); cho các cột mẫu lưới sẽ cho bạn 12 cột, mỗi cột có 1fr.

.parent {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.child-span-12 {
  grid-column: 1 / 13;
}

Giờ đây, bạn đã có một lưới gồm 12 cột, chúng ta có thể đặt các thành phần con trên lưới. Một cách để thực hiện việc này là đặt chúng bằng các đường lưới. Ví dụ: grid-column: 1 / 13 sẽ trải dài từ dòng đầu tiên đến dòng cuối cùng (dòng thứ 13) và trải dài 12 cột. grid-column: 1 / 5; sẽ trải dài trong 4 phần đầu tiên.

Một cách khác để viết mã này là sử dụng từ khoá span. Với span, bạn đặt đường bắt đầu và sau đó đặt số cột cần trải dài từ điểm bắt đầu đó. Trong trường hợp này, grid-column: 1 / span 12 sẽ tương đương với grid-column: 1 / 13grid-column: 2 / span 6 sẽ tương đương với grid-column: 2 / 8.

.child-span-12 {
  grid-column: 1 / span 12;
}

07. RAM (Lặp lại, Tự động, Tối thiểu/Tối đa): grid-template-columns(auto-fit, minmax(<base>, 1fr))

Đối với ví dụ thứ bảy này, hãy kết hợp một số khái niệm mà bạn đã học để tạo một bố cục thích ứng với các phần tử con linh hoạt và được đặt tự động. Khá gọn gàng. Các thuật ngữ chính cần nhớ ở đây là repeat, auto-(fit|fill)minmax()'. Bạn có thể nhớ bằng từ viết tắt RAM.

Tất cả các thông tin này sẽ có dạng như sau:

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

Bạn đang sử dụng lại lệnh lặp lại, nhưng lần này, bạn dùng từ khoá auto-fit thay vì một giá trị số rõ ràng. Thao tác này cho phép tự động đặt các phần tử con này. Các thành phần con này cũng có giá trị tối thiểu cơ bản là 150px với giá trị tối đa là 1fr, nghĩa là trên màn hình nhỏ hơn, chúng sẽ chiếm toàn bộ chiều rộng 1fr và khi đạt đến chiều rộng 150px, chúng sẽ bắt đầu xuất hiện trên cùng một dòng.

Với auto-fit, các hộp sẽ kéo giãn khi kích thước chiều ngang vượt quá 150 px để lấp đầy toàn bộ không gian còn lại. Tuy nhiên, nếu bạn thay đổi giá trị này thành auto-fill, thì các phần tử sẽ không giãn ra khi kích thước cơ sở của chúng trong hàm minmax bị vượt quá:

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}

08. Line Up: justify-content: space-between

Đối với bố cục tiếp theo, điểm chính cần minh hoạ ở đây là justify-content: space-between. Phần tử này đặt phần tử con đầu tiên và cuối cùng ở các cạnh của hộp giới hạn, với khoảng trống còn lại được phân phối đều giữa các phần tử. Đối với những thẻ này, chúng được đặt ở chế độ hiển thị Flexbox, với hướng được đặt thành cột bằng cách sử dụng flex-direction: column.

Thao tác này sẽ đặt tiêu đề, nội dung mô tả và khối hình ảnh vào một cột dọc bên trong thẻ mẹ. Sau đó, việc áp dụng justify-content: space-between sẽ cố định phần tử đầu tiên (tiêu đề) và phần tử cuối cùng (khối hình ảnh) vào các cạnh của flexbox, đồng thời văn bản mô tả ở giữa các phần tử đó sẽ được đặt với khoảng cách bằng nhau cho mỗi điểm cuối.

.parent {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

09. Clamping My Style (Kẹp kiểu của tôi): clamp(<min>, <actual>, <max>)

Đây là nơi chúng ta sẽ tìm hiểu một số kỹ thuật ít được trình duyệt hỗ trợ, nhưng lại có một số tác động thực sự thú vị đối với bố cục và thiết kế giao diện người dùng thích ứng. Trong bản minh hoạ này, bạn đang đặt chiều rộng bằng cách sử dụng clamp như sau: width: clamp(<min>, <actual>, <max>).

Thao tác này sẽ đặt kích thước tối thiểu và tối đa tuyệt đối, cũng như kích thước thực tế. Với các giá trị, thuộc tính đó có thể như sau:

.parent {
  width: clamp(23ch, 60%, 46ch);
}

Kích thước tối thiểu ở đây là 23ch hoặc 23 đơn vị ký tự và kích thước tối đa là 46ch, 46 ký tự. Đơn vị chiều rộng ký tự dựa trên kích thước phông chữ của phần tử (cụ thể là chiều rộng của glyph 0). Kích thước "thực tế" là 50%, tức là 50% chiều rộng của phần tử mẹ này.

Chức năng clamp() ở đây là cho phép phần tử này giữ lại chiều rộng 50% cho đến khi 50% lớn hơn 46ch (trên các khung hiển thị rộng hơn) hoặc nhỏ hơn 23ch (trên các khung hiển thị nhỏ hơn). Bạn có thể thấy rằng khi tôi kéo giãn và thu nhỏ kích thước của thành phần mẹ, chiều rộng của thẻ này sẽ tăng lên điểm tối đa được cố định và giảm xuống điểm tối thiểu được cố định. Sau đó, nút này vẫn nằm ở giữa phần tử mẹ vì chúng ta đã áp dụng các thuộc tính bổ sung để căn giữa nút. Điều này giúp bố cục dễ đọc hơn, vì văn bản sẽ không quá rộng (trên 46ch) hoặc quá hẹp (dưới 23ch).

Đây cũng là một cách hiệu quả để triển khai kiểu chữ thích ứng. Ví dụ: bạn có thể viết: font-size: clamp(1.5rem, 20vw, 3rem). Trong trường hợp này, font-size của tiêu đề sẽ luôn nằm trong khoảng từ 1.5rem đến 3rem nhưng sẽ tăng và giảm dựa trên giá trị thực tế 20vw để phù hợp với chiều rộng của khung nhìn.

Đây là một kỹ thuật tuyệt vời để đảm bảo khả năng đọc với giá trị kích thước tối thiểu và tối đa, nhưng hãy nhớ rằng kỹ thuật này không được hỗ trợ trong tất cả các trình duyệt hiện đại, vì vậy, hãy đảm bảo bạn có các giải pháp dự phòng và tiến hành kiểm thử.

10. Tôn trọng tỷ lệ khung hình: aspect-ratio: <width> / <height>

Cuối cùng, công cụ bố cục cuối cùng này là công cụ thử nghiệm nhất trong số các công cụ. Tính năng này mới được giới thiệu cho Chrome Canary trong Chromium 84 và Firefox đang nỗ lực triển khai tính năng này, nhưng hiện tại tính năng này chưa có trong bất kỳ phiên bản trình duyệt ổn định nào.

Tuy nhiên, tôi vẫn muốn đề cập đến vấn đề này vì đây là vấn đề thường gặp. Và đó chỉ đơn giản là việc duy trì tỷ lệ khung hình của một hình ảnh.

Với thuộc tính aspect-ratio, khi tôi đổi kích thước thẻ, khối hình ảnh màu xanh lục vẫn duy trì tỷ lệ khung hình 16 x 9 này. Chúng tôi đang điều chỉnh tỷ lệ khung hình bằng aspect-ratio: 16 / 9.

.video {
  aspect-ratio: 16 / 9;
}

Để duy trì tỷ lệ khung hình 16 x 9 mà không có thuộc tính này, bạn cần sử dụng một thủ thuật padding-top và cho thuộc tính này một khoảng đệm là 56.25% để đặt tỷ lệ từ trên xuống theo chiều rộng. Chúng tôi sẽ sớm có một thuộc tính cho việc này để tránh bị xâm nhập và không cần tính tỷ lệ phần trăm. Bạn có thể tạo một hình vuông có tỷ lệ 1 / 1, tỷ lệ 2:1 với 2 / 1 và thực sự chỉ cần bất kỳ thứ gì bạn cần để hình ảnh này có thể điều chỉnh tỷ lệ theo tỷ lệ kích thước đã đặt.

.square {
  aspect-ratio: 1 / 1;
}

Mặc dù tính năng này vẫn đang trong quá trình phát triển, nhưng bạn nên biết về tính năng này vì nó giải quyết rất nhiều vấn đề mà nhà phát triển gặp phải, đặc biệt là khi nói đến video và iframe.

Kết luận

Cảm ơn bạn đã theo dõi hành trình này qua 10 dòng CSS mạnh mẽ. Để tìm hiểu thêm, hãy xem toàn bộ video và tự mình dùng thử các bản minh hoạ.