Vì sao không dùng margin vs padding css được

Vì sao không dùng margin vs padding css được

Bài viết được tham khảo và viết lại dựa trên bài gốc của tác giả ishadeed

Khi các bạn code giao diện cho một dự án nào đó chẳng hạn, các bạn sẽ thấy rằng để làm khoảng cách giữa các phần tử thì sẽ có nhiều cách như margin hoặc padding hay gọi chung là spacing. Tuy nhiên mình thấy nhiều bạn mới học thì hay bị rối giữa việc dùng 2 thứ này, hôm nay mình lại tiếp tục research tìm nội dung về nó để viết cho các bạn, hi vọng sẽ giúp ích được cho các bạn phần nào trong việc cải thiện kiến thức hơn, thông suốt hơn về spacing để có thể làm chủ việc code tốt hơn.

# Các loại spacing

Như mình đã nói ở trên thì trong CSS có 2 loại spacing đó chính là outer-spaceinner-space mà chúng ta hay gặp. Trong bài viết này mình gọi tạm là outerinner cho dễ hiểu nhé. Ví dụ như hình dưới đây khoảng trống bên ngoài là outer và bên trong là inner.

Vì sao không dùng margin vs padding css được

Ví dụ ở trên có class là element đi thì chúng ta có thể có CSS đơn giản như này với inner là padding và outer là margin. Đơn giản đúng không nào ?

.element { padding: 20px; margin-bottom: 20px; }
Tuy nhiên không chỉ đơn giản như vậy đâu, nó còn nhiều trường hợp khác thú vị lắm, chúng ta sẽ cùng nhau tìm hiểu tiếp dưới đây nhé.

# Margin

Margin thường được sử dụng khi các bạn muốn tạo khoảng cách giữa phần tử này so với các phần tử khác. Như ví dụ ở trên thì mình có dùng margin-bottom: 20px để tạo ra khoảng cách so với phần tử ở dưới.

Chắc các bạn cũng đã biết là margin có thể sử dụng ở 4 hướng (top right bottom left), và chúng ta nên nắm rõ những thứ cơ bản này để có thể áp dụng chúng tốt vào trong dự án thực tế được.

Vấn đề margin collapse

Hiểu đơn giản là margin collapse xảy ra khi chúng ta có 2 phần tử nằm hàng dọc và có margin và một trong số chúng có margin lớn hơn cái còn lại. Trong trường hợp này thằng nào có margin lớn hơn sẽ được sử dụng và thằng còn lại sẽ bị bỏ qua. Các bạn xem hình nhé.

Vì sao không dùng margin vs padding css được

Các bạn thấy phần tử ở trên có margin-bottom: 50px và thằng ở dưới có margin-top: 30px thì khoảng cách lúc này không phải là 80px như các bạn nghĩ đâu mà là 50px do thằng ở trên có margin lớn hơn, và điều đó tạo nên một thứ chính là margin collapse.

Và để giải quyết vấn đề này thì người ta khuyến khích chỉ sử dụng một một hướng mà thôi ví dụ các bạn muốn khoảng cách giữa chúng là 80px thì chỉ cần dùng margin-bottom: 80px là đủ, tuy nhiên nếu code .element {margin-bottom: 80px} thì cái cuối cùng sẽ có khoảng trống dư thừa cho nên để fix cái này chúng ta sẽ dùng :not(:last-child)

.element:not(:last-child) { margin-bottom: 80px; } Một ví dụ khác nữa cũng khá thú vị đó là mối quan hệ giữa phần tử cha và con bên trong. Giả sử ta có HTML và CSS như sau

<div class="parent"> <div class="child">I'm the child element</div> </div>
.parent { margin: 50px auto 0 auto; width: 400px; height: 120px; } .child { margin: 50px 0; }
Vì sao không dùng margin vs padding css được

Hôm nay Green House xin hướng dẫn các bạn 2 thuộc tính cơ bản trong CSS khi lập trình website, đây là 2 thuộc tính được sử dụng nhiều nhất và phổ biến nhất, vì nó sẽ tăng độ hợp lý, đẹp đẽ trong website, đó chính là Padding và Margin. Vậy Padding là gì? Margin là gì? Cách sử dụng padding và margin trong css là gì?

