Zentrieren eines Div-Blocks ohne die Breite

240

Ich habe ein Problem, wenn ich versuche, den Div-Block "Produkte" zu zentrieren, weil ich die Div-Breite nicht im Voraus kenne. Hat jemand eine Lösung?

Update: Das Problem ist, dass ich nicht weiß, wie viele Produkte ich anzeigen werde. Ich kann 1, 2 oder 3 Produkte haben. Ich kann sie zentrieren, wenn es eine feste Zahl ist, da ich die Breite des übergeordneten Produkts kenne div, ich weiß nur nicht, wie ich es machen soll, wenn der Inhalt dynamisch ist.

.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>

Nhan
quelle
Was genau ist das Problem, das Sie haben?
anand.trex

Antworten:

254

Update 27. Februar 2015: Meine ursprüngliche Antwort wird immer wieder abgestimmt, aber jetzt verwende ich normalerweise stattdessen den Ansatz von @ bobince.

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

Mein ursprünglicher Beitrag für historische Zwecke:

Vielleicht möchten Sie diesen Ansatz ausprobieren.

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

Hier ist der passende Stil:

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

JSFiddle

Die Idee hier ist, dass Sie den Inhalt, den Sie zentrieren möchten, in zwei Divs enthalten, einem äußeren und einem inneren. Sie schweben beide Divs so, dass ihre Breite automatisch an Ihren Inhalt angepasst wird. Als nächstes positionieren Sie das äußere Div relativ mit seiner rechten Kante in der Mitte des Containers. Zuletzt positionieren Sie den inneren Teil relativ in die entgegengesetzte Richtung um die Hälfte seiner eigenen Breite (tatsächlich die Breite des äußeren Teils, aber sie sind gleich). Letztendlich zentriert das den Inhalt in dem Container, in dem er sich befindet.

Sie können am Ende dieses leer div benötigen , wenn Sie die Höhe auf dem „Produkt“ Inhalt der Größe abhängen für die „product_container“.

Mike M. Lin
quelle
1
Wenn Sie nicht overflow:hiddenfür .product_containerdas outer-centerdiv sorgen , überlappen sich andere Inhalte in der Nähe rechts davon. Alle Links oder Schaltflächen rechts von outer-centerfunktionieren nicht. Versuchen Sie die Hintergrundfarbe outer-center, um die Notwendigkeit zu verstehen overflow :hidden. Dies war eine vorgeschlagene Bearbeitung von Cicil Thomas
Benjol
Dieser Ansatz ist perfekt für Desktop-Websites ... auf mobilen Websites scheinen die inneren Divs jedoch rechts anzuhängen. Gibt es eine Lösung?
Mich Dart
3
Erzähl mir davon! Manchmal brauchen wir einfach eine Lösung und haben nicht den Luxus, eine gute zur Auswahl zu haben. Eine Einzelzellentabelle ist eine weitere Option, obwohl eine Tabelle mit einer Zelle nicht wirklich eine Tabelle ist, oder?
Mike M. Lin
@fgysin Einverstanden, es ist ein kontraintuitiver Hack. Und Designer fragen sich, warum die Leute immer noch darüber nachdenken, auf tischbasierte Layouts zurückzugreifen.
Yuck
1
Diese Frage ist fünf Jahre alt. Diese Antwort ist veraltet, war aber anfangs nie sehr elegant. Was Sie tun sollten, ist Anzeige verwenden: Inline-Block
Wray Bowling
140

Ein Element mit 'display: block' (standardmäßig div) hat eine Breite, die durch die Breite seines Containers bestimmt wird. Sie können die Breite eines Blocks nicht von der Breite seines Inhalts abhängig machen (auf Anpassung verkleinern).

(Mit Ausnahme von Blöcken, die in CSS 2.1 "float: left / right" sind, aber für die Zentrierung nicht geeignet sind.)

Sie können die Eigenschaft 'display' auf 'inline-block' setzen, um einen Block in ein Objekt zu verwandeln, das an die Größe angepasst werden kann. Dies kann durch die Textausrichtungseigenschaft des übergeordneten Objekts gesteuert werden. Die Browserunterstützung ist jedoch unvollständig. Sie können meistens mit Hacks davonkommen (siehe z. B. -moz-inline-stack), wenn Sie diesen Weg gehen möchten.

