Centrare un blocco div senza la larghezza


241

Ho un problema quando provo a centrare il blocco div "prodotti" perché non conosco in anticipo la larghezza div. Qualcuno ha una soluzione?

Aggiornamento: il problema che ho è che non so quanti prodotti visualizzerò, posso avere 1, 2 o 3 prodotti, posso centrarli se fosse un numero fisso in quanto conoscerei la larghezza del genitore div, semplicemente non so come farlo quando il contenuto è dinamico.

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


Qual è esattamente il problema che stai riscontrando?
anand.trex,

Risposte:


256

Aggiornamento 27 febbraio 2015: la mia risposta originale continua a essere votata, ma ora uso invece l'approccio di @ bobince.

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

Il mio post originale per scopi storici:

Potresti voler provare questo approccio.

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

Ecco lo stile di corrispondenza:

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

JSFiddle

L'idea qui è che tu contenga il contenuto che vuoi centrare in due div, uno esterno e uno interno. Fai galleggiare entrambi i div in modo che le loro larghezze si riducano automaticamente per adattarsi ai tuoi contenuti. Successivamente, si posiziona relativamente il div esterno con il bordo destro al centro del contenitore. Infine, posizioni relativamente il div interno nella direzione opposta della metà della sua stessa larghezza (in realtà la larghezza del div esterno, ma sono gli stessi). In definitiva, ciò centra il contenuto in qualunque contenitore si trovi.

Si potrebbe essere necessario che div vuoto, alla fine, se si dipende dal vostro contenuto "prodotto" a misura l'altezza per il "product_container".


1
Se non si prevede overflow:hiddenche .product_containeril outer-centerdiv si sovrapporrà ad altri contenuti vicini alla sua destra. Eventuali collegamenti o pulsanti a destra outer-centernon funzioneranno. Prova il colore di sfondo per outer-centercapire la necessità di overflow :hidden. Questa è stata una modifica suggerita da Cicil Thomas
Benjol il

Questo approccio è perfetto per i siti Web desktop ... su quelli per dispositivi mobili sembra che le divinità interne si attacchino a destra. C'è una soluzione?
Mich Dart,

3
Parlamene! A volte abbiamo semplicemente bisogno di una soluzione e non abbiamo il lusso di sceglierne una buona. Una tabella a cella singola è un'altra opzione, sebbene una tabella con una cella non sia realmente una tabella, vero?
Mike M. Lin,

@fgysin D'accordo, è un trucco controintuitivo. E i designer si chiedono perché le persone stiano ancora considerando di ricorrere a layout basati su tabella.
Yuck,

1
Questa domanda ha cinque anni. Questa risposta non è aggiornata ma non è mai stata molto elegante all'inizio. Quello che dovresti fare è usare display: inline-block
Wray Bowling

140

Un elemento con 'display: block' (come div è di default) ha una larghezza determinata dalla larghezza del suo contenitore. Non è possibile fare in modo che la larghezza di un blocco dipenda dalla larghezza del suo contenuto (riduzione per adattamento).

(Tranne i blocchi che sono 'float: left / right' in CSS 2.1, ma non serve per il centraggio.)

È possibile impostare la proprietà 'display' su 'inline-block' per trasformare un blocco in un oggetto restringibile che può essere controllato dalla proprietà text-align del genitore, ma il supporto del browser è imprevedibile. Puoi principalmente cavartela usando degli hack (es. Vedi -moz-inline-stack) se vuoi andare in quel modo.

L'altra strada da percorrere sono i tavoli. Questo può essere necessario quando hai colonne la cui larghezza non può essere conosciuta in anticipo. Non riesco davvero a capire cosa stai cercando di fare dal codice di esempio - non c'è nulla di ovvio lì dentro che avrebbe bisogno di un blocco restringibile per adattarsi - ma un elenco di prodotti potrebbe forse essere considerato tabulare.

[PS. non usare mai "pt" per le dimensioni dei caratteri sul Web. 'px' è più affidabile se hai davvero bisogno di testo di dimensioni fisse, altrimenti le unità relative come '%' sono migliori. E "chiaro: ccc entrambi" - un errore di battitura?]

.center{
   text-align:center; 
}

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

JSFiddle


53
parent -> text-align: center | child-> display: inline-block
mdskinner

5
display: inline-blocknon è supportato in IE7 e nelle versioni precedenti di Firefox
Jake Wilson,

1
@Jakobud, per IE7 usa "display: inline; zoom: 1;" anziché "display: inline-block;". Funziona con elementi a blocchi.
mihail-haritonov,