Padding và Margin là hai thuộc tính được sử dụng thường xuyên trong code CSS. Tuy nhiên vẫn còn khá nhiều bạn chưa hiểu rõ và còn nhầm lẫn giữa hai thuộc tính này, vì chúng đều được sử dụng để điều chỉnh không gian giữa các phần tử. Tuy nhiên bài viết này mình sẽ đề cập sau hơn về 2 thuộc tính này.

Các bạn hãy xem hình vẽ sau và mình sẽ giải thích ở dưới

Vì sao không dùng margin vs padding css được
Padding và margin trong modal box

Box Model

Trên trang HTML, các phần tử của trang điều được biểu diễn bởi hình hộp chữ nhật. vì thế thuật ngữ box model được dùng để ám chỉ các phần tử của trang. Nhìn trên hình bạn sẽ thấy có 3 box model là 3 hình chữ nhật

Padding là gì?

Padding hiểu 1 cách đơn giản thì thuộc tính là khoảng trống nằm giữa nội dung và viền. Chúng ta sẽ có 4 khoảng cách giữa nội dung với viền và bên trái, bên phải, phía trên và phía dưới tương ứng là padding-top, padding-left, padding-right và padding-bottom. Chúng ta có thể hiểu đơn giản hơn, là padding chính là khoảng cách giữa thẻ mẹ so với thẻ con.

Cách sử dụng padding trong css:

p { padding: 2px 2px 2px 2px; }

hoặc

p { padding-left: 2px; padding-right: 2px ; padding-top: 2px; padding-bottom: 2px}

Margin là gì?

Margin cũng là khoảng cách, nhưng không phải là khoảng cách giữa thẻ mẹ so với thẻ con, mà là khoảng cách giữa các phần tử con với nhau, và khoảng cách giữa phần tử cùng với viền. Khoảng cách này cũng có 4 thuộc tính là trái phải, trên dưới tương ứng là margin-left, margin-right, margin-top, margin-bottom.

Cách sử dụng margin trong css:

p { margin: 2px 2px 2px 2px; }

hoặc

p { margin-left: 2px; margin-right: 2px ; margin-top: 2px; margin-bottom: 2px}

Hy vọng qua bài viết này, các bạn sẽ hiểu rõ hơn Margin và Padding và cách dùng chúng trong CSS để làm đẹp trang web của các bạn nhé.

Margin trong CSS có vẻ đơn giản ngay từ thời điểm đầu tiên bạn biết nó. Margin áp dụng cho một phần tử, nó tạo thành một khoảng trống xung quanh phần tử đấy, đẩy xa các phần tử khác.


  • Bạn có thể hiểu Margin Lề


Tuy nhiên, Margin có nhiều thứ có thể bạn chưa biết.


Một trong những điều đầu tiên mà hầu hết chúng ta học được khi học CSS, là chi tiết về các phần khác nhau của một hộp trong CSS, được mô tả là CSS Box Model.


Một trong những yếu tố trong Box ModelMargin, đó một vùng trong suốt xung quanh box, nó sẽ đẩy các phần tử khác ra khỏi nó.


Các thuộc tính margin-top, margin-right, margin-bottommargin-left được mô tả lại ngay trong CSS1, cùng với kiểu viết tắt margin để thiết lập cả bốn thuộc tính cùng một lúc.



  • Cú pháp: marign: toprightbottomleft;
  • margin: 10px; tương đương margin: 10px 10px 10px 10px;
  • margin: 10px 20px; tương đương margin: 10px 20px 10px 20px;


Margin mặc dù khá đơn giản nhưng có một số thứ xảy ra có thể khiến bạn khó nắm bắt. Trong bài này chúng ta sẽ cùng tìm hiểu và xử lý chúng khi viết CSS.



Vì sao không dùng margin vs padding css được


Tất tần tật về Margin trong CSS



Cụ thể, chúng ta sẽ xem xét cách các margin tương tác với nhau và cách margin collapsing thực sự hoạt động như thế nào.


CSS Box Model là gì?



