Trung tâm và các yếu tố flexbox canh lề phải


146

Tôi muốn có A BCliên kết ở giữa.

Làm thế nào tôi có Dthể đi hoàn toàn sang phải?

TRƯỚC:

nhập mô tả hình ảnh ở đây

SAU:

nhập mô tả hình ảnh ở đây

ul {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
li:last-child {
  background: #ddd;
  /* magic to throw to the right*/
}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>

https://jsfiddle.net/z44p7bsx/

Câu trả lời:


212

Dưới đây là năm tùy chọn để đạt được bố cục này:

  • Định vị CSS
  • Flexbox với phần tử DOM vô hình
  • Flexbox với phần tử giả vô hình
  • Flexbox với flex: 1
  • Bố cục lưới CSS

Phương pháp # 1: Thuộc tính định vị CSS

Áp dụng position: relativecho container flex.

Áp dụng position: absolutecho mục D.

Bây giờ mặt hàng này được định vị tuyệt đối trong container flex.

Cụ thể hơn, mục D được xóa khỏi luồng tài liệu nhưng nằm trong giới hạn của tổ tiên định vị gần nhất .

Sử dụng các thuộc tính bù CSS toprightđể di chuyển phần tử này vào vị trí.

Một lưu ý cho phương pháp này là một số trình duyệt có thể không loại bỏ hoàn toàn một mục flex được định vị tuyệt đối khỏi luồng thông thường. Điều này thay đổi sự liên kết theo cách không chuẩn, bất ngờ. Thêm chi tiết: Mục flex được định vị tuyệt đối không bị xóa khỏi luồng bình thường trong IE11


Phương pháp # 2: Lề tự động Flex & Mục Flex vô hình (phần tử DOM)

Với sự kết hợp giữa các autolề và một mục flex mới, vô hình, bố cục có thể đạt được.

Mục flex mới giống hệt với mục D và được đặt ở đầu đối diện (cạnh trái).

Cụ thể hơn, vì căn chỉnh flex dựa trên sự phân bố không gian trống, vật phẩm mới là một đối trọng cần thiết để giữ ba hộp ở giữa được đặt ở giữa. Mục mới phải có cùng chiều rộng với mục D hiện có hoặc các hộp ở giữa sẽ không được căn giữa chính xác.

Các mục mới được loại bỏ khỏi xem với visibility: hidden.

Nói ngắn gọn:

  • Tạo một bản sao của Dphần tử.
  • Đặt nó ở đầu danh sách.
  • Sử dụng flex autolề để giữ A, BClàm trung tâm, với cả hai Dyếu tố tạo ra sự cân bằng bằng từ cả hai đầu.
  • Áp dụng visibility: hiddencho bản saoD


Phương pháp # 3: Lợi nhuận tự động Flex & Mục Flex vô hình (phần tử giả)

Phương pháp này tương tự như # 2, ngoại trừ nó sạch hơn về mặt ngữ nghĩa và độ rộng của Dphải được biết.

  • Tạo một phần tử giả có cùng chiều rộng với D.
  • Đặt nó ở đầu container với ::before.
  • Sử dụng flex autolề để giữ A, BCmột cách hoàn hảo làm trung tâm, với giả và Dcác yếu tố tạo ra sự cân bằng bằng từ cả hai đầu.


Phương pháp # 4: Thêm vào các flex: 1mục trái và phải

Bắt đầu với Phương pháp # 2 hoặc # 3 ở trên, thay vì lo lắng về chiều rộng bằng nhau cho các mục bên trái và bên phải để duy trì sự cân bằng như nhau, chỉ cần cung cấp cho mỗi mục flex: 1. Điều này sẽ buộc cả hai phải tiêu thụ không gian có sẵn, do đó tập trung vào mục giữa.

Sau đó, bạn có thể thêm display: flexvào các mục riêng lẻ để căn chỉnh nội dung của chúng.

LƯU Ý về việc sử dụng phương pháp này với min-height: Hiện tại trong Chrome, Firefox, Edge và có thể các trình duyệt khác, quy tắc tốc ký đượcflex: 1chia thành:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0%

Đơn vị phần trăm đó (%) trên flex-basiskhiến phương thức này bị hỏng khi min-heightđược sử dụng trên container. Điều này là do, theo nguyên tắc chung, tỷ lệ phần trăm chiều cao ở trẻ em yêu cầu heightcài đặt thuộc tính rõ ràng trên cha mẹ.

Đây là một quy tắc CSS cũ có từ năm 1998 ( CSS Cấp 2 ) vẫn còn hiệu lực trong nhiều trình duyệt ở mức độ này hay mức độ khác. Để biết chi tiết đầy đủ xem tại đâyở đây .

Dưới đây là một minh họa về vấn đề được đăng trong các bình luận của user2651804 :

Giải pháp là không sử dụng đơn vị tỷ lệ phần trăm. Hãy thử pxhoặc hoàn toàn không có gì ( đó là những gì thông số kỹ thuật thực sự khuyến nghị , mặc dù thực tế là ít nhất một số trình duyệt chính đã gắn thêm một đơn vị tỷ lệ cho bất kỳ lý do gì).


Phương pháp # 5: Bố cục lưới CSS

Đây có thể là phương pháp sạch nhất và hiệu quả nhất. Không cần định vị tuyệt đối, các yếu tố giả mạo hoặc các tin tặc khác.

Đơn giản chỉ cần tạo một lưới với nhiều cột. Sau đó định vị các mục của bạn trong cột giữa và cuối. Về cơ bản, chỉ để trống cột đầu tiên.

ul {
  display: grid;
  grid-template-columns: 1fr repeat(3, auto) 1fr;
  grid-column-gap: 5px;
  justify-items: center;
}

li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }

