Căn giữa một khối div không có chiều rộng


240

Tôi gặp sự cố khi cố gắng tập trung vào "sản phẩm" của khối div vì tôi không biết trước chiều rộng của div. Bất cứ ai cũng có một giải pháp?

Cập nhật: Vấn đề tôi gặp phải là tôi không biết mình sẽ hiển thị bao nhiêu sản phẩm, tôi có thể có 1, 2 hoặc 3 sản phẩm, tôi có thể căn giữa chúng nếu đó là một số cố định vì tôi biết chiều rộng của phụ huynh div, tôi chỉ không biết làm thế nào khi nội dung động.

.product_container {
  text-align: center;
  height: 150px;
}

.products {
  height: 140px;
  text-align: center;
  margin: 0 auto;
  clear: ccc both; 
}
.price {
  margin: 6px 2px;
  width: 137px;
  color: #666;
  font-size: 14pt;
  font-style: normal;
  border: 1px solid #CCC;
  background-color:	#EFEFEF;
}
<div class="product_container">
  <div class="products" id="products">
    <div id="product_15">
      <img src="/images/ecommerce/card_default.png">
      <div class="price">R$ 0,01</div>
    </div>

    <div id="product_15">
      <img src="/images/ecommerce/card_default.png">
      <div class="price">R$ 0,01</div>
    </div>   

    <div id="product_15">
      <img src="/images/ecommerce/card_default.png">
      <div class="price">R$ 0,01</div>
    </div>
  </div>
</div>


Chính xác thì vấn đề bạn đang gặp phải là gì?
anand.trex

Câu trả lời:


254

Cập nhật ngày 27 tháng 2 năm 2015: Câu trả lời ban đầu của tôi tiếp tục được bình chọn, nhưng bây giờ tôi thường sử dụng phương pháp của @ bobince thay thế.

.child { /* This is the item to center... */
  display: inline-block;
}
.parent { /* ...and this is its parent container. */
  text-align: center;
}

Bài viết gốc của tôi cho mục đích lịch sử:

Bạn có thể muốn thử phương pháp này.

<div class="product_container">
    <div class="outer-center">
        <div class="product inner-center">
        </div>
    </div>
    <div class="clear"/>
</div>

Đây là phong cách phù hợp:

.outer-center {
    float: right;
    right: 50%;
    position: relative;
}
.inner-center {
    float: right;
    right: -50%;
    position: relative;
}
.clear {
    clear: both;
}

Câu đố

Ý tưởng ở đây là bạn chứa nội dung bạn muốn tập trung vào hai div, một bên ngoài và một bên trong. Bạn thả nổi cả hai div để độ rộng của chúng tự động co lại để phù hợp với nội dung của bạn. Tiếp theo, bạn tương đối định vị div bên ngoài với cạnh phải của nó ở giữa container. Cuối cùng, bạn tương đối định vị div bên trong theo hướng ngược lại bằng một nửa chiều rộng của chính nó (thực ra là chiều rộng của div bên ngoài, nhưng chúng giống nhau). Cuối cùng, tập trung vào nội dung trong bất kỳ vật chứa nào.

Bạn có thể cần div trống đó ở cuối nếu bạn phụ thuộc vào nội dung "sản phẩm" của mình để định kích thước chiều cao cho "sản phẩm_container".


1
Nếu bạn không cung cấp overflow:hiddencho .product_containercác outer-centerdiv sẽ chồng chéo nội dung khác gần đó để bên phải của nó. Bất kỳ liên kết hoặc nút bên phải của outer-centerwont sẽ không hoạt động. Hãy thử màu nền outer-centerđể hiểu sự cần thiết cho overflow :hidden. Đây là một chỉnh sửa đề xuất bởi Cicil Thomas
Benjol

Cách tiếp cận này là hoàn hảo cho các trang web máy tính để bàn ... trên các thiết bị di động, các div bên trong dường như gắn vào bên phải. Có một giải pháp?
Mich Dart

