Como posso fazer uma div não maior que seu conteúdo?

2071

Eu tenho um layout semelhante a:

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

Eu gostaria que a divexpansão fosse tão ampla quanto possível table.

Peter Mortensen
fonte
90
o efeito é chamado de "shrinkwrapping", e como respondida há um par de maneiras de fazer isso (float, inline, min / max-largura) os quais têm efeitos colaterais para escolher
annakata

Respostas:

2426

A solução é definir o seu divpara display: inline-block.

user473598
fonte
239
@ leif81 Você pode usar um spanou uma divou ulou qualquer outra coisa, a parte importante é para o recipiente que você gostaria de ser de largura mínima têm a propriedade CSSdisplay: inline-block
miahelf
10
se alguém se perguntar: é possível centralizar o pai da tabela definindo "text-align: center" em seu pai e "text-align: left" nele (por exemplo, <body style = "text-align: center"> < span style = "text-align: left; display: inline-block;"> <table> ... </ table> </ span> </ body>)
Bernstein
12
Ele não funciona no chrome para mim com extensão, mas funciona usando espaço em branco: nowrap;
Albanx 07/07
57
Observe que, depois de display: inline-blockdefinir a propriedade margin: 0 auto;, não funcionará conforme o esperado. Nesse caso, se o contêiner pai tiver text-align: center;, o inline-blockelemento será centralizado horizontalmente.
Savas Vedova
12
inline-blocknão funcionou para mim, mas inline-flexfez.
Mareoraft # 24/15
331

Você deseja um elemento de bloco que possua o que o CSS chama de largura encolher para ajustar e a especificação não fornece uma maneira abençoada de obter uma coisa dessas. No CSS2, encolher para ajustar não é um objetivo, mas significa lidar com uma situação em que o navegador "precisa" obter uma largura do nada. Essas situações são:

  • flutuador
  • elemento absolutamente posicionado
  • elemento de bloco embutido
  • elemento da tabela

quando não há largura especificada. Ouvi dizer que eles pensam em adicionar o que você deseja no CSS3. Por enquanto, convide-se com uma das opções acima.

A decisão de não expor o recurso diretamente pode parecer estranha, mas há um bom motivo. É caro. Reduzir para ajustar significa formatar pelo menos duas vezes: você não pode começar a formatar um elemento até conhecer sua largura e não pode calcular a largura sem passar por todo o conteúdo. Além disso, não é necessário o elemento encolher para ajustar com a frequência que se pensa. Por que você precisa de div extra em torno da sua mesa? Talvez a legenda da tabela seja tudo que você precisa.

buti-oxa
fonte
34
Eu diria que inline-blocké exatamente para isso e resolve o problema perfeitamente.
miahelf
6
eu acho que eles estão adicionando em css4 e seriacontent-box, max-content, min-content, available, fit-content, auto
Muhammad Umer
4
A nova fit-contentpalavra-chave (que não existe quando esta resposta foi escrita pela primeira vez e ainda não é totalmente suportada ) permite aplicar explicitamente o dimensionamento "shrink-to-fit" a um elemento, eliminando a necessidade de qualquer um dos hacks sugeridos aqui, se você sorte o suficiente para segmentar apenas navegadores com suporte. +1, no entanto; estes permanecem úteis por enquanto!
Mark Amery
floatfiz o que eu precisava fazer!
Nipunasudha 15/0318
228

Eu acho que usando

display: inline-block;

funcionaria, no entanto, não tenho certeza sobre a compatibilidade do navegador.


Outra solução seria envolver o seu divem outro div(se você quiser manter o comportamento do bloco):

HTML:

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

CSS:

.yourdiv
{
    display: inline;
}
mbillard
fonte
23
Para responder à pergunta de compatibilidade do navegador: isso não funcionará com o IE7 / 8 em elementos DIV. Você precisa usar elementos SPAN.
Matt Brock
@feeela - eu sempre coloco um * na frente do zoom, por exemplo *display: inline; *zoom: 1;. Não testei para essa situação específica, mas sempre achei no passado que o hack hasLayout é necessário apenas para o IE7 ou IE8 no modo IE7 (ou o IE8 em peculiaridades!).
robocat
@robocat Sim, é realmente uma solução para ter inline-blockhabilitado no IE 7.
feeela
@feela - seu comentário não faz sentido para mim! Eu estava sugerindo colocar * na frente do zoom também Ie * zoom: 1;
robocat
4
Explique por que sua solução de bloco embutido funciona.
precisa
220

