¿Cómo puedo hacer un div no más grande que su contenido?

2071

Tengo un diseño similar a:

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

Me gustaría que el divsolo se expanda tanto como tablesea ​​posible.

Peter Mortensen
fuente
90
el efecto se llama "shrinkwrapping", y como respondida hay un par de maneras de hacer esto (float, en línea, min / max-ancho) todos los cuales tienen efectos secundarios para elegir
annakata

Respuestas:

2426

La solución es configurar su diva display: inline-block.

usuario473598
fuente
239
@ leif81 Puede usar una spano una divo ulcualquier otra cosa, la parte importante es que el contenedor que le gustaría tener un ancho mínimo tenga la propiedad CSSdisplay: inline-block
miahelf
10
si alguien se pregunta: uno puede centrar al padre de la tabla configurando "text-align: center" en su padre y "text-align: left" en él (por ejemplo, <body style = "text-align: center"> < span style = "text-align: left; display: inline-block;"> <table> ... </table> </span> </body>)
bernstein
12
Para mí no funciona en Chrome con span, pero funciona utilizando espacios en blanco: nowrap;
albanx
57
Tenga en cuenta que una vez que haya display: inline-blockconfigurado la propiedad margin: 0 auto;, no funcionará como se esperaba. En ese caso, si el contenedor principal tiene, text-align: center;entonces el inline-blockelemento estará centrado horizontalmente.
Savas Vedova
12
inline-blockNO funcionó para mí, pero sí inline-flex.
mareoraft
331

Desea un elemento de bloque que tenga lo que CSS llama ancho de contracción y la especificación no proporciona una forma bendecida de obtener tal cosa. En CSS2, reducir para ajustar no es un objetivo, sino que significa lidiar con una situación en la que el navegador "tiene" que obtener un ancho de la nada. Esas situaciones son:

  • flotador
  • elemento absolutamente posicionado
  • elemento de bloque en línea
  • elemento de tabla

cuando no hay ancho especificado. Escuché que piensan en agregar lo que quieres en CSS3. Por ahora, hazte con uno de los anteriores.

La decisión de no exponer la función directamente puede parecer extraña, pero hay una buena razón. Es caro. Reducir para ajustar significa formatear al menos dos veces: no puede comenzar a formatear un elemento hasta que sepa su ancho, y no puede calcular el ancho sin pasar por todo el contenido. Además, no se necesita un elemento de contracción tan a menudo como se pueda pensar. ¿Por qué necesitas div extra alrededor de tu mesa? Tal vez el título de la tabla es todo lo que necesitas.

buti-oxa
fuente
34
Yo diría que inline-blockes exactamente para esto y resuelve el problema perfectamente.
miahelf
66
Creo que están agregando CSS4 y seríacontent-box, max-content, min-content, available, fit-content, auto
Muhammad Umer
44
La nueva fit-contentpalabra clave (que no existía cuando se escribió esta respuesta por primera vez, y aún no es totalmente compatible ) le permite aplicar explícitamente el tamaño de "reducir para ajustar" a un elemento, eliminando la necesidad de cualquiera de los hacks sugeridos aquí si está tiene la suerte de solo apuntar a los navegadores con soporte. +1 no obstante; estos siguen siendo útiles por ahora!
Mark Amery
floatHice lo que necesitaba hacer!
nipunasudha
228

Creo que usando

display: inline-block;

funcionaría, sin embargo, no estoy seguro de la compatibilidad del navegador.


Otra solución sería envolverlo diven otro div(si desea mantener el comportamiento de bloqueo):

HTML:

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

CSS:

.yourdiv
{
    display: inline;
}
mbillard
fuente
23
Para responder a la pregunta de compatibilidad del navegador: esto no funcionará con IE7 / 8 en elementos DIV. Tienes que usar elementos SPAN.
Matt Brock
@feeela: siempre pongo un * delante del zoom, por ejemplo *display: inline; *zoom: 1;. No he probado esta situación en particular, pero siempre he encontrado en el pasado que el hack hasLayout solo es necesario para IE7, o IE8 en modo IE7 (¡o IE8 en peculiaridades!).
robocat el
@robocat Sí, de hecho, es una solución alternativa haber inline-blockhabilitado en IE 7.
feeela
@feela: ¡tu comentario no tiene sentido para mí! Estaba sugiriendo poner * delante del zoom también Ie * zoom: 1;
robocat
44
Explique por qué funciona su solución de bloqueo en línea.
HelloWorldNoMore
220