3
Nói cho tôi nghe về nó đi! Đôi khi chúng ta chỉ cần một giải pháp và không cần phải có một lựa chọn tốt. Một bảng một ô là một tùy chọn khác, mặc dù một bảng có một ô không thực sự là một bảng, phải không?
Mike M. Lin

@fgysin Đồng ý, đó là một hack phản trực giác. Và các nhà thiết kế tự hỏi tại sao mọi người vẫn xem xét rơi trở lại bố trí dựa trên bảng.
Yuck

1
Câu hỏi này là năm tuổi. Câu trả lời này đã lỗi thời nhưng không bao giờ rất thanh lịch để bắt đầu. Những gì bạn nên làm là sử dụng display: inline-block
Wray Bowling

140

Một phần tử có 'display: block' (theo div là mặc định) có chiều rộng được xác định bởi chiều rộng của vùng chứa của nó. Bạn không thể tạo chiều rộng của khối phụ thuộc vào chiều rộng của nội dung của khối (co lại cho vừa).

(Ngoại trừ các khối 'float: left / right' trong CSS 2.1, nhưng điều đó không được sử dụng để định tâm.)

Bạn có thể đặt thuộc tính 'hiển thị' thành 'khối nội tuyến' để biến một khối thành một đối tượng thu nhỏ vừa vặn có thể được điều khiển bởi thuộc tính căn chỉnh văn bản của cha mẹ, nhưng hỗ trợ trình duyệt là không chính xác. Bạn hầu như có thể thoát khỏi nó bằng cách sử dụng hack (ví dụ: xem -moz-inline-stack) nếu bạn muốn đi theo cách đó.

Cách khác để đi là bảng. Điều này có thể cần thiết khi bạn có các cột có chiều rộng thực sự không thể biết trước. Tôi thực sự không thể biết bạn đang cố gắng làm gì từ mã ví dụ - không có gì rõ ràng trong đó sẽ cần một khối thu nhỏ để phù hợp - nhưng một danh sách các sản phẩm có thể được coi là dạng bảng.

[PS. không bao giờ sử dụng 'pt' cho kích thước phông chữ trên web. 'px' đáng tin cậy hơn nếu bạn thực sự cần văn bản có kích thước cố định, nếu không, các đơn vị tương đối như '%' sẽ tốt hơn. Và rõ ràng: ccc cả hai - một lỗi đánh máy?]

.center{
   text-align:center; 
}

.center > div{ /* N.B. child combinators don't work in IE6 or less */
   display:inline-block;
}

Câu đố


53
cha mẹ -> text-align: centre | con-> display: inline-block
mdskinner

5
display: inline-blockkhông được hỗ trợ trong IE7 và các phiên bản Firefox cũ hơn
Jake Wilson

1
@Jakobud, đối với IE7, hãy sử dụng "display: inline; zoom: 1;" thay vì "display: inline-block;". Nó hoạt động cho các yếu tố khối.
mihail-haritonov

1
kiểm tra liên kết này để biết thêm thông tin về cách sử dụng phương pháp này qua trình duyệt chéo - blog.mozilla.org/webdev/2009/02/20/cross-browser-inline-block
keyoke

1
Tôi đã sử dụng scss này để thực hiện nó, nó sẽ hoạt động miễn là cấu trúc html của bạn tồn tại để hỗ trợ nó: .center {text-align: centre; &: con đầu lòng {display: inline-block; }}
Dovev Hefetz

95

Hầu hết các trình duyệt hỗ trợ display: table;quy tắc CSS. Đây là một mẹo hay để tập trung vào div trong vùng chứa mà không cần thêm HTML cũng như áp dụng các kiểu ràng buộc cho vùng chứa (giống như text-align: center;sẽ tập trung tất cả nội dung nội tuyến khác trong vùng chứa), trong khi vẫn giữ độ rộng động cho div chứa:

HTML:

<div class="container">
  <div class="centered">This content is centered</div>
</div>

CSS:

.centered { display: table; margin: 0 auto; }


Cập nhật (2015 / 03-09):