display: inline-block adiciona uma margem extra ao seu elemento.

Eu recomendaria o seguinte:

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

Bônus: agora você também pode centralizar facilmente esse novo chique #elementapenas adicionando margin: 0 auto.

Salman von Abbas
fonte
14
+1 - Esta é a melhor e mais limpa solução para navegadores modernos que também permite que o elemento seja centralizado. Um comentário condicional com position: absoluteé necessário para <IE8.
uınbɐɥs
21
A especificação display: inline-blocknão adiciona margens. Mas o CSS manipula o espaço em branco a ser mostrado entre os elementos embutidos.
Fee12
Por favor, explique por que sua solução de display: table funciona.
precisa
2
inline-block torna o elemento impossível de posição no seu pai (por exemplo, se há um text-align: center você não pode obtê-lo a ficar à esquerda) display: table é perfeito :)
FlorianB
1
Este é o caminho a percorrer se você temposition: absolute
m4heshd
90

Você pode tentar fit-content(CSS3):

div {
  width: fit-content; 
  /* To adjust the height as well */ 
  height: fit-content;
}
Vitalii Fedorenko
fonte
1
@BartlomiejSkwira Algum substituto trabalhando no IE ou no Eclipse? outra solução como inline-bloco não está funcionando para mim .. \
DAVIDBALAS1 9/16
8
Isso faz muito sentido, é claro que falta apoio.
Sava B.
86

O que funciona para mim é:

display: table;

no div. (Testado no Firefox e Google Chrome ).

Sony Santos
fonte
4
Sim, especialmente se você precisar centralizar com a margem: auto. Nesse caso, o bloco embutido não é a solução.
Zsolt Szatmari
1
Observe também que, se você quiser trabalhar com preenchimento dentro deste elemento, deverá definir o border-collapse: separate;estilo. É o padrão em muitos navegadores, mas geralmente as estruturas CSS, como a inicialização, redefinem o valor para collapse.
Ruslan Stelmachenko
Testado no MSIE 6 em um telefone Windows Mobile 6.5 fabricado em 2009: degrada-se normalmente para um div de largura total (o que é improvável que seja um problema no telefone). Se alguém estiver usando uma versão do Internet Explorer menor que 8 em uma área de trabalho, estará usando um sistema operacional não suportado (o IE6 veio com o XP, o IE7 veio com o Vista); Eu os redirecionaria para uma página dizendo para atualizar para o GNU / Linux se eles desejassem um uso seguro e contínuo da Internet nessa máquina.
Silas S. Brown
85

Existem duas soluções melhores

  1. display: inline-block;

    OU

  2. display: table;

Destes dois display:table;é melhor, porque display: inline-block;adiciona uma margem extra.

Para display:inline-block;você poder usar o método de margem negativa para corrigir o espaço extra

Shuvo Habib
fonte
2
Você se importa de explicar por que display:tableé melhor?
Nathaniel Ford
1
Para exibição: bloco em linha, é necessário usar o método de margem negativa para corrigir o espaçamento extra.
Shuvo Habib
8
@NathanielFord, display:tabledeixa o elemento no contexto de formatação do bloco, para que você possa controlar sua posição com margens etc., como de costume. display:-inline-*, por outro lado, coloca o elemento no contexto de formatação Inline, fazendo com que o navegador crie o invólucro de bloco anônimo ao seu redor, contendo a caixa de linha com as configurações herdadas de fonte / altura da linha e insira o bloco nessa caixa de linha (alinhando verticalmente por linha de base por padrão). Isso envolve mais "mágica" e, portanto, possíveis surpresas.
Ilya Streltsyn
43

