Come posso fare un div non più grande del suo contenuto?


2071

Ho un layout simile a:

<div>
    <table>
    </table>
</div>

Vorrei che il divsolo si espandesse fino a tablediventare il mio .


90
l'effetto si chiama "restringimento" e, come detto, ci sono un paio di modi per farlo (float, inline, min / max-width) che hanno tutti effetti collaterali tra cui scegliere
annakata

Risposte:


2426

La soluzione è quella di impostare il diva display: inline-block.


239
@ leif81 Puoi usare a spano a divo ulqualsiasi altra cosa, la parte importante è per il contenitore che vorresti avere la larghezza minima avere la proprietà CSSdisplay: inline-block
miahelf

10
se qualcuno si chiede: si può quindi centrare il genitore della tabella impostando "text-align: center" sul suo genitore e "text-align: left" su di esso (es. <body style = "text-align: center"> < span style = "text-align: left; display: inline-block;"> <table> ... </table> </span> </body>)
bernstein

12
Non funziona su Chrome per me con span, ma funziona usando white-space: nowrap;
albanx,

57
Si prega di notare che una volta display: inline-blockimpostata la proprietà margin: 0 auto;non funzionerà come previsto. In tal caso, se il contenitore padre ha text-align: center;l' inline-blockelemento verrà centrato orizzontalmente.
Savas Vedova,

12
inline-blocknon ha funzionato per me, ma inline-flexDID.
mareoraft,

331

Volete un elemento a blocchi che abbia ciò che CSS chiama larghezza ridotta per adattarsi e le specifiche non forniscono un modo benedetto per ottenere una cosa del genere. In CSS2, il ridimensionamento non è un obiettivo, ma significa affrontare una situazione in cui il browser "deve" ottenere una larghezza dal nulla. Tali situazioni sono:

  • galleggiante
  • elemento assolutamente posizionato
  • elemento inline-block
  • elemento da tavolo

quando non è stata specificata alcuna larghezza. Ho sentito che pensano di aggiungere quello che vuoi in CSS3. Per ora, accontentati di uno dei precedenti.

La decisione di non esporre direttamente la funzionalità può sembrare strana, ma c'è una buona ragione. È costoso. Rimpicciolire significa formattare almeno due volte: non è possibile iniziare a formattare un elemento finché non si conosce la sua larghezza e non è possibile calcolare la larghezza senza passare attraverso l'intero contenuto. Inoltre, non è necessario un elemento termoretraibile ogni volta che si potrebbe pensare. Perché hai bisogno di div extra attorno al tuo tavolo? Forse la didascalia della tabella è tutto ciò che serve.


34
Direi che inline-blockè esattamente destinato a questo e risolve perfettamente il problema.
miahelf

6
penso che stiano aggiungendo in css4 e sarebbecontent-box, max-content, min-content, available, fit-content, auto
Muhammad Umer il

4
La nuova fit-contentparola chiave (non esistente al momento in cui questa risposta è stata scritta per la prima volta e ancora non completamente supportata ) ti consente di applicare esplicitamente il dimensionamento "restringi per adattarlo" a un elemento, eliminando la necessità di uno qualsiasi degli hack suggeriti qui se sei abbastanza fortunato da scegliere come target solo i browser con supporto. +1 comunque; questi rimangono utili per ora!
Mark Amery,

floatfatto quello che dovevo fare!
nipunasudha,

228

Penso che usando

display: inline-block;

funzionerebbe, tuttavia non sono sicuro della compatibilità del browser.


Un'altra soluzione sarebbe quella di avvolgere il tuo divin un altro div(se vuoi mantenere il comportamento del blocco):

HTML:

<div>
    <div class="yourdiv">
        content
    </div>
</div>

CSS:

.yourdiv
{
    display: inline;
}

23
Per rispondere alla domanda di compatibilità del browser: questo non funzionerà con IE7 / 8 sugli elementi DIV. Devi usare gli elementi SPAN.
Matt Brock,