Box Model đề cập đến cách các phần khác nhau của hộp như:


  • content (nội dung)
  • padding (phần đệm giữa nội dung và đường viền)
  • border (đường viền)
  • margin (lề)


được trình bày và tương tác với nhau.


Trong CSS1, Box Model được trình bày chi tiết như hình bên dưới:



Vì sao không dùng margin vs padding css được


Mô tả CSS Box Model trong CSS1


Bốn thuộc tính lề cho mỗi bên của box và cách viết tắt của margin đều được xác định trong CSS1.


Trong đặc tả CSS2.1 có hình minh họa để thể hiện Box Model và cũng xác định các thuật ngữ chúng ta vẫn sử dụng để mô tả các box khác nhau.


Thông số kỹ thuật mô tả content box, padding box, border boxmargin box, mỗi box được xác định bởi các cạnh của nội dung, phần đệm, đường viền và lề tương ứng.



Vì sao không dùng margin vs padding css được


Mô tả CSS Box Model trong phiên bản CSS2.1

Hiện tại đã có đặc tả CSS Box Model 3 nhưng đang là bản nháp.


Do đó, chúng ta sẽ sử dụng định nghĩa trong CSS2 cho phần lớn bài viết này.


Margin Collapsing là gì?



Đặc tả CSS1, đã xác định margin, cũng xác định Margin Collapsing.


Margin Collapsing là vấn đề tự động thu gọn lề trong một số trường hợp:



  • Anh chị em liền kề
  • Hộp trống hoàn toàn
  • Phần tử cha mẹ với phần tử con đầu tiên hoặc phần tử con cuối cùng


Chúng ta hãy xem xét từng trường hợp xảy ra Margin collapsing.


Tình huống #1: Tự động thu gọn margin của phần tử anh chị em liền kề



Nếu bạn có hai phần tử hiển thị lần lượt từng phần tử trong luồng bình thường, lề dưới của phần tử bên trên chồng với lề trên của phần tử phía dưới.


Trong ví dụ CodePen dưới đây, chúng ta có ba phần tử div.



  • Div đầu tiên có lề trên (margin-top) và lề dưới (margin-bottom) là 50 pixel.
  • Div thứ hai cólề trên (margin-top) và lề dưới (margin-bottom)là 20px.
  • Div thứ ba cólề trên (margin-top) và lề dưới (margin-bottom)là 3em.


Lề giữa div 1 và div 2 là 50 pixel (chứ không phải 70px). Vì lề trên của div thứ hai nhỏ hơn nên nó được kết hợp với lề dưới của div đầu tiên.


Lề giữa div thứ 2 và div thứ 3 là 3em, vì 3em lớn hơn 20px (margin-bottom của div thứ hai)




See the Pen VD1: Margin Collapsing by NIIT -ICT Hà Nội (@niiticthanoi) on CodePen.



Tình huống #2: Tự động thu gọn Margin của hộp trống hoàn toàn



Nếu một hộp trống, thì lề trên và lề dưới của nó có thể bị thu gọn.


Trong ví dụ CodePen sau đây, phần tử có class empty có lề trên và lề dưới là 50 pixel. Còn 2 phần tử có class là boxthì không thiết lập margin.


Tuy nhiên, khoảng cách thực tế giữa các 2 phần tử thứ nhất và thứ ba không phải là 100px, mà là 50px.


Điều này là do hai lề bị thu gọn lại.


Nếu bạn thêm bất cứ thứ gì vào box đó (thậm chí là thêm padding) sẽ khiến cho lề trên và lề dưới được sử dụng và không bị thu gọn.



See the Pen VD2: Lề chồng lấn trong phần tử trống by NIIT -ICT Hà Nội (@niiticthanoi) on CodePen.



Tình huống #3: Margin thu gọn giữa phần tử cha mẹ và phần tử con đầu tiên hoặc phần tử con cuối cùng



Đây là tình huống lề bị thu gọn thường xuyên gặp phải nhất, là nó không dễ thấy bằng mắt thường.


Trong ví dụ CodePen sau, mình có một div với một class wrapper, và mình đã cho rằng div đó một outlinemàu đỏ để bạn có thể thấy nó ở đâu.


Mình thiết lập cho ba phần tử con của wrapperđều có một margin: 50px;