Sem saber em que contexto isso vai aparecer, mas acredito que a propriedade de estilo CSS floatquer leftou rightvai ter esse efeito. Por outro lado, também terá outros efeitos colaterais, como permitir que o texto flutue ao redor dele.

Corrija-me se estiver errado, porém, não tenho 100% de certeza e, atualmente, não posso testá-lo.

falstro
fonte
1
Sim, no CSS 2.1. (CSS2.0 tornaria o float de largura total, mas apenas o IE5 / Mac realmente faz isso). Tabelas e carros alegóricos são os únicos tipos de exibição que podem encolher para ajustar seu conteúdo.
bobince
41

A resposta para sua pergunta está no futuro, meu amigo ...

ou seja, "intrínseco" está chegando com a atualização CSS3 mais recente

width: intrinsic;

infelizmente, o IE está por trás disso, por isso ainda não o suporta

Saiba mais: Módulo de dimensionamento intrínseco e extrínseco CSS nível 3 e posso usar? : Dimensão intrínseca e extrínseca .

Por enquanto, você precisa estar satisfeito <span>ou <div>definido como

display: inline-block;
trojan
fonte
12
intrinsiccomo um valor não é padrão. Na verdade é width: max-content. Consulte a página MDN nesse ou no rascunho já vinculado.
Maryisdead 20/05
34

Uma solução compatível com CSS2 é usar:

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

Você também pode fazer a flutuação da sua div, que a forçará o menor possível, mas será necessário usar um clearfix se algo dentro da sua div estiver flutuando:

.my-div
{
    float: left;
}
Soviut
fonte
3
Deveria. Qual tipo de documento você está usando?
Soviut 18/10/09
34
width:1px;
white-space: nowrap;

funciona bem para mim :)

Daft Wullie
fonte
Mas, novamente, meu caso era texto dentro de uma div e não uma tabela como o OP.
Rui Marques
para o controle deslizante ui de jquery este é greate porque u não precisa definir a largura do item de conteúdo
CoffeJunky
26

OK, em muitos casos, você nem precisa fazer nada como por padrão o div heighte widthcomo automático, mas se não for o seu caso, a aplicação de inline-blockexibição funcionará para você ... veja o código que eu criei para você e faça o que você está procurando:

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

Isso foi mencionado nos comentários e é difícil de encontrar em uma das respostas:

Se você estiver usando display: flexpor qualquer motivo, poderá usar:

div {
    display: inline-flex;
}

Isso também é amplamente suportado nos navegadores.

youngrrrr
fonte
Isso é o que eu precisava quando já estava usandodisplay: flex;
Denny
19

Você pode fazer isso simplesmente usando display: inline;(ou white-space: nowrap;).

Espero que você ache isso útil.

miksiii
fonte
18

Você pode usar inline-blockcomo @ user473598, mas cuidado com navegadores mais antigos ..

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

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

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

O Mozilla não suporta bloco inline, mas eles têm -moz-inline-stacko mesmo

Alguns navegadores em torno do inline-blockatributo de exibição: https://css-tricks.com/snippets/css/cross-browser-inline-block/

Você pode ver alguns testes com este atributo em: https://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/

RPichioli
fonte
1
Do que você está falando? O Mozilla Firefox suporta inline-blockdesde 3.0 (2008). Fonte: developer.mozilla.org/pt-BR/docs/Web/CSS/…
Chazy Chaz
18

Basta colocar um estilo no seu arquivo CSS

div { 
    width: fit-content; 
}
Hamza
fonte
1
Não acho que essa seja uma opção compatível com vários navegadores.
David Rector
2
Atualmente não funciona no Edge: caniuse.com/#search=fit-content
molsson
Você pode usar -moz-fit-contentpara FF, presumivelmente, os outros prefixos de fornecedores permitirá que o seu próprio ...
Benj
1
Este é o mesmo que a resposta 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>

Eu sei que as pessoas às vezes não gostam de tabelas, mas tenho que dizer, tentei os hacks em linha do css, e eles meio que funcionavam em alguns divs, mas em outros não, então era realmente mais fácil incluir o div em expansão uma tabela ... e ... ela pode ter ou não a propriedade inline e ainda assim é a tabela que manterá a largura total do conteúdo. =)

