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.


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.


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.


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

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.


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


86

O que funciona para mim é:

display: table;

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


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


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.


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;

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

3
Deveria. Qual tipo de documento você está usando?
— Soviut 18/10/09

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

funciona bem para mim :)


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>



19

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

Espero que você ache isso útil.


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/


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


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>


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.


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.


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>


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.


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>


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


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.


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

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>


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


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!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.