1
controlla questo link per maggiori informazioni su come utilizzare questo metodo cross browser - blog.mozilla.org/webdev/2009/02/20/cross-browser-inline-block
keyoke

1
Ho usato questo scss per implementarlo, che funzionerà fintanto che la tua struttura html esiste per supportarlo: .center {text-align: center; &: first-child {display: inline-block; }}
Dovev Hefetz,

95

La maggior parte dei browser supporta la display: table;regola CSS. Questo è un buon trucco per centrare un div in un contenitore senza aggiungere ulteriore HTML né applicare stili vincolanti al contenitore (come quello text-align: center;che centrerebbe tutto il resto del contenuto incorporato nel contenitore), mantenendo la larghezza dinamica per il div contenuto:

HTML:

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

CSS:

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


Aggiornamento (2015-03-09):

Il modo corretto per farlo oggi è in realtà utilizzare le regole di flexbox. Il supporto del browser è un po 'più limitato ( supporto tabella CSS vs supporto flexbox ) ma questo metodo consente anche molte altre cose ed è una regola CSS dedicata per questo tipo di comportamento:

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
Penso che questa sia sicuramente la soluzione migliore. Non comporta strani hack con div annidati fluttuanti o simili. Penso che l'unico motivo per cui non è valutato più in alto sia perché le persone sono andate troppo in là rispetto ai tavoli. Questo non è un tavolo, quindi penso che sia un metodo perfettamente legittimo.
Dan Jones,

1
D'accordo, questa sembra essere la soluzione migliore. Anche se la soluzione di @ bobince è semplice, ha anche l'effetto collaterale di alterare gli stili nell'elemento interno.
Jorgeh,

La display: table;variante è ideale per pseudo-elementi ( ::before, ::after) in cui non è possibile aggiungere markup extra e si desidera evitare l'interruzione di stili di elementi adiacenti.
Walf,

20

sei modi per pelare quel gatto:

Pulsante uno: qualsiasi tipo di tipo display: blockassumerà l'intera larghezza dei genitori. (se non combinato con floato un display: flexgenitore). Vero. Cattivo esempio

Pulsante 2: andare per display: inline-blockporterà alla larghezza automatica (piuttosto che piena). È quindi possibile centrare usando text-align: center sul blocco di avvolgimento . Probabilmente il più semplice e ampiamente compatibile, anche con i browser "vintage" ...

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

Pulsante 3: non è necessario mettere nulla sulla pellicola. Quindi forse questa è la soluzione più elegante. Funziona anche in verticale. (Il supporto browser per transtlate è abbastanza buono (≥IE9) in questi giorni ...).

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

A proposito: anche un ottimo modo per centrare verticalmente blocchi di altezza sconosciuta (in connessione con posizionamento assoluto).

Pulsante 4: posizionamento assoluto. Assicurati di riservare un'altezza sufficiente nel wrapper, poiché nessun altro lo farà (né clearfix né implicito ...)

.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

Pulsante 5: float (che porta anche gli elementi a livello di blocco alla larghezza dinamica) e uno spostamento relativo. Anche se non l'ho mai visto in natura. Forse ci sono degli svantaggi ...

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

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

Aggiornamento: Pulsante 6: e al giorno d'oggi, è possibile utilizzare anche la scatola flessibile. Si noti che gli stili si applicano al wrapper dell'oggetto centrato.

.wrapSix
  display: flex
  justify-content: center

→ codice sorgente completo (sintassi dello stilo)


17

Ho trovato una soluzione più elegante, combinando "inline-block" per evitare di usare float e hacky clear: entrambi. Richiede comunque div nidificati, che non è molto semantico ma funziona solo ...

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

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

Spero che sia d'aiuto!


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

Se l'elemento bersaglio è posizionato in modo assoluto, puoi centrarlo spostandolo del 50% in una direzione ( left: 50%) e poi trasformandolo del 50% nella direzione dell'opposizione ( transform:translateX(-50%)). Funziona senza definire la larghezza dell'elemento target (o con width:auto). La posizione dell'elemento genitore può essere statica, assoluta, relativa o fissa.


1
Questo sarà fuori centro di metà della larghezza della cosa che stai centrando.
4

@ 4imble No, non lo farà. La proprietà "left" la sposta del 50% (50% della larghezza del suo genitore), e translateX (-50%) la sposta del 50% nell'altro modo (50% della larghezza dell'elemento target).
Ovest 1

Ah, sì, mi mancava il translateX. Non sono sicuro che ciò sia affidabile in qualsiasi IE prima di IE 11. Ma hai ragione.
4

3