@feeela - Metto sempre un * davanti allo zoom, ad es *display: inline; *zoom: 1;. Non ho testato per questa situazione particolare, ma in passato ho sempre scoperto che l'hack hasLayout è richiesto solo per IE7 o IE8 in modalità IE7 (o IE8 in stranezze!).
robocat,

@robocat Sì, è davvero una soluzione alternativa avere inline-blockabilitato in IE 7.
feeela

@feela - il tuo commento non ha alcun senso per me! Stavo suggerendo di mettere * davanti allo zoom e Ie * zoom: 1;
robocat,

4
Spiega perché la tua soluzione di blocco inline funziona.
HelloWorldNoMore

220

display: inline-block aggiunge un margine extra al tuo elemento.

Consiglierei questo:

#element {
    display: table; /* IE8+ and all other modern browsers */
}

Bonus: ora puoi anche facilmente centrare quella nuova fantasia #elementsemplicemente aggiungendo margin: 0 auto.


14
+1 - Questa è la soluzione migliore e più pulita per i browser moderni che consente anche di centrare l'elemento. È necessario un commento condizionale con position: absolute<IE8.
uınbɐɥs

21
La specifica display: inline-blocknon aggiunge alcun margine. Ma CSS gestisce gli spazi bianchi da mostrare tra gli elementi in linea.
feeela,

Spiega perché la tua soluzione di visualizzazione: table funziona.
HelloWorldNoMore

2
blocco inline rende impossibile posizionare l'elemento nel suo genitore (ad es. se c'è un allineamento del testo: al centro non è possibile farlo aderire a sinistra) display: la tabella è perfetta :)
FlorianB

1
Questa è la strada da percorrere se haiposition: absolute
m4heshd,


86

Ciò che funziona per me è:

display: table;

nel div. (Testato su Firefox e Google Chrome ).


4
Sì, soprattutto se devi centrare con il margine: auto. Questo caso blocco in linea non è la soluzione.
Zsolt Szatmari,

1
Inoltre, se vuoi che il padding funzioni all'interno di questo elemento, devi impostare lo border-collapse: separate;stile. È predefinito in molti browser, ma spesso i framework CSS come Bootstrap ripristinano il valore collapse.
Ruslan Stelmachenko,

Testato su MSIE 6 su un telefono Windows Mobile 6.5 realizzato nel 2009: degrada con grazia fino a un div a tutta larghezza (che è improbabile che sia un problema su un telefono). Se qualcuno utilizza una versione di Internet Explorer inferiore a 8 su un desktop, sta utilizzando un sistema operativo non supportato (IE6 è arrivato con XP, IE7 è arrivato con Vista); Li reindirizzerei a una pagina che dice loro di aggiornare a GNU / Linux se vogliono un uso sicuro e continuo di Internet su quella macchina.
Silas S. Brown,

85

Esistono due soluzioni migliori

  1. display: inline-block;

    O

  2. display: table;

Di questi due display:table;è meglio, perché display: inline-block;aggiunge un margine in più.

Perché display:inline-block;puoi usare il metodo del margine negativo per riparare lo spazio extra


2
Ti dispiace spiegare perché display:tableè meglio?
Nathaniel Ford,

1
Per la visualizzazione: blocco in linea, è necessario utilizzare il metodo del margine negativo per correggere la spaziatura aggiuntiva.
Shuvo Habib,

8
@NathanielFord, display:tablelascia l'elemento nel contesto di formattazione del blocco, in modo da poter controllare la sua posizione con margini ecc. Come al solito. display:-inline-*, d'altra parte, inserisce l'elemento nel contesto di formattazione Inline, facendo in modo che il browser crei attorno a sé il wrapper di blocchi anonimo, contenente la casella di linea con le impostazioni di carattere / altezza linea ereditate e inserisca il blocco nella casella di riga (allineamento per impostazione predefinita in base alla linea di base). Ciò comporta più "magia" e quindi potenziali sorprese.
Ilya Streltsyn l'


43

Non sapendo in quale contesto apparirà, ma credo che la proprietà in stile CSS floatsia lefto rightavrà questo effetto. D'altra parte, avrà anche altri effetti collaterali, come consentire al testo di fluttuare attorno ad esso.