display: inline-block agrega un margen extra a su elemento.

Yo recomendaría esto:

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

Bonificación: ahora también puede centrar fácilmente esa nueva fantasía #elementsimplemente agregando margin: 0 auto.

Salman von Abbas
fuente
14
+1: esta es la mejor y más limpia solución para navegadores modernos que también permite que el elemento se centre. position: absoluteEs necesario un comentario condicional para <IE8.
Uınbɐɥs
21
Especificar display: inline-blockno agrega ningún margen. Pero CSS maneja espacios en blanco que se mostrarán entre elementos en línea.
feeela
Explique por qué su solución de visualización: la tabla funciona.
HelloWorldNoMore
2
inline-block hace que el elemento sea imposible de colocar en su elemento primario (por ejemplo, si hay una alineación de texto: centro, no se puede pegar a la izquierda) pantalla: la tabla es perfecta :)
FlorianB
1
Este es el camino a seguir si tieneposition: absolute
m4heshd
90

Puedes probar fit-content(CSS3):

div {
  width: fit-content; 
  /* To adjust the height as well */ 
  height: fit-content;
}
Vitalii Fedorenko
fuente
1
@BartlomiejSkwira ¿Algún sustituto que trabaje en IE o Eclipse? otra solución como bloque en línea no funciona para mí .. \
DAVIDBALAS1
8
Esto tiene demasiado sentido, por supuesto, carece de soporte.
Sava B.
86

Lo que funciona para mí es:

display: table;

en el div. (Probado en Firefox y Google Chrome ).

Sony Santos
fuente
44
Sí, especialmente si necesitas centrar con margen: automático. Ese caso inline-block no es la solución.
Zsolt Szatmari
1
También tenga en cuenta que si desea que el relleno funcione dentro de este elemento, debe establecer el border-collapse: separate;estilo. Es predeterminado en muchos navegadores, pero a menudo los marcos css como bootstrap restablecen su valor a collapse.
Ruslan Stelmachenko
Probado en MSIE 6 en un teléfono con Windows Mobile 6.5 fabricado en 2009: se degrada con gracia a un div de ancho completo (que es poco probable que sea un problema en un teléfono). Si alguien usa una versión de Internet Explorer inferior a 8 en un escritorio, está usando un sistema operativo no compatible (IE6 vino con XP, IE7 vino con Vista); Los redirigiría a una página que les diga que actualicen a GNU / Linux si desean un uso seguro y continuo de Internet en esa máquina.
Silas S. Brown
85

Hay dos mejores soluciones

  1. display: inline-block;

    O

  2. display: table;

De estos dos display:table;es mejor, porque display: inline-block;agrega un margen extra.

Para display:inline-block;que pueda utilizar el método de margen negativo para arreglar el espacio extra

Shuvo Habib
fuente
2
¿Te importa explicar por qué display:tablees mejor?
Nathaniel Ford el
1
Para la visualización: bloque en línea, debe usar el método de margen negativo para corregir el espaciado adicional.
Shuvo Habib
8
@NathanielFord, display:tabledeja el elemento en el contexto de formato de Bloque, para que pueda controlar su posición con márgenes, etc., como de costumbre. display:-inline-*, por otro lado, coloca el elemento en contexto de formato en línea, haciendo que el navegador cree el contenedor de bloques anónimo a su alrededor, que contiene el cuadro de línea con la configuración heredada de fuente / altura de línea, e inserta el bloque en ese cuadro de línea (alineando verticalmente por línea de base por defecto). Esto implica más "magia" y, por lo tanto, posibles sorpresas.
Ilya Streltsyn
43

