Chiến đấu với khoảng trắng giữa các phần tử inline block

Bài viết được dịch từ Fighting the Space Between Inline Block Elements của tác giả Chris Coyier.

Tôi đã thấy vấn đề này được đưa ra một vài lần gần đây trên Twitter và sau đó là một Dabblet thú vị nên tôi cho rằng vấn đề này sẽ là một thứ đáng để ghi chép lại.

Vấn đề đó là: một dãy các phần tử inline-block được định dạng khi bạn định dạng HTML bình thường sẽ có khoảng trắng giữa chúng.

Nói cách khác:

<nav>
  <a href="#">One</a>
  <a href="#">Two</a>
  <a href="#">Three</a>
</nav>
nav a {
  display: inline-block;
  padding: 5px;
  background: red;
}

sẽ sinh ra kết quả:

alt

Chúng ta thường muốn các phần tử chạm vào nhau. Ở trường hợp thanh điều hướng, chúng ta muốn tránh các khoảng cách khó chịu không nhấn vào được.

Thứ này không phải là "lỗi" (tôi không nghĩ là lỗi). Đó là cách hoạt động của việc sắp xếp các phần tử trên cùng một dòng. Bạn muốn có khoảng trắng giữa các từ mà bạn viết ra đúng không? Khoảng trắng giữa các khối này cũng như khoảng trắng giữa các từ. Điều đó không có nghĩa là đặc tả không thể được cập nhật để không có khoảng trắng giữa các khối inline-block, nhưng công bằng mà nói thì tôi chắc rắng điều đó sẽ không xảy ra.

Dưới đây là một số cách để chiến đấu lại với khoảng trống và làm các khối inline-block nối liền với nhau.

Loại bỏ các dấu cách

Lí do bạn gặp những khoảng trắng vì, chà, bạn có các dấu cách giữa các phần tử (một dấu ngắt dòng và một vài dấu tab được coi là các dấu cách). Tối thiểu hóa HTML sẽ giải quyết vấn đề, hoặc sử dụng một vài cách sau:

<ul>
  <li>
   one</li><li>
   two</li><li>
   three</li>
</ul>

hoặc

<ul>
  <li>one</li
  ><li>two</li
  ><li>three</li>
</ul>

hoặc dùng comment...

<ul>
  <li>one</li><!--
  --><li>two</li><!--
  --><li>three</li>
</ul>

Mấy cách này trông rất là tệ, nhưng giải quyết được vấn đề.

Margin âm

Bạn có thể đưa các phần tử về chỗ mình muốn bằng cách đặt margin âm 4px (có thể cần chỉnh lại dựa trên cỡ font của phần tử cha). Rõ ràng đây là một vấn đề trên IE phiên bản cũ (6 & 7), nhưng nếu bạn không quan tâm tới các trình duyệt đó ít nhất bạn có thể giữ cho định dạng code được rõ ràng:

nav a {
  display: inline-block;
  margin-right: -4px;
}

Bỏ các thẻ đóng

HTML5 chẳng quan tâm. Dù bạn phải thừa nhận rằng, trông nó khá là dị

<ul>
  <li>one
  <li>two
  <li>three
</ul>

Đặt font size bằng 0

Khoảng trắng có font size bằng 0 thì sẽ có ... độ rộng bằng 0

nav {
  font-size: 0;
}
nav a {
  font-size: 16px;
}

Matt Stow báo rằng cách đặt font-size: 0; gặp một vài vấn đề trên Android. Trích dẫn: "Phiên bản trước Jellybean không loại bỏ dấu cách gì cả, và Jellybean có một lỗi mà phần tử cuối có một chút khoảng trắng một cách ngẫu nhiên." Xem kết quả tìm hiểu.

Cũng chú ý rằng, nếu bạn đặt font size theo đơn vị em, font size bằng 0 có thể phát sinh vấn đề, do các phần tử con cũng sẽ có font size bằng 0. Rem có thể giúp trong trường hợp này, nếu không có thể dùng các non-cascading font-size khác.

Một sự kỳ lạ khác! Doug Stewart chỉ cho tôi thấy rằng nếu dùng @font-face với cách này, font sẽ bị mất khử răng cưa trên Safari 5.0.x (testcase) (ảnh chụp).

Dùng float thay vì inline-block

Có thể chúng chẳng cần inline-block gì hết, có thể chúng chỉ cần được float bằng cách này hay cách khác. Điều đó cho phép bạn đặt width, height, padding và các thứ khác. Bạn chỉ không thể căn giữa chúng như khi bạn dùng text-align: center; trên phần tử cha của các phần tử được inline-block. Chà, bạn có thể nhưng trông nó kỳ quặc.

Dùng flexbox thay vì inline-block

Nếu danh sách các trình duyệt hỗ trợ chấp nhận được đối với bạn và những gì bạn cần ngoài việc inline-block là căn giữa, bạn có thể dùng flexbox. Chúng có thể không hoàn toàn thay thế cho nhau, nhưng bạn có thể có được hiệu ứng bạn cần.