CSS Layout

Summary

  • display - Xác định cách mà các phần tử bên trong sẽ hiển thị.
    • inline - Các phần tử được hiển thị/ show cạnh nhau
    • block - Mỗi phần tử nằm trên 1 dòng (block)
    • flex - Linh hoạt. Nó sẽ hiển thị các phần tử con theo trục. Các elements bên trong sẽ thành flex items, có thể config custom hiển thị. One-dimension layouts
    • grid - Các elements bên trong được bố trí dưới dạng lưới Two-dimension layouts
  • position - Xác định vị trí cụ thể của 1 elements.
    • static - Mặc định, hiển thị theo document flow.
    • relative - Hiển thị ở vị trí tương đối so với vị trí ban đầu. (control qua top, right, left, bottom)
    • absolute - Hiển thị ở vị trí tuyệt đối so với phần tử cha, hoặc viewport.
    • fixed - Hiển thị cố định ở 1 vị trí so với viewport.
    • sticky - Bình thường sẽ hiển thị như relative, nhưng nếu scroll qua thì sẽ hiển thị như fixed.

Layout

Layout: a brief history

A History of CSS Through Fifteen Years of 24 ways ◆ 24 ways

Understanding the display property

  • display property làm 2 việc:
    • Xác định xem box được applied inline hay block

  • Inline elements 🌱
    • Giống như chữ trong 1 câu vậy, các phần tử sẽ đứng cạnh nhau trên 1 dòng. Các elements như spanstrong mặc định là hiển thị inline cùng với text trong thẻ p.
    • Không thể set width và height cho các phần tử inline. Các inline elements sẽ tự mở rộng theo content bên trong nó. Các thuộc tính width, height chỉ hoạt động với các block element như div, p, section, ...
    • Margin và Padding ở cấp độ block sẽ bị bỏ qua với các phần tử inline: Các thuộc tính như margin-top, padding-top, margin-bottom, padding-bottom sẽ bị bỏ qua hết. Chỉ có margin-leftmargin-right, padding-left/right mới có ảnh hưởng tới các phần tử inline. Lý do là vì các phần tử inline chỉ chiếm không gian theo chiều ngang, nên các thuộc tính điều chỉnh khoảng cách theo chiều dọc sẽ không có tác dụng.
    • Nếu muốn thay đổi theo chiều dọc, thử sử dụng display: inline-block :D
  • Block elements 🌱
    • Block elements đứng cạnh nhau. Mỗi element sẽ tự đứng trên 1 dòng.
    • Do đứng trên 1 dòng, nên width của nó thường sẽ chiếm hết 100% width. Margin and padding on all sides of a block element will be respected.
  • Flexbox
    • display: flex - Tạo ra 1 flex container. Các phần tử bên trong đó sẽ thành flex items, được sắp xếp 1 cách linh hoạt, tùy thuộc vào các quy tắc của flexbox.

Flexbox ⭐⭐⭐

  • Flexbox là một kiểu dàn trang (layout mode) mà nó sẽ tự cân đối kích thước của các phần tử bên trong để hiển thị trên mọi thiết bị. Nói theo cách khác, bạn không cần thiết lập kích thước của phần tử, không cần cho nó float, chỉ cần thiết lập nó hiển thị chiều ngang hay chiều dọc, lúc đó các phần tử bên trong có thể hiển thị theo ý muốn.

  • One-dimension layouts. Các items sẽ được đặt cạnh nhau by default (theo chiều dọc hoặc chiều ngang - trục chính hoặc trục phụ)

    • Trục chính (main axis) - mặc định sẽ là theo chiều ngang. Có thể thay đổi bằng thuộc tính flex-direction
    • Trục phụ (cross axis) - Trục vuông góc với trục chính
  • Default thì các items mới sẽ luôn nằm cạnh nhau, trừ khi chúng ta thay đổi các thuộc tính như flex-wrap, align-items hoặc justify-content. Các thuộc tính quan trọng trong flexbox:

    • justify-content: Cách hiển thị các phần tử con. (center, spaced-around, flex-end, … Căn giữa, căn đều hay đẩy về 1 phía)
    • align-items: Điều chỉnh các phần tử con, căn chỉnh theo trục phụ. (vd Căn giữa theo chiều dọc)
    • flex-wrap: Cho phép các phần tử con có thể xuống dòng nếu không đủ chỗ trên một hàng.
  • Flexbox converts child elements thành flex items, do đó, chúng ta có thể set rules cho các phần tử để set cách hiển thị trong flex container: Thay đổi alignment, order, justification on an individual item, also change how it shirks or grows using flex property: .my-element div { flex: 1 0 auto; }

  • flex property viết tắt cho flex-grow, flex-shirkflex-basis

    • flex-grow - Quyết định khả năng giãn nở của phần tử. Nếu trong container có không gian dư thừa, thuộc tính này sẽ qđ phần tử nào giãn ra để lấp đầy khoảng trống đó.
    • flex-shirk - Quyết định khả năng co lại bao nhiêu nếu không gian trong container bị thu hẹp.
    • flex-basis - Xác định kích thước mặc định của phần tử trước khi bị flex-growflex-shirk tác động. Qđ kích thước phần tử nên có trước khi bị co lại/ giãn ra. Nếu không chỉ định width/height thì nó sẽ tự động điều chỉnh theo kích thước nội dung.