Per favore, correggimi se sbaglio, non sono sicuro al 100% e al momento non posso provarlo da solo.


1
Sì, in CSS 2.1. (CSS2.0 renderebbe il float a tutta larghezza, ma solo IE5 / Mac lo fa effettivamente). Tabelle e float sono gli unici tipi di visualizzazione che possono ridursi per adattarli al loro contenuto.
bobince

41

La risposta alla tua domanda risiede in futuro, amico mio ...

vale a dire "intrinseco" sta arrivando con l'ultimo aggiornamento CSS3

width: intrinsic;

sfortunatamente IE è dietro con esso, quindi non lo supporta ancora

Ulteriori informazioni: Modulo di dimensionamento intrinseco ed estrinseco CSS livello 3 e posso usare? : Dimensionamento intrinseco ed estrinseco .

Per ora devi essere soddisfatto <span>o <div>impostato su

display: inline-block;

12
intrinsiccome valore non è standard. Lo è davvero width: max-content. Vedi la pagina MDN su quella o la bozza già collegata.
Maryisdead,

34

Una soluzione compatibile CSS2 è utilizzare:

.my-div
{
    min-width: 100px;
}

Puoi anche far galleggiare il tuo div che lo forzerà il più piccolo possibile, ma dovrai usare un clearfix se qualcosa all'interno del tuo div sta fluttuando:

.my-div
{
    float: left;
}

3
Dovrebbe. Quale tipo di documento stai usando?
Soviet

34
width:1px;
white-space: nowrap;

funziona bene per me :)


Ma poi il mio caso era il testo all'interno di un div, e non una tabella come l'OP.
Rui Marques,

per il cursore dell'interfaccia utente di jquery, questo è delizioso perché non è necessario impostare la larghezza dell'elemento di contenuto
CoffeJunky

26

OK, in molti casi non devi nemmeno fare nulla come per impostazione predefinita div ha heighte widthcome auto, ma se non è il tuo caso, applicare inline-blockdisplay funzionerà per te ... guarda il codice che creo per te e lo fa quello che cerchi:

div {
  display: inline-block;
}
<div>
  <table>
    <tr>
      <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ultrices feugiat massa sed laoreet. Maecenas et magna egestas, facilisis purus quis, vestibulum nibh.</td>
      <td>Nunc auctor aliquam est ac viverra. Sed enim nisi, feugiat sed accumsan eu, convallis eget felis. Pellentesque consequat eu leo nec pharetra. Aenean interdum enim dapibus diam.</td>
      <td>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi ultrices feugiat massa sed laoreet. Maecenas et magna egestas, facilisis purus quis, vestibulum nibh.</td>
    </tr>
  </table>
</div>



19

Puoi farlo semplicemente usando display: inline;(o white-space: nowrap;).

Spero che lo trovi utile


18

Puoi usare inline-block@ user473598, ma fai attenzione ai browser più vecchi.

/* Your're working with */
display: inline-block;

/* For IE 7 */
zoom: 1;
*display: inline;

/* For Mozilla Firefox < 3.0 */
display:-moz-inline-stack;

Mozilla non supporta affatto il blocco inline, ma hanno quello -moz-inline-stackche è più o meno lo stesso

Alcuni inline-blockattributi del browser intorno al display: https://css-tricks.com/snippets/css/cross-browser-inline-block/

Puoi vedere alcuni test con questo attributo in: https://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/


1
Di cosa stai parlando? Mozilla Firefox supporta inline-blockdal 3.0 (2008). Fonte: developer.mozilla.org/en-US/docs/Web/CSS/…
Chazy Chaz


18
<table cellpadding="0" cellspacing="0" border="0">
    <tr>
        <td>
            <div id="content_lalala">
                this content inside the div being inside a table, needs no inline properties and the table is the one expanding to the content of this div =)
            </div>
        </td>
    </tr>
</table>