Tuy nhiên, phần tử con đầu tiên (first child) và phần tử con cuối cùng (last child) thực tế lại không có lề cách 50px với phần tử wrapper.



See the Pen VD3: Lề chồng lấn với phần tử cha và phần tử con đầu tiên, cuối cùng by NIIT -ICT Hà Nội (@niiticthanoi) on CodePen.



Điều này là do lề của phần tử con bị thu gọn với bất kỳ lề nào trên phần tử cha.


Do đó lề nằm ở bên ngoài của phần tử cha (Lề này sẽ đẩy ra khoảng cách với phần tử nằm trên / dưới phần tử cha wrapper)


Bạn có thể thấy rõ nếu bạn kiểm tra phần tử đầu tiên bằng DevTools. Vùng màu vàng nổi bật chính là lề.



Vì sao không dùng margin vs padding css được


Kiểm tra lề (margin) bằng DevTools



Tình huống thứ 3 này cũng nêu bật ý nghĩa của Margin Collapsing.


Trong CSS2, chỉ các lề dọc được chỉ định để thu gọn - đó là lề trên và dưới trên một phần tử nếu bạn ở chế độ viết ngang.


Vì vậy, lề trái và phải của cả 3 phần tử ở trên không bị thu gọn và cách wrapperđúng bằng 50px.



Những thứ ngăn chặn Margin Collapsing



Margin không bao giờ thu gọn nếu một phần tử có vị trí tuyệt đối (position: absolute;), hoặc được float.


Tuy nhiên, giả sử bạn không muốn việc thu gọn xảy ra. Vậy làm cách nào để ngăn chặn nó?


Điều đầu tiên ngăn chặn margin collapsing là có một cái gì đó giữa chúng.


Ví dụ: Một hộp hoàn toàn trống sẽ không thu bị thu gọn lề trên và lề dưới của nó nếu nó được thiết lập đường viền (border) hoặc phần đệm (padding).


Trong ví dụ dưới đây, mình đã thêm padding: 1px; vào phần tử trống có class là empty. Hiện tại nó có một lề 50 pixel ở trên và 50px ở dưới.



See the Pen VD1: Ngăn chặn Margin collapsing by NIIT -ICT Hà Nội (@niiticthanoi) on CodePen.




Điều này có logic phía sau nó, nếu hộp là hoàn toàn trống rỗng không có đường viền (border) hay phần đệm (padding) thì bản chất của nó là vô hình.


Đây là một phần tử không có tác dụng gì.


Nếu bạn không muốn đều này xảy ra. Hãy thêm bất cứ cái gì vào phần tử trống này.


Hành vi tương tự có thể xảy ra trong tình huống thứ #3.


Nếu chúng ta thêm một đường viền (border) cho phần tử cha, margin của phần tử con sẽ nằm ở bên trong, như ví dụ codepen dưới đây:



See the Pen VD2: Ngăn chặn Margin Collapsing by NIIT -ICT Hà Nội (@niiticthanoi) on CodePen.



Một lần nữa, đây là một hành vi logic.


Nếu bạn có phần tử wrapper nhưng thiết lập nó trống, có thể bạn không muốn có thêm khoảng trống trên màn hình hiển thị.


Điều này rất có ý nghĩa khi trang web của bạn chủ yếu là văn bản.


Nó ít hữu ích như hành vi khi chúng ta đang sử dụng các phần tử để bố trí một thiết kế.



Định nghĩa bối cảnh cho một khối để ngăn chặn Margin Collapsing



Định nghĩa bối cảnh cho một khối (Block Formatting Context (BFC)) cũng sẽ ngăn chặn lề tự động thu gọn.


Nếu chúng ta nhìn lại tình huống thứ #3:



Phần tử con đầu tiên và phần tử con cuối cùng kết thúc với lề của chúng nằm ở bên ngoài phần tử cha.

Nếu chúng ta thiết lập cho phần tử cha display: flow-root; để tạo ra bối cảnh cho khối này, các lề sẽ nằm ở bên trong.



See the Pen Định nghĩa bối cảnh cho block để ngăn chặn Margin collapsing by NIIT -ICT Hà Nội (@niiticthanoi) on CodePen.




