Làm thế nào để phân phối đều các phần tử trong một div bên cạnh nhau?


82

Điều này có nghĩa là cho một menu.
Ví dụ, tôi có một phần tử div với 3 nhịp trong đó, tất cả đều có một số lề, chiều rộng tối đa và số nổi (trái hoặc phải).
Nó được định vị bắt đầu từ phía bên trái và như thế này:
[[span1][span2][span3] - lots of free space here].
Tôi muốn làm cho nó giống như thế này:
[[span1] - space - [span2] - space - [span3]]
Làm cách nào để làm điều này bằng cách sử dụng CSS? Tôi hơi nghi ngờ điều đó là không thể.
Lưu ý rằng tôi muốn nó giữ nguyên kiểu khi tôi thêm hoặc xóa một mục menu.
HTML:

<div id="menu">
    <span class="menuitem"></span>
    <span class="menuitem"></span>
    <span class="menuitem"></span>
</div>

CSS:

#menu {
    ...
    width:800px;
}
.menuitem {
    display:block;
    float:left;
    margin-left:25px;
    position:relative;
    min-height:35px;
    max-width:125px;
    padding-bottom:10px;
    text-align:center;
}

1
<span>không được chặn phần tử, nó không nên chấp nhận widthbất động sản
Marek Sebera

Bạn có thể cung cấp mã thực tế?
Blazemonger

Câu trả lời:


93

Trong 'ngày xưa', bạn sẽ sử dụng một bảng và các mục menu của bạn sẽ được cách đều nhau mà không cần phải trình bày rõ ràng chiều rộng cho số lượng mục.

Nếu đó không phải là IE 6 và 7 (nếu điều đó đáng lo ngại) thì bạn có thể làm tương tự trong CSS.

<div class="demo">
    <span>Span 1</span>
    <span>Span 2</span>
    <span>Span 3</span>
</div>

CSS:

div.demo {
    display: table;
    width: 100%;
    table-layout: fixed;    /* For cells of equal size */
}
div.demo span {
    display: table-cell;
    text-align: center;
}

Mà không cần phải điều chỉnh cho số lượng mặt hàng.

Ví dụ không có table-layout:fixed- các ô được phân bố đều trên toàn bộ chiều rộng, nhưng chúng không nhất thiết phải có kích thước bằng nhau vì chiều rộng của chúng được xác định bởi nội dung của chúng.

Ví dụ với table-layout:fixed- các ô có kích thước bằng nhau, bất kể nội dung của chúng. (Cảm ơn @DavidHerse trong nhận xét cho phần bổ sung này.)

Nếu bạn muốn các phần tử menu đầu tiên và cuối cùng được căn đều trái và phải, thì bạn có thể thêm CSS sau:

div.demo span:first-child {
    text-align: left;
}
div.demo span:last-child {
    text-align: right;
}

3
Với phương pháp này, các ô không được phân bố đều. Xem jsfiddle.net/hcrzx . Ô giữa dài hơn hai ô còn lại.
Susam Pal

1
@Susam: Đúng, các ô không nhất thiết phải có kích thước bằng nhau , vì chiều rộng của ô được xác định bởi nội dung của nó (giống như với bảng HTML). Tuy nhiên, tôi vẫn muốn nói rằng chúng có thể được mô tả là phân bố đồng đều , vì chúng được phân phối đồng đều (không nhất thiết phải bằng nhau) trên toàn bộ chiều rộng của phần tử mẹ, dựa trên nội dung của chúng. Nếu bạn muốn các ô có kích thước bằng nhau, bất kể nội dung của chúng là gì, thì tôi cá rằng bạn cần một giải pháp theo tập lệnh.
MrWhite

50

Bạn có thể sử dụng justify.

Điều này tương tự với các câu trả lời khác, ngoại trừ việc các phần tử ngoài cùng bên trái và bên phải sẽ nằm ở các cạnh thay vì cách đều nhau - [a ... b ... c thay vì .a..b..c.]

<div class="menu">
    <span>1</span>
    <span>2</span>
    <span>3</span>
</div>

<style>
.menu {text-align:justify;}
.menu:after { content:' '; display:inline-block; width: 100%; height: 0 }
.menu > span {display:inline-block} 
</style>

Một điều cần lưu ý là bạn phải để khoảng cách giữa mỗi phần tử. [Xem trò đùa.]

Có hai lý do để đặt các mục menu thành khối nội tuyến:

  1. Nếu phần tử là theo mặc định, một mục cấp khối (chẳng hạn như an <li>), thì màn hình phải được đặt thành nội tuyến hoặc khối nội tuyến để ở trên cùng một dòng.
  2. Nếu phần tử có nhiều hơn một từ ( <span>click here</span>), mỗi từ sẽ được phân phối đồng đều khi được đặt thành nội tuyến, nhưng chỉ các phần tử sẽ được phân phối khi được đặt thành khối nội tuyến.

Xem JSFiddle

CHỈNH SỬA:
Bây giờ flexbox đã hỗ trợ rộng rãi (tất cả không phải IE và IE 10+), có một "cách tốt hơn".
Giả sử cấu trúc phần tử giống như trên, tất cả những gì bạn cần là:

<style>
    .menu { display: flex; justify-content: space-between; }
</style>

Nếu bạn muốn các phần tử bên ngoài cũng có khoảng cách, chỉ cần chuyển không gian giữa sang không gian xung quanh.
Xem JSFiddle


22

Nếu ai đó muốn thử một cách tiếp cận hơi khác, họ có thể sử dụng FLEX.

HTML

<div class="test">
    <div>Div 1</div>
    <div>Div 2</div>
    <div>Div 3</div>
    <div>Div 4</div>
</div>

CSS

.test {
    display: flex;
    flex-flow: row wrap;
    justify-content: space-around;
}
.test > div {
    margin-top: 10px;
    padding: 20px;
    background-color: #FF0000;
}

Đây là fiddle: http://jsfiddle.net/ynemh3c2/ (Hãy thử thêm / bớt div)

Đây là nơi tôi đã tìm hiểu về điều này: https://css-tricks.com/snippets/css/a-guide- to-flexbox /


10

justify-content: space-betweendisplay: flexlà tất cả những gì chúng tôi cần, nhưng cảm ơn @Pratul đã truyền cảm hứng!


Câu trả lời tuyệt vời. Mẹo: Sử dụng flex-wrap: wrapđể bọc nội dung xung quanh.
Suyash Gupta

8

Đây là cách nhanh chóng và dễ dàng để làm điều đó

<div>
    <span>Span 1</span>
    <span>Span 2</span>
    <span>Span 3</span>
</div>

css

div{
    width:100%;
}
span{
    display:inline-block;    
    width:33%;
    text-align:center;
}

Sau đó điều chỉnh widthcủaspan s cho số mà bạn có.

Ví dụ: http://jsfiddle.net/jasongennaro/wvJxD/


sooo ... không có cách nào dễ dàng để nó chỉ tự động điều chỉnh chiều rộng?
jurchiks

width: 33%;gần như bạn có thể nhận được, nhưng nó dựa trên vùng chứa mẹ, không phải số phần tử con. Nếu bạn muốn nó điều chỉnh dựa trên các phần tử con (span), có thể bạn sẽ cần chơi với JavaScript.
Shauna

đúng @Shauna. @jurchiks, bạn có thể tự động tính toán các widths dựa trên số spans nhưng điều đó sẽ yêu cầu một số j. Nếu menu của bạn không thay đổi thường xuyên, thì việc điều chỉnh menu widthsẽ không thành vấn đề.
Jason Gennaro

@ josh.trow. Nó đã chậm đối với tôi cả ngày.
Jason Gennaro

@Jason - đã làm điều đó rồi (ngoại trừ PHP; không biết JS đủ tốt, có thể ai đó có thể dạy tôi cách làm điều này?). Có vẻ ổn, nhưng lợi nhuận trở thành một vấn đề.
jurchiks

1

Bạn chỉ cần hiển thị div với id #menulà vùng chứa flex như thế này:

#menu{
    width: 800px;
    display: flex;
    justify-content: space-between;
}

0

Tôi đã quản lý để làm điều đó với tổ hợp css sau:

text-align: justify;
text-align-last: justify;
text-justify: inter-word;

0

.container {
  padding: 10px;
}
.parent {
  width: 100%;
  background: #7b7b7b;
  display: flex;
  justify-content: space-between;
  height: 4px;
}
.child {
  color: #fff;
  background: green;
  padding: 10px 10px;
  border-radius: 50%;
  position: relative;
  top: -8px;
}
<div class="container">
  <div class="parent">
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
    <span class="child"></span>
  </div>
</div>


-1

Tạo tất cả các nhịp được sử dụng các phần tử khối nội tuyến. Tạo một khoảng kéo dài trống với chiều rộng 100% bên dưới danh sách các nhịp chứa các mục menu. Tiếp theo, tạo div chứa các nhịp text-align: justified. Sau đó, điều này sẽ buộc các phần tử khối nội tuyến [các mục menu của bạn] phân phối đồng đều.

https://jsfiddle.net/freedawirl/bh0eadzz/3/

  <div id="container">

          <div class="social">
            <a href="#" target="_blank" aria-label="facebook-link">
            <img src="http://placehold.it/40x40">
            </a>
            <a href="#" target="_blank" aria-label="twitter-link">
                <img src="http://placehold.it/40x40">
            </a>
            <a href="#" target="_blank" aria-label="youtube-link">
                <img src="http://placehold.it/40x40">
            </a>
            <a href="#" target="_blank" aria-label="pinterest-link">
                 <img src="http://placehold.it/40x40">
            </a>
            <a href="#" target="_blank" aria-label="snapchat-link">
                <img src="http://placehold.it/40x40">
            </a>
            <a href="#" target="_blank" aria-label="blog-link">
                 <img src="http://placehold.it/40x40">
            </a>

            <a href="#" aria-label="phone-link">
                 <img src="http://placehold.it/40x40">
            </a>
            <span class="stretch"></span>
          </div>
             </div>
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.