So che alle persone non piacciono i tavoli a volte, ma devo dirtelo, ho provato gli hack in linea CSS, e in un certo senso hanno funzionato in alcuni div ma in altri no, quindi, era davvero più semplice racchiudere il div in espansione una tabella ... e ... può avere o meno la proprietà inline e comunque la tabella è quella che conterrà la larghezza totale del contenuto. =)


2
Non è il modo "corretto", ma IE6 / 7/8 spesso non funziona bene quando le cose si complicano un po ', quindi capisco perfettamente perché lo faresti in questo modo. Mi hai dato il mio voto.
Craigo

Lo farei, ma devo circondare ogni singola casella di input, quindi è un sacco di extra HTML.
NickSoft,

15

Una demo funzionante è qui-

.floating-box {
    display:-moz-inline-stack;
    display: inline-block;

    width: fit-content; 
    height: fit-content;

    width: 150px;
    height: 75px;
    margin: 10px;
    border: 3px solid #73AD21;  
}
<h2>The Way is using inline-block</h2>

Supporting elements are also added in CSS.

<div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
   <div class="floating-box">Floating box</div>
</div>


13

La mia soluzione flexbox CSS3 in due versioni: quella in alto si comporta come una campata e quella in basso si comporta come un div, prendendo tutta la larghezza con l'aiuto di un wrapper. Le loro classi sono rispettivamente "top", "bottom" e "bottomwrapper".

body {
    font-family: sans-serif;
}
.top {
    display: -webkit-inline-flex;
    display: inline-flex;
}
.top, .bottom {
    background-color: #3F3;
    border: 2px solid #FA6;
}
/* bottomwrapper will take the rest of the width */
.bottomwrapper {
    display: -webkit-flex;
    display: flex;
}
table {
    border-collapse: collapse;
}
table, th, td {
    width: 280px;
    border: 1px solid #666;
}
th {
    background-color: #282;
    color: #FFF;
}
td {
    color: #444;
}
th, td {
    padding: 0 4px 0 4px;
}
Is this
<div class="top">
	<table>
        <tr>
            <th>OS</th>
            <th>Version</th> 
        </tr>
        <tr>
            <td>OpenBSD</td>
            <td>5.7</td> 
        </tr>
        <tr>
            <td>Windows</td>
            <td>Please upgrade to 10!</td> 
        </tr>
    </table>
</div>
what you are looking for?
<br>
Or may be...
<div class="bottomwrapper">
    <div class="bottom">
    	<table>
            <tr>
                <th>OS</th>
                <th>Version</th> 
            </tr>
            <tr>
                <td>OpenBSD</td>
                <td>5.7</td> 
            </tr>
            <tr>
                <td>Windows</td>
                <td>Please upgrade to 10!</td> 
            </tr>
        </table>
    </div>
</div>
this is what you are looking for.


complimenti per display: inline-flex;. A proposito, questo funziona senza prefisso per Chrome 62, Firefox 57 e Safari 11
Horacio

12
<div class="parentDiv" style="display:inline-block">
    // HTML elements
</div>

Questo renderà la larghezza div principale uguale alla larghezza dell'elemento più grande.


c'è un modo in cui posso applicarlo solo per dimensioni verticali per ridurre al minimo e mantenere orizzontale di grandi dimensioni?
Gobliins,

12

Prova display: inline-block;. Per essere compatibile con più browser, utilizzare il codice css riportato di seguito.

div {
  display: inline-block;
  display:-moz-inline-stack;
  zoom:1;
  *display:inline;
  border-style: solid;
  border-color: #0000ff;
}
<div>
  <table>
    <tr>
      <td>Column1</td>
      <td>Column2</td>
      <td>Column3</td>
    </tr>
  </table>
</div>


11

Manomettendo con Firebug ho trovato il valore della proprietà -moz-fit-contentche fa esattamente ciò che l'OP voleva e poteva essere usato come segue:

width: -moz-fit-content;

Sebbene funzioni solo su Firefox, non sono riuscito a trovare alcun equivalente per altri browser come Chrome.


A partire da gennaio 2017, IE (tutte le versioni, Edge e mobile incluse) e Opera Mini non hanno supporto fit-content. Firefox supporta solo la larghezza. Altri browser lo supportano bene.
Gavin,