Thiết lập overflow: auto;thì cũng nhận được hiệu quả tương tự, mặc dù nó cũng có thể tạo ra scrollbars mà có thể bạn không muốn.


FLEX và GRID containers



Flex và Grid containers thiết lập định dạng ngữ cảnh Flex và Grid cho phần tử con của chúng, vì thế, chúng có hành vi khác nhau để bố trí khối.


Một trong những sự khác biệt là vấn đề lề thu gọn sẽ không xảy ra.



Một flex container thiết lập một bối cảnh định dạng flex mới cho nội dung của nó. Điều này giống như việc thiết lập bối cảnh định dạng block, ngoại trừ việc bố trí flex được sử dụng thay vì bố trí block.

Ví dụ, float không xâm nhập vào flex container và lề của flex container không bị thu gọn với lề nội dung của nó.

Flexbox Level1




Nếu chúng ta lấy ví dụ ở trên và thiết lập wrapper thành một flex container (display: flex;), hiển thị các item với kiểuflex-direction: column; bạn có thể thấy rằng các lề hiện được chứa bởi wrapper.


Ngoài ra, lề giữa các flex item liền kề không bị thu gọn với nhau, vì vậy giữa cácitemchúng cách nhau 100px.


Đó là tổng 50pxtop và 50pxbottom của các item.



See the Pen Lề của Flex item không bị thu gọn by NIIT -ICT Hà Nội (@niiticthanoi) on CodePen.



Chiến lược thiết lập Margin cho website của bạn



Do lề bị thu gọn, nên cần có một ý tưởng tốt để đưa ra một cách xử lý nhất quán với lề trong trang web của bạn.


Điều đơn giản nhất để làm là chỉ xác định lề trên (margin-top) hoặc lề dưới (margin-bottom) của các phần tử.


Theo cách đó, bạn không nên chạy vào các vấn đề sụp đổ lề quá thường xuyên vì bên có lề sẽ luôn liền kề với một bên mà không có lề.




Giải pháp này không giải quyết được các vấn đề mà bạn có thể gặp phải với vấn đề thu gọn lề của phần tử con trong phần tử cha.


Vấn đề cụ thể đó có xu hướng ít phổ biến hơn, và hiểu tại sao vấn đề này xảy ra giúp bạn đưa ra giải pháp cụ thể.


Một giải pháp lý tưởng cho điều đó là thiết lập cho phần tử đódisplay: flow-root;


Trong các trình duyệt cũ hơn thì bạn có thể dùng overflow: auto;


Hoặc biến phần tử cha của nó thành một flex hoặc grid container.


Thậm chí có thể thêm padding để ngăn chặn vấn đề tự động thu gọn lề này.


Đừng quên rằng bạn có thể sử dụng caniuseđể biết rõ
display: flow-root;được hỗ trợ chính xác trên các phiên bản trình duyệt nào.


Hầu hết thời gian, hãy hiểu tại sao Margin Collapsing quan trọng và không quan trọng.


Sau đó, bạn có thể tìm ra từng trường hợp và làm thế nào để đối phó với nó.


Dù bạn lựa chọn phương pháp gì, hãy luôn chia sẻ thông tin với team của mình.


Vì vấn đề Margin collapsing thường không rõ ràng, vì thế, phương pháp bạn sử dụng để ngăn chặn nó cũng không rõ ràng.


Lúc này, nên có một comment tại đó để giúp team của bạn hiểu bạn đang làm gì.





Và thêm một điều nữa đề làm bài viết này trọn vẹn hơn.


Sử dụng Tỷ lệ phần trăm cho Margin



Khi bạn sử dụng tỷ lệ phần trăm trong CSS, nó phải là tỷ lệ phần trăm của một cái gì đó.


Các margin (và padding) được đặt bằng tỷ lệ phần trăm sẽ luôn là tỷ lệ phần trăm của kích thước nội tuyến (chiều rộng ở chế độ viết ngang) của phần tử cha mẹ.


Hãy xem ví dụ bên dưới đây:



See the Pen Sử dụng tỷ lệ phần trăm cho Margin by NIIT -ICT Hà Nội (@niiticthanoi) on CodePen.