/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p  { text-align: center; }
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
<p><span>| true center |</span></p>


1
Rất đẹp, cảm ơn đã giải thích! Tôi đoán các đoạn mã mới được thêm sẽ có lợi từ việc rút ngắn văn bản mẫu vì nó không thực sự rõ ràng từ đầu ra mà nội dung được căn giữa / không được căn giữa do chế độ xem nhỏ. Chỉ có tôi?
dùng2651804

"Mục mới phải có cùng chiều rộng với mục D hiện có hoặc các hộp ở giữa sẽ không được căn giữa chính xác." - thật tệ khi nó phải có cùng chiều rộng, nhưng cảm ơn chúa vì lưới CSS :)
Vucko

Sử dụng kỹ thuật Grid, các vật phẩm không nằm trong trung tâm chết, có cách nào để làm cho phần tử logo bị chết ở trung tâm không? imgur.com/a/SVg9xsj
J86

Không đủ quen thuộc với giải pháp lưới mặc dù nó hoạt động như một bùa mê và là sạch nhất. Một câu hỏi tôi có là làm thế nào để cung cấp thêm không gian cho cột giữa không bằng cả ba?
Saba Ahang

5

Cách dễ nhất

.box{
  display:flex;
  justify-content:center;
}
.item1{
   flex:1;
   display: flex;
   justify-content: center;
   transform: translateX(10px);/*D element Width[if needed]*/
}
 <div class="box">
   <div class="item1">
      <div>A</div>
      <div>B</div>
      <div>C</div>
   </div>
   <div class="item2">D</div>
 </div>


2

Nếu bạn muốn làm cho nó được căn chỉnh, bạn chỉ cần gắn một khoảng trống và chia ba nhịp con thành chúng.


2
bạn có thể cung cấp một bản demo ngắn để sao lưu tuyên bố của mình không?
klewis

2

Giải pháp đơn giản nhất sẽ là trung tâm nội dung biện minh cho vùng chứa chính và cung cấp tự động lề trái cho phần tử con đầu tiên và cuối cùng.

ul {
  display:flex;
  justify-content:center;
}


.a,.d {
  margin-left:auto;
}
<ul>
  <li class="a">A</li>
  <li>B</li>
  <li>C</li>
  <li class="d">D</li>
</ul>


1

Sử dụng display:gridphương pháp này, bạn có thể chỉ cần đặt tất cả ultrẻ em vào cùng một ô và sau đó đặt justify-self:

ul {
  display: grid;
}

ul > * {
  grid-column-start: 1;
  grid-row-start: 1;
  justify-self:center;
}

ul > *:last-child {
  justify-self: right;
}

/* Make Fancy */
li {
  display:inline-block;
  margin: 1px;
  padding: 5px;
  background: #bbb;
}
<ul>
  <span>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  </span>
  <li>D</li>