11

Puoi provare questo codice. Segui il codice nella sezione CSS.

div {
  display: inline-block;
  padding: 2vw;
  background-color: green;
}

table {
  width: 70vw;
  background-color: white;
}
<div>
    <table border="colapsed">
      <tr>
        <td>Apple</td>
        <td>Banana</td>
        <td>Strawberry</td>
      </tr>
      <tr>
        <td>Apple</td>
        <td>Banana</td>
        <td>Strawberry</td>
      </tr>
      <tr>
        <td>Apple</td>
        <td>Banana</td>
        <td>Strawberry</td>
      </tr>

    </table>
</div>


7

Ho risolto un problema simile (dove non volevo usare display: inline-blockperché l'elemento era centrato) aggiungendo un spantag all'interno del divtag e spostando la formattazione CSS dal divtag esterno al nuovo spantag interno . Basta lanciarlo qui come un'altra idea alternativa se display: inline blocknon è una risposta adatta a te.


7

Possiamo usare uno dei due modi sul div sull'elemento:

display: table;

o,

display: inline-block; 

Preferisco usare display: table;, perché gestisce, tutti gli spazi extra da solo. Mentre ha display: inline-blockbisogno di un po 'di spazio aggiuntivo di fissaggio.


6
div{
  width:auto;
  height:auto;
}

Questo non funzionerà se div contiene elementi inline (o inline-block) e hanno dimensioni del carattere e altezza della linea diverse rispetto al div stesso.
virgolette il

5

Se hai contenitori che spezzano le linee, dopo ore alla ricerca di una buona soluzione CSS e non trovandone nessuna, ora uso jQuery:

$('button').click(function(){

  $('nav ul').each(function(){
    
    $parent = $(this).parent();
    
    $parent.width( $(this).width() );
    
  });
});
nav {
  display: inline-block;
  text-align: left; /* doesn't do anything, unlike some might guess */
}
ul {
  display: inline;
}

/* needed style */
ul {
  padding: 0;
}
body {
  width: 420px;
}

/* just style */
body {
  background: #ddd;
  margin: 1em auto;
}
button {
  display: block;
}
nav {
  background: #bbb;
  margin: 1rem auto;
  padding: 0.5rem;
}
li {
  display: inline-block;
  width: 40px;
  height: 20px;
  border: solid thin #777;
  margin: 4px;
  background: #999;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button>fix</button>

<nav>
  <ul>
    <li>3</li>
    <li>.</li>
    <li>1</li>
    <li>4</li>
  </ul>
</nav>

<nav>
  <ul>
    <li>3</li>
    <li>.</li>
    <li>1</li>
    <li>4</li>
    <li>1</li>
    <li>5</li>
    <li>9</li>
    <li>2</li>
    <li>6</li>
    <li>5</li>
    <li>3</li>
    <li>5</li>
  </ul>
</nav>


Questo è visibilmente rotto nel frammento di Chrome; facendo clic una seconda volta sul pulsante di correzione si ottengono risultati diversi rispetto alla prima selezione.
Mark Amery,

@MarkAmery sul mio Mac L'ho appena provato su Chrome, Safari e Firefox ed è tutto a posto: nessun errore visibile, niente sulla console, comportamento coerente. forse è qualcosa con Windows ...
Cregox,

5

Revisionato (funziona se hai più figli): puoi usare jQuery (guarda il link JSFiddle)

var d= $('div');
var w;


d.children().each(function(){
 w = w + $(this).outerWidth();
 d.css('width', w + 'px')
});

Non dimenticare di includere jQuery ...

Vedi il JSfiddle qui


Questo si interrompe se il tuo div ha più figli; imposta semplicemente la larghezza div a quella del primo figlio.
Mark Amery,

@MarkAmery Prima di tutto, prima di dare un voto negativo, leggi attentamente la domanda, hanno chiesto un figlio. Se sei davvero curioso di sapere come si può fare con più bambini, vedi la risposta rivista.
Bondsmith,

4

Ho provato div.classname{display:table-cell;}e ha funzionato!

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.