Der andere Weg sind Tische. Dies kann erforderlich sein, wenn Sie Spalten haben, deren Breite im Voraus nicht bekannt sein kann. Ich kann anhand des Beispielcodes nicht wirklich sagen, was Sie versuchen - es ist nichts Offensichtliches darin, das einen Schrumpfblock benötigt -, aber eine Liste von Produkten könnte möglicherweise als tabellarisch betrachtet werden.

[PS. Verwenden Sie niemals 'pt' für Schriftgrößen im Web. 'px' ist zuverlässiger, wenn Sie wirklich Text mit fester Größe benötigen, andernfalls sind relative Einheiten wie '%' besser. Und "klar: ccc beide" - ein Tippfehler?]

.center{
   text-align:center; 
}

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

JSFiddle

Bobince
quelle
53
Eltern -> Textausrichtung: Mitte | child-> display: inline-block
mdskinner
5
display: inline-blockwird in IE7 und älteren Versionen von Firefox nicht unterstützt
Jake Wilson
1
@Jakobud, für IE7 verwenden Sie "display: inline; zoom: 1;" anstelle von "display: inline-block;". Es funktioniert für Blockelemente.
Mihail-Haritonov
1
Schauen Sie sich diesen Link an, um weitere Informationen zur Verwendung dieser Methode im Cross-Browser zu erhalten - blog.mozilla.org/webdev/2009/02/20/cross-browser-inline-block
keyoke
1
Ich habe dieses scss verwendet, um es zu implementieren. Dies funktioniert, solange Ihre HTML-Struktur vorhanden ist, um es zu unterstützen: .center {text-align: center; &: erstes Kind {Anzeige: Inline-Block; }}
Dovev Hefetz
95

Die meisten Browser unterstützen die display: table;CSS-Regel. Dies ist ein guter Trick, um ein Div in einem Container zu zentrieren, ohne zusätzlichen HTML-Code hinzuzufügen oder einschränkende Stile auf den Container anzuwenden (wie text-align: center;dies bei allen anderen Inline-Inhalten im Container der Fall wäre), während die dynamische Breite für das enthaltene Div beibehalten wird:

HTML:

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

CSS:

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


Update (09.03.2015):

Der richtige Weg, dies heute zu tun, besteht darin, Flexbox-Regeln zu verwenden. Die Browserunterstützung ist etwas eingeschränkter ( CSS-Tabellenunterstützung vs. Flexbox-Unterstützung ), aber diese Methode ermöglicht auch viele andere Dinge und ist eine dedizierte CSS-Regel für diese Art von Verhalten:

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; }

Maxime Rossini
quelle
11
Ich denke, das ist definitiv die beste Lösung. Enthält keine seltsamen Hacks mit schwebenden verschachtelten Divs oder Ähnlichem. Ich denke, der einzige Grund, warum es nicht höher bewertet wird, ist, dass die Leute zu weit gegen Tische gegangen sind. Dies ist kein Tisch, daher denke ich, dass es eine absolut legitime Methode ist.
Dan Jones
1
Einverstanden scheint dies die beste Lösung zu sein. Die Lösung von @ bobince ist zwar ebenfalls einfach, hat jedoch den Nebeneffekt, dass Stile im inneren Element geändert werden.
Jorgeh
Die display: table;Variante ist ideal für Pseudoelemente ( ::before, ::after), bei denen Sie kein zusätzliches Markup hinzufügen können und Störungen benachbarter Elementstile vermeiden möchten.
Walf
20

Sechs Möglichkeiten, diese Katze zu häuten:

Schaltfläche eins: Jeder Typ display: blocknimmt die volle Breite der Eltern an. (sofern nicht mit floatoder einem display: flexElternteil kombiniert ). Wahr. Schlechtes Beispiel.

Taste 2: Wenn Sie nach "gehen", display: inline-blockwird die Breite automatisch (und nicht in voller Breite) angezeigt. Sie können dann mit text-align: center auf dem Verpackungsblock zentrieren . Wahrscheinlich der einfachste und am weitesten kompatible, selbst mit "Vintage" -Browsern ...

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

Taste 3: Sie müssen nichts auf die Verpackung legen. Vielleicht ist dies die eleganteste Lösung. Funktioniert auch vertikal. (Browser-Unterstützung für Transtlate ist heutzutage gut genug (≥IE9) ...).

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