Grid

  • Tương tự như flexbox, nhưng được design để control multi-axis layouts thay vì single-axis layouts.

  • Layout styling supported with repeat() and minmax().

  • fr unit - đại diện cho phần không gian sẵn có trong grid container (fraction of remaining space).

    • Sau khi không gian cố định (kích thước được đặt bằng px, %, em, …) được phân bổ, phần còn lại của không gian sẽ được chia theo các giá trị fr mà ta đặt.
    • Ưu điểm: không cần phải tính toán chính xác kích thước cho mỗi cột hoặc hàng.
    • Ví dụ: .container { display: grid; grid-template-columns: 1fr 2fr 1fr; } - Không gian được chia làm 3 cột, cột đầu và cuối chiếm 1 phần không gian sẵn có, cột giữa chiếm 2 phần.
  • Grid cho phép chúng ta control items theo 2 chiều. (Giống như merge cells trong Excel, hoặc như col-span/ row-span trong Bootstrap/ table)

    • grid-row: 1/3 - Chỉ định item này sẽ span row tới hết vị trí của item số 2 (đầu vị trí của item số 3)
    • grid-column: 1/4 - Chỉ định item sẽ span column tới hết vị trí của item số 3 (đầu vị trí của item số 4)

Flow layout

Inline block

  • Respect block margin and padding on an inline element

Float

  • Được sử dụng để đẩy phần tử sang bên trái hoặc phải của container, cho phép các phần tử khá bao quanh nó.

    • Khi Flexbox và CSS Grid chưa ra đời thì thuộc tính này được sử dụng khá phổ biến để tạo bố cục trang web.
  • float: left

  • Sử dụng float có thể ảnh hưởng tới các element có layout riêng. Cân nhắc sử dụng clear: both để clear floated element.

  • Nguyên lý hoạt động:

    • Khi một phần tử được set thuộc tính float, nó sẽ:
      • Bắt đầu ở hàng phía trên, nếu hàng trên còn đủ chỗ trống cho nó.
      • Bắt đầu ở hàng mới, nếu hàng trên không đủ chỗ trống cho nó.
    • Nếu một phần tử được thiết lập thuộc tính float mà trong khi phần tử đứng trước nó không được thiết lập thuộc tính float, thì mặc định nó được bắt đầu ở hàng mới.
    • Khi trên một hàng có nhiều phần tử được thiết lập thuộc tính float và mỗi phần tử có chiều cao khác nhau, nếu hàng không đủ chỗ chứa phần tử thì phần tử sẽ bắt đầu bên cạnh phần tử có chiều cao thấp nhất và còn đủ khoảng trống để chứa nó.

Multicolumn layout

  • Sử dụng khi list dài quá, muốn chia cột cho đỡ phải lăn chuột nhiều.
  • column-count, column-gap, column-width

Positioning

Ở flow thông thường, các phần tử sẽ được hiển thị theo layout. Viết trước hiển thị trước =)) Tuy nhiên, đôi lúc ta muốn các phần tử hiển thị lệch so với vị trí ban đầu, hoặc fixed header khi scroll, … Đó là lúc cần sử dụng position.

  • position dùng để set vị trí của phần tử sẽ nằm ở đâu trên trang web, hoặc phần tử đó tương tác với các phần tử khác trong bố cục.
    • static
      • Mặc định. Phần tử sẽ được định vị theo document fow.
      • Ở giá trị mặc định, các thuộc tính như top, right, bottom, left không có tác dụng.
    • relative - Tương đối
      • Phần tử sẽ ở vị trí tương đối so với vị trí ban đầu.
      • Ta có thể sử dụng thêm top, right, bottom, left để điều chỉnh vị trí của phần tử. Vị trí ban đầu của nó vẫn sẽ được giữ lại.
      • Sử dụng khi ta muốn dịch chuyển phần tử 1 chút so với vị trí gốc.
    • absolute - Tuyệt đối
      • Định vị so với phần tử cha hoặc viewport. Nó không còn trong document flow. (It’s no longer positioned based on its siblings positions.)
      • Phần tử được định vị tuyệt đối so với phần tử chứa gần nhất có thuộc tính position khác với static. Nếu không có phần tử cha nào được định vị, nó sẽ được đặt so với toàn bộ trang.
      • Các thuộc tính top, right, left, bottom sẽ điều khiển vị trí của phần tử.
      • Sử dụng khi ta muốn phần tử không tuân theo document flow, và định vị theo chính xác vị trí bạn chỉ định.
    • fixed - Cố định
      • Element được định vị tương đối so với viewport, ngay cả khi trang scroll.
      • Sử dụng khi muốn phần tử luôn được xuất hiện ở 1 vị trí cố định, ví dụ header hoặc nút Back to Top.
    • sticky
      • Stick vào 1 vị trí cố định khi cuộn đến một ngưỡng nhất định.
      • Element hoạt động như relative cho đến khi bạn cuộn trang tới 1 vị trí nhất định. Khi đó, nó trở nên “dính” vào vị trí đã chỉ định và hoạt động như fixed. Khi cuộn qua ngưỡng, nó lại trở về bình thường.

Notes

  • Sử dụng Grid để bố trí trang web, Float để thêm hình ảnh, Flex để có được yếu tố UI pop up
  • Lưu ý khi build layout:
    • Bắt đầu với nội dung
    • Mobile First
    • Xây dựng bản phác thảo trước (sắp xếp trên giấy các box chẳng hạn)
    • Sử dụng background-image thay cho img có thể tiết kiệm bytes khi tải, mà cũng tránh được 1 số khó khăn khi tạo layout.
    • Chia nhỏ layout

References