Per impostazione predefinita, gli divelementi vengono visualizzati come elementi a blocchi, quindi hanno una larghezza del 100%, il che rende il loro centramento insignificante. Come suggerito da Arief, devi specificare a widthe puoi quindi usarlo autoquando specifichi marginper centrare a div.

In alternativa, potresti anche forzare display: inline, ma poi avresti qualcosa che si comporta praticamente come un spaninvece di un div, quindi non ha molto senso.


3

Questo centrerà un elemento come un Elenco ordinato, un Elenco non ordinato o qualsiasi altro elemento. Basta avvolgerlo con un Div con la classe di outerElement e dare all'elemento interno la classe di innerElement.

La classe degli elementi esterni rappresenta IE, il vecchio Mozilla e la maggior parte dei browser più recenti.

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

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

Aggiungi una descrizione con il tuo codice. Pubblicare il codice da solo non significherà molto per i futuri visitatori di SO.
Ren,

3

usa la css3 flexbox con justify-content: center;

    <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

Leggera variazione sulla risposta di Mike M. Lin

Se aggiungi overflow: auto;(o hidden) a div.product_container, non hai bisogno div.clear.

Questo è derivato da questo articolo -> http://www.quirksmode.org/css/clearing.html

Ecco HTML modificato:

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

E qui è modificato 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;
}

Il motivo per cui è meglio senza div.clear(a parte il fatto che si senta sbagliato avere un elemento vuoto) è l'assegnazione del margine troppo zelante di Firefox.

Se, ad esempio, hai questo html:

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

quindi, in Firefox (8.0 al momento della scrittura), vedrai prima il11px margine . Quel che è peggio, è che otterrai una barra di scorrimento verticale per l'intera pagina, anche se il contenuto si adatta perfettamente alle dimensioni dello schermo. product_container


1

Prova questo nuovo CSS e markup

Ecco HTML modificato:

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

E qui è modificato 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;
}


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

Se non fornisci "overflow: hidden" per ".product_container", il div "centro-esterno" si sovrapporrà ad altri contenuti vicini alla sua destra. Eventuali collegamenti o pulsanti a destra di "centro esterno" non funzioneranno. Prova il colore di sfondo di "centro esterno" per comprendere la necessità di "overflow: nascosto"


1

Ho trovato una soluzione interessante, stavo realizzando un dispositivo di scorrimento e dovevo centrare i controlli delle diapositive e l'ho fatto e funziona bene. È inoltre possibile aggiungere la posizione relativa al genitore e spostare la posizione del figlio in verticale. Dai un'occhiata 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

Fare display:table;e impostare marginsuauto

Bit importante di codice:

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

Non importa quanti elementi hai ora si allinea automaticamente al centro

Esempio nello snippet di codice:


0

Temo che l'unico modo per farlo senza specificare esplicitamente la larghezza sia usare le tabelle (gasp).


5
riformulato: se non vuoi passare l'ora successiva a provare tutti i tipi di combinazione di CSS, DIV nidificati e browser, vai direttamente alle tabelle.
Eduardo Molteni,

Le tabelle non sono progettate per essere utilizzate come elementi di design. Questo è un cattivo stile.
Sebi2020,

0

Correzione scadente, ma funziona ...

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

Correzione semplice che funziona nei vecchi browser (ma utilizza le tabelle e richiede l'impostazione di un'altezza):

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

}

usa span invece dei div interni

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

0

So che questa domanda è vecchia, ma ci sto provando. Molto simile alla risposta di Bobince ma con un esempio di codice funzionante.

Trasforma ogni prodotto in un blocco in linea. Centra il contenuto del contenitore. Fatto.

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>

Vedi anche: Centra i blocchi inline con larghezza dinamica in CSS


Questa risposta non fornisce già la stessa soluzione? stackoverflow.com/a/284064/547733
Maxime Rossini,

1
hai ragione, madmox! Non è così robusto però. Inoltre, mi rendo conto che l'impostazione dell'allineamento del testo su sinistra o destra significa che non funzionerà mai su un sito con traduzioni che includono il passaggio dall'ordine di lettura da sinistra a destra a destra a sinistra. text-align serve per allineare il testo, non gli elementi. Idealmente nel prossimo futuro dipenderemo dal display: flessibilità per questo genere di cose.
Wray Bowling

0

Questo è un modo per centrare qualsiasi cosa all'interno di un div senza conoscere la larghezza interna degli elementi.

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

-1

la mia soluzione era:

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

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

-7

aggiungi questo css alla tua classe product_container

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

La domanda dice specificamente "senza larghezza"
Dez Udezue,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.