Cách thích hợp để làm điều này ngày nay thực sự là sử dụng các quy tắc flexbox. Hỗ trợ trình duyệt bị hạn chế hơn một chút ( hỗ trợ bảng CSS so với hỗ trợ flexbox ) nhưng phương pháp này cũng cho phép nhiều thứ khác và là quy tắc CSS dành riêng cho loại hành vi này:

HTML:

<div class="container">
  <div class="centered">This content is centered</div>
</div>

CSS:

.container {
  display: flex;
  flex-direction: column; /* put this if you want to stack elements vertically */
}
.centered { margin: 0 auto; }


11
Tôi nghĩ rằng đây chắc chắn là giải pháp tốt nhất. Không liên quan đến bất kỳ hack lạ nào với div lồng nhau trôi nổi, hoặc bất cứ điều gì tương tự. Tôi nghĩ lý do duy nhất nó không được đánh giá cao hơn là vì mọi người đã đi quá xa so với bàn. Đây không phải là một bảng, vì vậy tôi nghĩ rằng đó là một phương pháp hoàn toàn hợp pháp.
Dan Jones

1
Đồng ý, đây dường như là giải pháp tốt nhất. Mặc dù giải pháp của @ bobince cũng đơn giản, nhưng nó có tác dụng phụ là thay đổi kiểu trong thành phần bên trong.
jorgeh

Các display: table;biến thể là lý tưởng cho pseudo-yếu tố ( ::before, ::after), nơi bạn không thể bổ sung thêm đánh dấu, và bạn muốn tránh sự gián đoạn cho phong cách nguyên tố lân cận.
Trả lời

20

Sáu cách để da mèo đó:

Nút một: bất cứ thứ gì thuộc loại display: blocksẽ đảm nhận chiều rộng cha mẹ đầy đủ. (trừ khi kết hợp với floathoặc display: flexcha mẹ). Thật. Ví dụ xấu.

Nút 2: đi display: inline-blocksẽ dẫn đến chiều rộng tự động (chứ không phải đầy đủ). Sau đó bạn có thể sử dụng trung tâm text-align: center trên khối gói . Có lẽ là dễ nhất và tương thích rộng rãi nhất, ngay cả với các trình duyệt 'cổ điển' ...

.wrapTwo
  text-align: center;
.two
  display: inline-block; // instantly shrinks width

Nút 3: Không cần đặt bất cứ thứ gì lên bọc. Vì vậy, có lẽ đây là giải pháp thanh lịch nhất. Cũng hoạt động theo chiều dọc. (Hỗ trợ trình duyệt cho transtlate là đủ tốt (≥IE9) những ngày này ...).

position: relative;
display: inline-block; // instantly shrinks width
left: 50%;
transform: translateX(-50%);

Btw: Cũng là một cách tuyệt vời cho các khối định tâm theo chiều dọc có chiều cao không xác định (liên quan đến định vị tuyệt đối).

Nút 4: Định vị tuyệt đối. Chỉ cần đảm bảo dự trữ đủ chiều cao trong trình bao bọc, vì sẽ không có ai khác (không xóa hoặc không ẩn ...)

.four
  position absolute
  top 0
  left 50%
  transform translateX(-50%)
.wrapFour
  position relative // otherwise, absolute positioning will be relative to page!
  height 50px // ensure height
  background lightgreen // just a marker

Nút 5: float (cũng mang các yếu tố cấp khối cho chiều rộng động) và sự thay đổi tương đối. Mặc dù tôi chưa bao giờ thấy điều này trong tự nhiên. Có lẽ có những bất lợi ...

.wrapFive
  &:after // aka 'clearfix'
    content ''
    display table
    clear both

.five  
  float left
  position relative
  left 50%
  transform translateX(-50%)

Cập nhật: Nút 6: Và ngày nay, bạn cũng có thể sử dụng hộp flex. Lưu ý, các kiểu đó áp dụng cho trình bao bọc của đối tượng chính giữa.

.wrapSix
  display: flex
  justify-content: center

→ mã nguồn đầy đủ (cú pháp bút stylus)


17

Tôi tìm thấy một giải pháp tao nhã hơn, kết hợp "chặn nội tuyến" để tránh sử dụng float và hacky Clear: cả hai. Nó vẫn yêu cầu các div lồng nhau, không phải là rất ngữ nghĩa nhưng nó chỉ hoạt động ...