Sin saber en qué contexto esta aparecerá, pero creo que el establecimiento de estilo CSS float, ya sea lefto righttendrá este efecto. Por otro lado, también tendrá otros efectos secundarios, como permitir que el texto flote a su alrededor.

Sin embargo, corríjame si estoy equivocado, no estoy 100% seguro y actualmente no puedo probarlo yo mismo.

falstro
fuente
1
Sí, en CSS 2.1. (CSS2.0 haría que el flotante sea de ancho completo, pero solo IE5 / Mac realmente lo hace). Las tablas y los flotantes son los únicos tipos de visualización que pueden reducir su contenido.
bobince
41

La respuesta a su pregunta está en el futuro, mi amigo ...

a saber, "intrínseco" viene con la última actualización de CSS3

width: intrinsic;

desafortunadamente IE está atrasado con él, así que aún no lo admite

Más información al respecto: CSS Intrinsic & Extrinsic Sizing Module Level 3 y ¿puedo usarlo? : Dimensionamiento intrínseco y extrínseco .

Por ahora tienes que estar satisfecho <span>o <div>configurado

display: inline-block;
troyano
fuente
12
intrinsiccomo un valor no es estándar. De hecho lo es width: max-content. Vea la página MDN sobre eso o el borrador ya vinculado.
Maryisdead
34

Una solución compatible con CSS2 es usar:

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

También puede flotar su div, lo que lo forzará lo más pequeño posible, pero necesitará usar una corrección clara si algo dentro de su div está flotando:

.my-div
{
    float: left;
}
Soviut
fuente
3
Debería. ¿Qué doctype estás usando?
Soviut
34
width:1px;
white-space: nowrap;

funciona bien para mí :)

Daft Wullie
fuente
Pero, de nuevo, mi caso era texto dentro de un div, y no una tabla como el OP.
Rui Marques
para el control deslizante ui de jquery esto es mejor porque no es necesario establecer el ancho del elemento de contenido
CoffeJunky
26

De acuerdo, en muchos casos, incluso no es necesario hacer nada, ya que por defecto div lo ha hecho heighty widthcomo automático, pero si no es tu caso, aplicar la inline-blockpantalla funcionará para ti ... mira el código que creo para ti y listo Qué estás buscando:

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>

Alireza
fuente
19

Puede hacerlo simplemente usando display: inline;(o white-space: nowrap;).

Espero que encuentres esto útil.

miksiii
fuente
18

Puede usar inline-blockcomo @ user473598, pero tenga cuidado con los navegadores más antiguos.

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

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

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

Mozilla no admite bloqueo en línea en absoluto, pero tienen lo -moz-inline-stackque es casi lo mismo

Algunos inline-blockatributos de visualización alrededor del navegador : https://css-tricks.com/snippets/css/cross-browser-inline-block/

Puede ver algunas pruebas con este atributo en: https://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/

RPichioli
fuente
1
¿De qué estás hablando? Mozilla Firefox es compatible inline-blockdesde 3.0 (2008). Fuente: developer.mozilla.org/en-US/docs/Web/CSS/…
Chazy Chaz
18

Simplemente ponga un estilo en su archivo CSS

div { 
    width: fit-content; 
}
Hamza
fuente
1
No creo que esta sea una opción compatible con varios navegadores.
David Rector
2
Actualmente no funciona en Edge: caniuse.com/#search=fit-content
molsson
Puede usar -moz-fit-contentpara FF, presumiblemente los otros prefijos de proveedor permitirán su propio ...
Benj
1
Esto es lo mismo que la respuesta de Vitalii Fedorenko
mfluehr
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>

Sé que a la gente no le gustan las tablas a veces, pero debo decirte que probé los hacks en línea css, y funcionaron en algunos divs pero en otros no, así que, en realidad, fue más fácil encerrar el div en expansión una tabla ... y ... puede tener o no la propiedad en línea y aún así la tabla es la que va a contener el ancho total del contenido. =)