</ul>


0

Câu hỏi rất rõ ràng. Tôi không thể không đăng câu trả lời sau vài giờ đào. Chúng tôi có thể giải quyết điều này bằng các bảng, ô bảng, vị trí tuyệt đối, biến đổi nhưng chúng tôi chỉ phải làm điều đó với flexbox :)

.parent {
  display: flex;
  justify-content: flex-end;
}

.center {
  margin: auto;
}

http://codepen.io/rgfx/pen/BLorgd


8
Điều này không thực sự tập trung vào các mục ở giữa vì nó chỉ là yếu tố trong không gian còn lại , không phải toàn bộ không gian. codepen.io/anon/pen/QKGrRk
Michael Benjamin

@Michael_B, quyền của bạn đã không nhận thấy điều đó, xấu của tôi. Quay lại sử dụng các vị trí tuyệt đối :( Có thể với đại diện cao của bạn, bạn nên đặt tiền thưởng để giải quyết vấn đề này. Tôi sẽ có một đại diện rất thấp, thậm chí còn thấp hơn khi cố gắng giúp bạn.
rgfx

Không có tiền thưởng sẽ thêm một hành vi mới vào mô hình flexbox, bởi Michael_B, câu trả lời được đưa ra là tốt như nó có được ... ngày hôm nay.
Ason

0

Tôi đã mở rộng câu trả lời của Michael_B

.center-flex__2-of-3 > :nth-child(1), .center-flex__2-of-3 > :nth-child(3) {
  flex: 1;
}
.center-flex__2-of-3 > :nth-child(1) {
  justify-content: flex-start;
}
.center-flex__2-of-3 > :nth-child(3) {
  justify-content: flex-end;
}
.center-flex__1-of-2 > :nth-child(1) {
  margin: auto;
}
.center-flex__1-of-2 > :nth-child(2) {
  flex: 1;
  justify-content: flex-end;
}
.center-flex__2-of-2 > :nth-child(1) {
  flex: 1;
  justify-content: flex-start;
}
.center-flex__2-of-2 > :nth-child(2) {
  margin: auto;
}
.center-flex__1-of-2:before, .center-flex__1-of-1:before {
  content: '';
  flex: 1;
}
.center-flex__1-of-1:after, .center-flex__2-of-2:after {
  content: '';
  flex: 1;
}

[class*=center-flex] {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  border: 10px solid rgba(0, 0, 0, 0.1);
}
[class*=center-flex] > * {
  display: flex;
}
li {
  padding: 3px 5px;
}
2 of 3
<ul class="center-flex__2-of-3">
  <span>
    <li>Accusamus</li>
    <li>Porro</li>
  </span>
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
</ul>

<br><br>
1 of 2
<ul class="akex center-flex__1-of-2">
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
</ul>

<br><br>
2 of 2
<ul class="akex center-flex__2-of-2">
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
</ul>

<br><br>
1 of 1
<ul class="center-flex__1-of-1">
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
</ul>

Ở đây với sự giúp đỡ của SASS như một codepen


0

Lấy cảm hứng từ Phương pháp # 5: CSS Lưới Layout của @Michal Benjamin giải pháp 's và vì tôi đang sử dụng tailwind và tính đến nay vẫn không có quyền truy cập vào tất cả các tùy chọn lưới theo mặc định. Điều này dường như làm việc:

ul {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
li:nth-child(1) { justify-content: flex-start; } // OR: margin-right: auto
li:nth-child(3) { justify-content: flex-end; } // OR: margin-left:auto
li: {align-self: center;}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>

PS: Không chắc chắn nếu trộn lẫn flex và lưới như thế này là một ý tưởng tốt!


1
bạn không trộn lưới và flex, nội dung chính đáng là thuộc tính lưới CSS và thuộc tính flexbox (tương tự cho tự chỉnh)
Temani Afif

-1

Câu trả lời được chấp nhận có thể được thay đổi một chút vì bạn có thể sử dụng các vùng mẫu lưới và thực hiện nó mà không có phần tử giả

grid-template-areas '. b c'
grid-template-columns: 1fr 1fr 1fr

-1
ul { 
  padding: 0; 
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
li:last-child {
  background: #ddd;
  position:absolute;
  right:10px;

}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.