div.outer{
    display:inline-block;
    position:relative;
    left:50%;
}

div.inner{
    position:relative;
    left:-50%;
}

Hy vọng nó giúp!


4
<div class="outer">
   <div class="target">
      <div class="filler">
      </div>
   </div>
</div>

.outer{
   width:100%;
   height: 100px;
}

.target{
   position: absolute;
   width: auto;
   height: 100px;
   left: 50%;
   transform: translateX(-50%);
}

.filler{
   position:relative;
   width:150px;
   height:20px;
}

Nếu phần tử mục tiêu được định vị tuyệt đối, bạn có thể căn giữa nó bằng cách di chuyển 50% theo một hướng ( left: 50%) và sau đó chuyển đổi 50% theo hướng đối lập ( transform:translateX(-50%)). Điều này hoạt động mà không xác định chiều rộng của phần tử đích (hoặc với width:auto). Vị trí của phần tử cha có thể là tĩnh, tuyệt đối, tương đối hoặc cố định.


1
Điều này sẽ ra khỏi trung tâm bằng một nửa chiều rộng của điều bạn đang định tâm.
4 giờ sáng

@ 4imble Không, nó sẽ không. Thuộc tính "bên trái" di chuyển nó 50% (50% chiều rộng của cha mẹ) và translX (-50%) di chuyển 50% theo cách khác (50% chiều rộng của phần tử mục tiêu).
West1

À đúng rồi, tôi đã bỏ qua bản dịchX. Không chắc chắn điều này đáng tin cậy trong bất kỳ IE nào trước IE 11. Nhưng bạn đã đúng.
4 giờ sáng

3

Theo mặc định, divcác phần tử được hiển thị dưới dạng phần tử khối, vì vậy chúng có chiều rộng 100%, làm cho việc định tâm chúng trở nên vô nghĩa. Theo đề xuất của Arief, bạn phải chỉ định a widthvà sau đó bạn có thể sử dụng autokhi chỉ định marginđể căn giữa a div.

Ngoài ra, bạn cũng có thể ép buộc display: inline, nhưng sau đó bạn sẽ có một cái gì đó gần giống như spanthay vì một div, vì vậy nó không có nhiều ý nghĩa.


3

Điều này sẽ tập trung vào một yếu tố như Danh sách được sắp xếp hoặc Danh sách không theo thứ tự hoặc bất kỳ yếu tố nào. Chỉ cần bọc nó bằng Div với lớp bên ngoài và cung cấp cho phần tử bên trong lớp bên trong.

Lớp tài khoản bên ngoài cho IE, Mozilla cũ và hầu hết các trình duyệt mới hơn.

 .outerElement {
        display: -moz-inline-stack;
        display: inline-block;
        vertical-align: middle;
        zoom: 1;
        position: relative;
        left: 50%;
    }

.innerElement {
    position: relative;
    left: -50%;
} 

Vui lòng thêm một mô tả với mã của bạn. Đăng mã trên nó sẽ không có ý nghĩa nhiều đối với khách truy cập tương lai của SO.
Ren

3

sử dụng flexbox css3 với nội dung justify: centre;

    <div class="row">
         <div class="col" style="background:red;">content1</div>
          <div class="col" style="">content2</div>
    </div>


.row {
    display: flex; /* equal height of the children */
    height:100px;
    border:1px solid red;
    width: 400px;
    justify-content:center;
}

1

Sự thay đổi nhỏ về câu trả lời của Mike M. Lin

Nếu bạn thêm overflow: auto;(hoặc hidden) vào div.product_container, thì bạn không cần div.clear.

Điều này được bắt nguồn từ bài viết này -> http://www.quirksmode.org/css/clear.html

Đây là bản sửa đổi HTML:

<div class="product_container">
    <div class="outer-center">
        <div class="product inner-center">
        </div>
    </div>
</div>

Và đây là CSS được sửa đổi:

.product_container {
  overflow: auto;
  /* width property only required if you want to support IE6 */
  width: 100%;
}

.outer-center {
  float: right;
  right: 50%;
  position: relative;
}

.inner-center {
  float: right;
  right: -50%;
  position: relative;
}

Lý do, tại sao tốt hơn mà không có div.clear(ngoài việc cảm thấy sai khi có một phần tử trống) là việc gán lề quá mức của Firefox.

Nếu, ví dụ, bạn có html này:

<div class="product_container">
    <div class="outer-center">
        <div class="product inner-center">
        </div>
    </div>
    <div style="clear: both;"></div>
</div>
<p style="margin-top: 11px;">Some text</p>

sau đó, trong Firefox (8.0 tại điểm viết), bạn sẽ thấy 11pxlề trước product_container . Điều tồi tệ hơn là bạn sẽ có được một thanh cuộn dọc cho toàn bộ trang, ngay cả khi nội dung vừa vặn với kích thước màn hình.


1

Hãy thử css và đánh dấu mới này

Đây là bản sửa đổi HTML:

<div class="product_container">
<div class="products" id="products">
   <div id="product_15" class="products_box">
       <img src="/images/ecommerce/card_default.png">
       <div class="price">R$ 0,01</div>
   </div>
   <div id="product_15" class="products_box">
       <img src="/images/ecommerce/card_default.png">
       <div class="price">R$ 0,01</div>
   </div>   
   <div id="product_15" class="products_box">
       <img src="/images/ecommerce/card_default.png">
       <div class="price">R$ 0,01</div>
   </div>
</div>

Và đây là CSS được sửa đổi:

<pre>
.product_container 
 {
 text-align:    center;
 height:        150px;
 }

.products {
    left: 50%;
height:35px;
float:left;
position: relative;
margin: 0 auto;
width:auto;
}
.products .products_box
{
width:auto;
height:auto;
float:left;
  right: 50%;
  position: relative;
}
.price {
    margin:        6px 2px;
    width:         137px;
    color:         #666;
    font-size:     14pt;
    font-style:    normal;
    border:        1px solid #CCC;
    background-color:   #EFEFEF;
}


1
<div class="product_container">
<div class="outer-center">
<div class="product inner-center">
    </div>
</div>
<div class="clear"></div>
</div>

.outer-center
{
float: right;
right: 50%;
position: relative;
}
.inner-center 
{
float: right;
right: -50%;
position: relative;
}
.clear 
{
clear: both;
}

.product_container
{
overflow:hidden;
}

Nếu bạn không cung cấp "tràn: ẩn" cho ".product_container" thì div "trung tâm bên ngoài" sẽ chồng lấp các nội dung khác gần đó sang bên phải của nó. Bất kỳ liên kết hoặc nút nào ở bên phải của "trung tâm bên ngoài" sẽ không hoạt động. Hãy thử màu nền cho "trung tâm bên ngoài" để hiểu nhu cầu của "tràn: ẩn"


1

Tôi tìm thấy giải pháp thú vị, tôi đang tạo thanh trượt và phải điều khiển trung tâm trượt và tôi đã làm điều này và hoạt động tốt. Bạn cũng có thể thêm vị trí tương đối cho cha mẹ và di chuyển vị trí con theo chiều dọc. Hãy xem http://jsfiddle.net/bergb/6DvJz/

CSS:

#parent{
        width:600px;
        height:400px;
        background:#ffcc00;
        text-align:center;
    }

#child{
        display:inline-block;
        margin:0 auto;
        background:#fff;
    }  

HTML:

<div id="parent">
    <div id="child">voila</div>
</div>

1

Làm display:table;và đặt marginthànhauto

Mã quan trọng của mã:

.relatedProducts {
    display: table;
    margin-left: auto;
    margin-right: auto;
}

Cho dù bây giờ bạn có bao nhiêu yếu tố, nó sẽ tự động căn chỉnh ở giữa

Ví dụ trong đoạn mã:


0

Tôi sợ cách duy nhất để làm điều này mà không chỉ định rõ ràng chiều rộng là sử dụng bảng (gasp).