Übrigens: Auch eine gute Möglichkeit, Blöcke unbekannter Höhe vertikal zu zentrieren (in Verbindung mit der absoluten Positionierung).

Taste 4: Absolute Positionierung. Stellen Sie einfach sicher, dass Sie genügend Höhe im Wrapper reservieren, da dies sonst niemand tun wird (weder Clearfix noch implizit ...).

.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

Schaltfläche 5: float (wodurch auch Elemente auf Blockebene auf dynamische Breite gebracht werden) und eine relative Verschiebung. Obwohl ich das noch nie in freier Wildbahn gesehen habe. Vielleicht gibt es Nachteile ...

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

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

Update: Button 6: Und heutzutage können Sie auch Flex-Box verwenden. Beachten Sie, dass Stile für den Wrapper des zentrierten Objekts gelten.

.wrapSix
  display: flex
  justify-content: center

→ vollständiger Quellcode (Stiftsyntax)

Frank Nocke
quelle
17

Ich fand eine elegantere Lösung, indem ich "Inline-Block" kombinierte, um die Verwendung von Float und Hacky Clear zu vermeiden: beides. Es erfordert immer noch verschachtelte Divs tho, was nicht sehr semantisch ist, aber es funktioniert einfach ...

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

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

Ich hoffe es hilft!

JavierIEH
quelle
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;
}

Wenn das Zielelement absolut positioniert ist, können Sie es zentrieren, indem Sie es zu 50% in eine Richtung bewegen ( left: 50%) und dann zu 50% in die entgegengesetzte Richtung transformieren ( transform:translateX(-50%)). Dies funktioniert ohne Definition der Breite des Zielelements (oder mit width:auto). Die Position des übergeordneten Elements kann statisch, absolut, relativ oder fest sein.

West1
quelle
1
Dies ist um die Hälfte der Breite des zu zentrierenden Objekts außermittig.
4imble
@ 4imble Nein, wird es nicht. Die Eigenschaft "left" verschiebt sie um 50% (50% der Breite des übergeordneten Elements) und translateX (-50%) verschiebt sie um 50% in die andere Richtung (50% der Breite des Zielelements).
West1
Ahh ja, ich habe die translateX verpasst. Ich bin mir nicht sicher, ob dies in einem IE vor IE 11 zuverlässig ist. Aber Sie haben Recht.
4imble
3

Standardmäßig werden divElemente als Blockelemente angezeigt, sodass sie eine Breite von 100% haben, sodass das Zentrieren bedeutungslos ist. Wie von Arief vorgeschlagen, müssen Sie a angeben widthund können es dann autobeim Angeben verwenden, marginum a zu zentrieren div.

Alternativ könnten Sie auch erzwingen display: inline, aber dann hätten Sie etwas, das sich so ziemlich wie ein spanstatt wie ein verhält div, so dass das nicht viel Sinn macht.

Adam Bellaire
quelle
3

Dadurch wird ein Element wie eine geordnete Liste oder eine ungeordnete Liste oder ein beliebiges Element zentriert. Wickeln Sie es einfach mit einem Div in die Klasse von OuterElement ein und geben Sie dem inneren Element die Klasse von InnerElement.

Die Outerelement-Klasse berücksichtigt IE, alten Mozilla und die meisten neueren Browser.

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

.innerElement {
    position: relative;
    left: -50%;
} 
Greg Benner
quelle
Bitte fügen Sie eine Beschreibung mit Ihrem Code hinzu. Allein die Postleitzahl bedeutet für zukünftige Besucher von SO nicht viel.
Ren
3

Verwenden Sie die CSS3-Flexbox mit Rechtfertigungsinhalt: Mitte;

    <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;
}
zloctb
quelle
1

Leichte Variation der Antwort von Mike M. Lin

Wenn Sie hinzufügen overflow: auto;(oder hidden) div.product_container, dann brauchen Sie nicht div.clear.

Dies leitet sich aus diesem Artikel ab -> http://www.quirksmode.org/css/clearing.html

Hier ist modifiziertes HTML:

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

Und hier ist modifiziertes CSS:

.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;
}

Der Grund, warum es ohne besser ist div.clear(abgesehen davon, dass es sich falsch anfühlt, ein leeres Element zu haben), ist die übereifrige Margenzuweisung von Firefox.