Eduardo
fuente
2
No es la forma "adecuada", pero IE6 / 7/8 a menudo simplemente no juega bien cuando las cosas se complican un poco, así que entiendo totalmente por qué lo harías de esta manera. Tienes mi voto positivo.
Craigo
Haría esto, pero tengo que rodear cada cuadro de entrada, así que eso es un montón de HTML extra.
NickSoft
15

Una demostración de trabajo está aquí

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

Abrar Jahin
fuente
13

Mi solución CSS3 flexbox en dos sabores: el de arriba se comporta como un tramo y el de abajo se comporta como un div, tomando todo el ancho con la ayuda de un contenedor. Sus clases son "top", "bottom" y "bottomwrapper" respectivamente.

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.

Lloyd Dominic
fuente
felicitaciones por display: inline-flex;. Por cierto, esto funciona sin prefijo para Chrome 62, Firefox 57 y Safari 11
Horacio
12
<div class="parentDiv" style="display:inline-block">
    // HTML elements
</div>

Esto hará que el ancho div principal sea igual al ancho del elemento más grande.

Jaimin Dave
fuente
¿Hay alguna manera de que pueda aplicar esto solo para el tamaño vertical para minimizar y mantener horizontal grande?
Gobliins
12

Tratar display: inline-block;. Para que sea compatible con varios navegadores, utilice el siguiente código CSS.

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>

James
fuente
11

Al manipular Firebug, encontré el valor de la propiedad -moz-fit-contentque hace exactamente lo que el OP quería y podría usarse de la siguiente manera:

width: -moz-fit-content;

Aunque solo funciona en Firefox, no pude encontrar ningún equivalente para otros navegadores como Chrome.

Hamed Momeni
fuente
A partir de enero de 2017, IE (todas las versiones, Edge y dispositivos móviles incluidos) y Opera Mini no tienen soporte para fit-content. Firefox solo admite ancho. Otros navegadores lo soportan bien.
Gavin el
11

Puedes probar este código. Sigue el código en la sección 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>

Showrin Barua
fuente
7

He resuelto un problema similar (donde no quería usar display: inline-blockporque el elemento estaba centrado) agregando una spanetiqueta dentro de la divetiqueta y moviendo el formato CSS de la divetiqueta externa a la nueva spanetiqueta interna . Simplemente lanzar esto como otra idea alternativa si display: inline blockno es una respuesta adecuada para usted.

Jessica Brown
fuente
7

Podemos usar cualquiera de las dos formas en el divelemento:

display: table;

o,

display: inline-block; 

Prefiero usar display: table;, porque maneja, todos los espacios adicionales por sí solo. Mientras que display: inline-blocknecesita un poco de espacio extra de fijación.

Principiante
fuente
6
div{
  width:auto;
  height:auto;
}
AJchandu
fuente
Esto no funcionará si div contiene elementos en línea (o bloque en línea) y tienen diferente tamaño de fuente y altura de línea que el div en sí.
citasBro
5

Si tiene contenedores que rompen líneas, después de horas buscando una buena solución CSS y no encontrando ninguna, ahora uso jQuery en su lugar:

$('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>

cregox
fuente
Esto está visiblemente roto en el fragmento para mí en Chrome; Al hacer clic en el botón de reparación por segunda vez, se obtienen resultados diferentes a hacer clic en él la primera vez.
Mark Amery
@ MarkAmery en mi Mac. Lo probé en Chrome, Safari y Firefox y todo está bien: sin errores visibles, nada en la consola, comportamiento consistente. tal vez es algo con windows ...
cregox
5

Revisado (funciona si tiene varios hijos): puede usar jQuery (Mire el enlace JSFiddle)

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


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

No olvides incluir el jQuery ...

Mira el JSfiddle aquí

Bondsmith
fuente
Esto se rompe si su div tiene varios hijos; simplemente establece el ancho div al del primer hijo.
Mark Amery
@ MarkAmery En primer lugar, antes de darle un voto negativo, lea la pregunta detenidamente, pidieron un hijo. Si tiene curiosidad sobre cómo se puede hacer con varios niños, vea la respuesta revisada.
Bondsmith
4

Lo intenté div.classname{display:table-cell;}y funcionó!

UnLoCo
fuente