Trong ví dụ CodePen ở trên, mình có một wrapper rộng 200px, bên trong là một box có margin: 10%;, có nghĩa là lề bằng 20px ở tất cả các mặt, nó chiếm 10% của 200px.


Xem xét Margin theo dòng chảy thực tế



Chúng ta đã nói về lề dọc (vertical margin) trong suốt bài viết này, tuy nhiên, CSS hiện đại có xu hướng suy nghĩ về mọi thứ theo một dòng chảy hơn là một theo cách vật lý.


Do đó, khi chúng ta nói về lề dọc, chúng ta thực sự đang nói về lề trong kích thước khối.


Các lề đó sẽ ở trên và dưới nếu chúng ta ở chế độ viết ngang (horizontal writing mode), nhưng sẽ ở bên phải và bên trái trong chế độ viết dọc (vertical writing mode) được viết từ trái sang phải.


Khi làm việc với logic, hãy đi theo dòng chảy tương đối, bất kể việc chế độ viết là gì, việc nói về block startblock end sẽ dễ dàng hơn, thay vì topbottom.



Đối với chúng ta hay đọc từ trái qua phải thì chế độ viết ngang như là mặc định.

Nhưng đối với các nền văn hóa khác nhau họ đọc từ phải qua trái và viết từ trên xuống dưới...

Chính vì thế, xem xét trong dòng chảy sẽ mang tính tổng quát hơn là trên / dưới / trái / phải.



Để hiểu rõ điều này hơn CSS đã giới thiệu đặc tả logic và các giá trị logic. Nó sẽ giúp bạn hiểu hơn về dòng chảy trong CSS.


Đối với margin, điều này giúp chúng ta ánh xạ thuộc tính như sau:



  • margin-top=margin-block-start
  • margin-right=margin-inline-end
  • margin-bottom=margin-block-end
  • margin-left=margin-inline-start


Chúng ta cũng có 2 cách viết tắt sau:

  • margin-block
  • margin-inline


Trong ví dụ CodePen tiếp theo, mình đã sử dụng các thay đổi chế độ viết, bạn có thể thấy cách các lề chạy theo hướng văn bản thay vì được gắn hướng vật lý top / right / bottom / left


See the Pen Margin theo dòng chảy thực tế by NIIT -ICT Hà Nội (@niiticthanoi) on CodePen.



Bạn có thể đọc thêm về CSS Logical Properties and Value trênMDN


Bạn đã hiểu hơn về Margin trong CSS chưa?



Như vậy chúng ta đã cùng nhau đi tìm hiểu tất cả về Margin trong CSS:


  • Bạn đã hiểu Margin Collapsing là gì. Hiểu tại sao nó xảy ra, tại sao nó không xảy ra sẽ giúp bạn bố trí layout tốt hơn.
  • Thiết lập margin theo một cách duy nhất giúp bạn đỡ đau đầu hơn.
  • Với bất cứ những gì bạn xử lý margin, hãy để lại comment cho đồng đội của mình (hoặc cho chính mình).
  • Suy nghĩ về dòng chảy thực tếchứ không phải là kích thước vật lý (top / right / bottom / left) giúp bạn viết web logic hơn.


CSS chỉ là một phần của trang web. Nếu bạn muốn nắm rõ hơn về CSS cũng như lập trình web. KHÓA HỌC PHP FULL STACKnày sẽ giúp bạn hoàn thiện cả Front end và Back end.


Hãy hành động ngay!



---

HỌC VIỆN ĐÀO TẠO CNTT NIIT - ICT HÀ NỘI

Học Lập trình chất lượng cao (Since 2002). Học làm Lập trình viên. Hành động ngay!

Đc: Tầng 3, 25T2, N05, Nguyễn Thị Thập, Cầu Giấy, Hà Nội

SĐT: 02435574074 - 0914939543

Email:

Website:https://niithanoi.edu.vn

Fanpage: https://facebook.com/NIIT.ICT/

#niit #niithanoi #niiticthanoi #hoclaptrinh #khoahoclaptrinh #hoclaptrinhjava #hoclaptrinhphp #php