Wenn Sie zum Beispiel dieses HTML haben:

<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>

In Firefox (8.0 zum Zeitpunkt des Schreibens) sehen Sie zuvor den11px Rand . Schlimmer ist, dass Sie eine vertikale Bildlaufleiste für die gesamte Seite erhalten, auch wenn der Inhalt gut in die Bildschirmabmessungen passt. product_container

Alexander Pogrebnyak
quelle
1

Probieren Sie dieses neue CSS und Markup aus

Hier ist modifiziertes 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>

Und hier ist modifiziertes CSS:

<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;
}

Shinov T.
quelle
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;
}

Wenn Sie für ".product_container" kein "overflow: hidden" angeben, überlappt das Div "Außenmitte" andere Inhalte in der Nähe rechts davon. Alle Links oder Schaltflächen rechts von "Außenmitte" funktionieren nicht. Versuchen Sie die Hintergrundfarbe für "äußere Mitte", um die Notwendigkeit von "Überlauf: versteckt" zu verstehen.

Cicil Thomas
quelle
1

Ich fand eine interessante Lösung, ich machte einen Schieberegler und musste die Schieberegler zentrieren, und ich tat dies und funktionierte einwandfrei. Sie können dem Elternteil auch eine relative Position hinzufügen und die untergeordnete Position vertikal verschieben. Schauen Sie sich http://jsfiddle.net/bergb/6DvJz/ an.

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>
Nikola
quelle
1

Tun display:table;und einstellen marginaufauto

Wichtiges Codebit:

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

Egal wie viele Elemente Sie jetzt haben, es wird automatisch in der Mitte ausgerichtet

Beispiel im Code-Snippet:

hahaha
quelle
0

Ich fürchte, der einzige Weg, dies zu tun, ohne die Breite explizit anzugeben, ist die Verwendung von (keuchenden) Tabellen.

Kon
quelle
5
umformuliert: Wenn Sie nicht die nächste Stunde damit verbringen möchten, alle Arten von Kombinationen aus CSS, verschachtelten DIVs und Browsern auszuprobieren, gehen Sie direkt zu den Tabellen.
Eduardo Molteni
Tabellen sind nicht als Gestaltungselemente gedacht. Das ist schlechter Stil.
Sebi2020
0

Crappy Fix, aber es funktioniert ...

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>
Lionel
quelle
0

Einfache Korrektur, die in alten Browsern funktioniert (verwendet jedoch Tabellen und erfordert das Festlegen einer Höhe):

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

}}

Verwenden Sie die Spanne anstelle der inneren Divs

<div class="container_box">
   <span class="content">Hello</span>
</div>
jemandem
quelle
0

Ich weiß, dass diese Frage alt ist, aber ich mache einen Sprung drauf. Sehr ähnlich zu Bobince's Antwort, aber mit funktionierendem Codebeispiel.

Machen Sie jedes Produkt zu einem Inline-Block. Zentrieren Sie den Inhalt des Behälters. Getan.

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>

Siehe auch: Inline-Blöcke mit dynamischer Breite in CSS zentrieren

Wray Bowling
quelle
Bietet diese Antwort nicht bereits die gleiche Lösung? stackoverflow.com/a/284064/547733
Maxime Rossini
1
Du hast recht, Madmox! Es ist jedoch nicht so robust. Außerdem ist mir klar, dass das Festlegen der Textausrichtung auf links oder rechts bedeutet, dass dies auf einer Site mit Übersetzungen, bei denen die Lesereihenfolge von links nach rechts von rechts nach links geändert wird, niemals funktioniert. Textausrichtung dient zum Ausrichten von Text, nicht von Elementen. Idealerweise werden wir in naher Zukunft auf das Display angewiesen sein: Flex für solche Dinge.
Wray Bowling
0

Dies ist eine Möglichkeit, alles innerhalb eines Div zu zentrieren, ohne die innere Breite der Elemente zu kennen.

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

Meine Lösung war:

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

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

Fügen Sie diese CSS zu Ihrer product_container-Klasse hinzu

    margin: 0px auto;
    padding: 0px;
    border:0;
    width: 700px;
Arief
quelle
Die Frage sagt ausdrücklich "ohne Breite"
Dez Udezue