Edward
fonte
2
Não é o caminho "adequado", mas o IE6 / 7/8 geralmente não funciona bem quando as coisas ficam um pouco complicadas, então eu entendo perfeitamente por que você faria dessa maneira. Você conseguiu meu voto.
Craigo 27/03
Eu faria isso, mas tenho que cercar cada caixa de entrada, para que haja muito html extra.
NickSoft
15

Uma demonstração de trabalho está aqui-

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

Minha solução flexbox CSS3 em dois sabores: o da parte superior se comporta como uma extensão e o da parte inferior se comporta como uma div, ocupando toda a largura com a ajuda de um invólucro. Suas classes são "top", "bottom" e "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
fonte
parabéns por display: inline-flex;. BTW isso funciona sem prefixo para o Chrome 62, firefox 57 e safari 11
Horacio
12
<div class="parentDiv" style="display:inline-block">
    // HTML elements
</div>

Isso tornará a largura div principal igual à maior largura do elemento.

Jaimin Dave
fonte
existe uma maneira de aplicar isso apenas ao tamanho vertical para minimizar e manter a horizontal grande?
Gobliins 22/02
12

Tente display: inline-block;. Para que seja compatível com vários navegadores, use o código css abaixo.

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

Adulterando o Firebug, encontrei o valor da propriedade -moz-fit-contentque exatamente faz o que o OP queria e poderia ser usado da seguinte maneira:

width: -moz-fit-content;

Embora funcione apenas no Firefox, não consegui encontrar nenhum equivalente para outros navegadores, como o Chrome.

Hamed Momeni
fonte
A partir de janeiro de 2017, o IE (todas as versões, Edge e móvel incluído) e o Opera Mini não tinham suporte fit-content. O Firefox suporta apenas largura. Outros navegadores suportam bem.
Gavin
11

Você pode tentar esse código. Siga o código na seção 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
fonte
7

Resolvi um problema semelhante (onde não queria usar display: inline-blockporque o item estava centralizado) adicionando uma spanmarca dentro da divmarca e movendo a formatação CSS da divmarca externa para a nova spanmarca interna . Apenas jogar isso lá fora como outra idéia alternativa, se display: inline blocknão for uma resposta adequada para você.

Jessica Brown
fonte
7

Podemos usar qualquer uma das duas maneiras no divelemento:

display: table;

ou,

display: inline-block; 

Eu prefiro usar display: table;, porque ele lida com todos os espaços extras por conta própria. Embora display: inline-blockprecise de alguma correção de espaço extra.

Novato
fonte
6
div{
  width:auto;
  height:auto;
}
AJchandu
fonte
Isso não funcionará se div contiver elementos inline (ou bloco inline) e eles tiverem tamanho de fonte e altura de linha diferentes do que o próprio div.
quotesBro
5

Se você tiver contêineres quebrando linhas, depois de horas procurando uma boa solução CSS e não encontrando nenhuma, agora uso o 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>

cregox
fonte
Isso está visivelmente quebrado no snippet para mim no Chrome; clicar no botão corrigir uma segunda vez produz resultados diferentes para clicar nele pela primeira vez.
Mark Amery
@ MarkAmery no meu mac Acabei de experimentar no chrome, safari e firefox e está tudo bem: sem erros visíveis, nada no console, comportamento consistente. talvez seja algo com janelas ...
cregox
5

Revisado (funciona se você tiver vários filhos): Você pode usar o jQuery (veja o link do JSFiddle)

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


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

Não se esqueça de incluir o jQuery ...

Veja o JSfiddle aqui

Bondsmith
fonte
Isso é interrompido se sua div tiver vários filhos; simplesmente define a largura da div para a do primeiro filho.
Mark Amery
@ MarkAmery Antes de tudo, antes de você dar um voto negativo, leia a pergunta com atenção, eles pediram um filho. Se você está realmente curioso para saber como isso pode ser feito com vários filhos, veja a resposta revisada.
Bondsmith
4

Eu tentei div.classname{display:table-cell;}e funcionou!

UnLoCo
fonte