5
rephrased: Nếu bạn không muốn dành một giờ tiếp theo để thử tất cả các loại kết hợp CSS, DIV lồng nhau và trình duyệt, hãy truy cập trực tiếp vào các bảng.
Eduardo Molteni

Bảng không được thiết kế để được sử dụng như là yếu tố thiết kế. Đó là phong cách xấu.
Sebi2020

0

Sửa lỗi nhanh, nhưng nó hoạt động ...

CSS:

#mainContent {
    position:absolute;
    width:600px;
    background:#FFFF99;
}

#sidebar {
    float:left;
    margin-left:610px;
    max-width:300;
    background:#FFCCCC;
}
#sidebar{


    text-align:center;
}

HTML:

<center>
<table border="0" cellspacing="0">
  <tr>
    <td>
<div id="mainContent">
1<br/>
<br/>
123<br/>
123<br/>
123<br/>
</div><div id="sidebar"><br/>
</div></td>
</tr>
</table>
</center>

0

Khắc phục đơn giản hoạt động trong các trình duyệt cũ (nhưng sử dụng bảng và yêu cầu đặt chiều cao):

<div style="width:100%;height:40px;position:absolute;top:50%;margin-top:-20px;">
  <table style="width:100%"><tr><td align="center">
    In the middle
  </td></tr></table>
</div>

0
<style type="text/css">
.container_box{
    text-align:center
}
.content{
    padding:10px;
    background:#ff0000;
    color:#ffffff;

}

sử dụng span istead của divs bên trong

<div class="container_box">
   <span class="content">Hello</span>
</div>

0

Tôi biết câu hỏi này đã cũ, nhưng tôi đang giải quyết nó. Rất giống với câu trả lời của bobince nhưng với ví dụ mã làm việc.

Làm cho mỗi sản phẩm là một khối nội tuyến. Trung tâm các nội dung của container. Làm xong.

http://jsfiddle.net/rgbk/6Z2Re/

<style>
.products{
    text-align:center;
}

.product{
    display:inline-block;
    text-align:left;

    background-image: url('http://www.color.co.uk/wp-content/uploads/2013/11/New_Product.jpg');
    background-size:25px;
    padding-left:25px;
    background-position:0 50%;
    background-repeat:no-repeat;
}

.price {
    margin:        6px 2px;
    width:         137px;
    color:         #666;
    font-size:     14pt;
    font-style:    normal;
    border:        1px solid #CCC;
    background-color:   #EFEFEF;
}
</style>


<div class="products">
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
    <div class="product">
        <div class="price">R$ 0,01</div>
    </div>
</div>

Xem thêm: Trung tâm khối nội tuyến với chiều rộng động trong CSS


Không phải câu trả lời này đã cung cấp cùng một giải pháp? stackoverflow.com/a/284064/547733
Maxime Rossini

1
bạn nói đúng, madmox! Nó không mạnh mẽ như vậy. Ngoài ra, tôi nhận ra rằng việc đặt văn bản căn chỉnh sang trái hoặc phải có nghĩa là điều này sẽ không bao giờ hoạt động trên một trang web có các bản dịch bao gồm chuyển thứ tự đọc từ trái sang phải sang phải sang trái. căn chỉnh văn bản là để căn chỉnh văn bản, không phải các yếu tố. Lý tưởng nhất trong tương lai gần, chúng tôi sẽ phụ thuộc vào hiển thị: flex cho loại điều này.
Wray Bowling

0

Đây là một cách để tập trung mọi thứ trong một div không biết chiều rộng bên trong của các phần tử.

#product_15{
    position: relative;
    margin: 0 auto;
    display: table;
}
.price, img{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

-1

giải pháp của tôi là:

.parent {
    display: flex;
    flex-wrap: wrap;
}

.product {
    width: 240px;
    margin-left: auto;
    height: 127px;
    margin-right: auto;
}

-7

thêm css này vào lớp Product_container của bạn

    margin: 0px auto;
    padding: 0px;
    border:0;
    width: 700px;

Câu hỏi đặc biệt nói "không có chiều rộng"
Dez Udezue
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.