Comment puis-je faire un div pas plus grand que son contenu?

2071

J'ai une disposition similaire à:

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

Je souhaiterais que le divne se développe que le plus large possible table.

Peter Mortensen
la source
90
l'effet est appelé "rétrécissement", et comme répondu, il y a deux façons de le faire (float, inline, min / max-width) qui ont toutes des effets secondaires à choisir
annakata

Réponses:

2426

La solution consiste à définir votre divà display: inline-block.

user473598
la source
239
@ leif81 Vous pouvez utiliser un spanou un divou ulou n'importe quoi d'autre, la partie importante est que le conteneur que vous souhaitez avoir une largeur minimale ait la propriété CSSdisplay: inline-block
miahelf
10
si quelqu'un se demande: on peut alors centrer le parent du tableau en mettant "text-align: center" sur son parent et "text-align: left" dessus (par exemple <body style = "text-align: center"> < span style = "text-align: left; display: inline-block;"> <table> ... </table> </span> </body>)
bernstein
12
Cela ne fonctionne pas sur le chrome pour moi avec span, mais fonctionne en utilisant white-space: nowrap;
albanx
57
Veuillez noter qu'une fois que vous avez display: inline-blockdéfini la propriété, le margin: 0 auto;ne fonctionnera pas comme prévu. Dans ce cas, si le conteneur parent a text-align: center;alors l' inline-blockélément sera centré horizontalement.
Savas Vedova
12
inline-blockn'a pas fonctionné pour moi, mais l'a fait inline-flex.
mareoraft
331

Vous voulez un élément de bloc qui a ce que CSS appelle une largeur de rétrécissement pour s'adapter et la spécification ne fournit pas un moyen béni pour obtenir une telle chose. En CSS2, rétrécir pour s'adapter n'est pas un objectif, mais signifie faire face à une situation où le navigateur "doit" obtenir une largeur hors de l'air. Ces situations sont les suivantes:

  • flotte
  • élément absolument positionné
  • élément de bloc en ligne
  • élément de table

lorsqu'aucune largeur n'est spécifiée. J'ai entendu dire qu'ils pensaient ajouter ce que vous voulez dans CSS3. Pour l'instant, contentez-vous de l'une des options ci-dessus.

La décision de ne pas exposer directement la fonctionnalité peut sembler étrange, mais il y a une bonne raison. Il est cher. Rétrécir signifie mettre en forme au moins deux fois: vous ne pouvez pas commencer à mettre en forme un élément tant que vous ne connaissez pas sa largeur, et vous ne pouvez pas calculer la largeur sans parcourir tout le contenu. De plus, on n'a pas besoin d'un élément rétractable pour s'adapter aussi souvent qu'on le pense. Pourquoi avez-vous besoin de div supplémentaires autour de votre table? Peut-être que la légende de table est tout ce dont vous avez besoin.

buti-oxa
la source
34
Je dirais qu'il inline-blockest exactement destiné à cela et résout parfaitement le problème.
moi-même
6
je pense qu'ils ajoutent dans css4 et ce seraitcontent-box, max-content, min-content, available, fit-content, auto
Muhammad Umer
4
Le nouveau fit-contentmot clé (qui n'existait pas lorsque cette réponse a été écrite pour la première fois et qui n'est toujours pas entièrement pris en charge ) vous permet d'appliquer explicitement un dimensionnement "rétréci pour s'adapter" à un élément, supprimant ainsi le besoin de tous les hacks suggérés ici si vous êtes la chance de ne cibler que les navigateurs avec support. +1 néanmoins; ceux-ci restent utiles pour l'instant!
Mark Amery
floata fait ce que je devais faire!
nipunasudha
228

Je pense qu'en utilisant

display: inline-block;

fonctionnerait, mais je ne suis pas sûr de la compatibilité du navigateur.


Une autre solution serait d'envelopper votre divdans un autre div(si vous voulez conserver le comportement de blocage):

HTML:

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

CSS:

.yourdiv
{
    display: inline;
}
mbillard
la source
23
Pour répondre à la question de compatibilité du navigateur: cela ne fonctionnera pas avec IE7 / 8 sur les éléments DIV. Vous devez utiliser des éléments SPAN.
Matt Brock
@feeela - J'ai toujours mis un * devant le zoom par exemple *display: inline; *zoom: 1;. Je n'ai pas testé pour cette situation particulière, mais j'ai toujours trouvé dans le passé que le hack hasLayout n'est requis que pour IE7 ou IE8 en mode IE7 (ou IE8 en bizarreries!).
robocat
@robocat Oui, c'est en effet une solution de contournement pour avoir inline-blockactivé dans IE 7.
feeela
@feela - votre commentaire n'a aucun sens pour moi! Je proposais de mettre * devant le zoom également Ie * zoom: 1;
robocat
4
Veuillez expliquer pourquoi votre solution de blocage en ligne fonctionne.
HelloWorldNoMore
220

display: inline-block ajoute une marge supplémentaire à votre élément.

Je recommanderais ceci:

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

Bonus: vous pouvez désormais facilement centrer cette nouveauté #elementen ajoutant simplement margin: 0 auto.

Salman von Abbas
la source
14
+1 - C'est la solution la meilleure et la plus propre pour les navigateurs modernes qui permet également de centrer l'élément. Un commentaire conditionnel avec position: absoluteest nécessaire pour <IE8.
uınbɐɥs
21
La spécification display: inline-blockn'ajoute aucune marge. Mais CSS gère les espaces à afficher entre les éléments en ligne.
feeela
Veuillez expliquer pourquoi votre solution d'affichage: la table fonctionne.
HelloWorldNoMore
2
inline-block rend l'élément impossible à positionner dans son parent (par exemple s'il y a un text-align: center vous ne pouvez pas le faire coller à gauche) display: table is perfect :)
FlorianB
1
C'est la voie à suivre si vous avezposition: absolute
m4heshd
90

Vous pouvez essayer fit-content(CSS3):

div {
  width: fit-content; 
  /* To adjust the height as well */ 
  height: fit-content;
}
Vitalii Fedorenko
la source
1
@BartlomiejSkwira Tout remplaçant travaillant dans IE ou Eclipse? autre solution car le bloc en ligne ne fonctionne pas pour moi .. \
DAVIDBALAS1
8
Cela a trop de sens, bien sûr, il manque de soutien.
Sava B.
86

Ce qui fonctionne pour moi, c'est:

display: table;

dans le div. (Testé sur Firefox et Google Chrome ).

Sony Santos
la source
4
Oui, surtout si vous avez besoin de centrer avec une marge: automatique. Ce cas, le bloc en ligne n'est pas la solution.
Zsolt Szatmari
1
Notez également que si vous souhaitez que le rembourrage fonctionne à l'intérieur de cet élément, vous devez définir le border-collapse: separate;style. C'est la valeur par défaut dans de nombreux navigateurs, mais souvent les frameworks CSS comme le bootstrap le réinitialisent collapse.
Ruslan Stelmachenko
Testé sur MSIE 6 sur un téléphone Windows Mobile 6.5 fabriqué en 2009: il se dégrade gracieusement en div pleine largeur (ce qui est peu susceptible d'être un problème sur un téléphone). Si quelqu'un utilise une version d'Internet Explorer inférieure à 8 sur un ordinateur de bureau, il utilise un système d'exploitation non pris en charge (IE6 fourni avec XP, IE7 fourni avec Vista); Je les redirigerais vers une page leur disant de passer à GNU / Linux s'ils veulent continuer à utiliser Internet en toute sécurité sur cette machine.
Silas S. Brown
85

Il y a deux meilleures solutions

  1. display: inline-block;

    OU

  2. display: table;

Sur ces deux, display:table;c'est mieux, car display: inline-block;ajoute une marge supplémentaire.

Car display:inline-block;vous pouvez utiliser la méthode de la marge négative pour fixer l'espace supplémentaire

Shuvo Habib
la source
2
Ça vous dérange d'expliquer pourquoi display:tablec'est mieux?
Nathaniel Ford
1
Pour display: inline-block, vous devez utiliser la méthode de la marge négative pour fixer l'espacement supplémentaire.
Shuvo Habib
8
@NathanielFord, display:tablelaisse l'élément dans le contexte de mise en forme du bloc, vous pouvez donc contrôler sa position avec des marges, etc. comme d'habitude. display:-inline-*, d'autre part, place l'élément dans le contexte de mise en forme en ligne, ce qui oblige le navigateur à créer un wrapper de bloc anonyme autour de lui, contenant la zone de ligne avec les paramètres hérités de police / hauteur de ligne et insère le bloc dans cette zone de ligne (alignement verticalement par ligne de base par défaut). Cela implique plus de «magie» et donc des surprises potentielles.
Ilya Streltsyn
43

Ne sachant pas dans quel contexte cela apparaîtra, mais je crois que la propriété de style CSS floatnon plus leftou rightaura cet effet. D'un autre côté, cela aura également d'autres effets secondaires, comme permettre au texte de flotter autour de lui.

Veuillez me corriger si je me trompe, je ne suis pas sûr à 100% et ne peux pas le tester moi-même actuellement.

falstro
la source
1
Oui, en CSS 2.1. (CSS2.0 rendrait le flotteur pleine largeur, mais seul IE5 / Mac le fait). Les tableaux et les flottants sont les seuls types d'affichage qui peuvent rétrécir pour s'adapter à leur contenu.
bobince
41

La réponse à votre question se trouve dans le futur mon ami ...

à savoir "intrinsèque" vient avec la dernière mise à jour CSS3

width: intrinsic;

malheureusement, IE est en retard, donc il ne le prend pas encore en charge

En savoir plus: Module de dimensionnement intrinsèque et extrinsèque CSS niveau 3 et puis-je utiliser? : Dimensionnement intrinsèque et extrinsèque .

Pour l'instant, vous devez être satisfait <span>ou <div>réglé sur

display: inline-block;
troyen
la source
12
intrinsiccomme valeur n'est pas standard. C'est vraiment le cas width: max-content. Voir la page MDN à ce sujet ou le brouillon déjà lié.
maryisdead
34

Une solution compatible CSS2 consiste à utiliser:

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

Vous pouvez également faire flotter votre div, ce qui le forcera le plus petit possible, mais vous devrez utiliser un clearfix si quelque chose à l'intérieur de votre div flotte:

.my-div
{
    float: left;
}
Soviut
la source
3
Cela devrait. Quel doctype utilisez-vous?
Soviut
34
width:1px;
white-space: nowrap;

fonctionne bien pour moi :)

Daft Wullie
la source
Mais là encore, mon cas était du texte à l'intérieur d'un div, et non un tableau comme l'OP.
Rui Marques
pour le curseur ui de jquery, c'est génial car vous n'avez pas besoin de définir la largeur de l'élément de contenu
CoffeJunky
26

OK, dans de nombreux cas, vous n'avez même pas besoin de faire quoi que ce soit comme div par défaut heightet widthcomme auto, mais si ce n'est pas votre cas, l'application d' inline-blockaffichage fonctionnera pour vous ... regardez le code que je crée pour vous et c'est fait ce que tu recherches:

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
la source
22

Cela a été mentionné dans les commentaires et est difficile à trouver dans l'une des réponses:

Si vous utilisez display: flexpour une raison quelconque, vous pouvez utiliser à la place:

div {
    display: inline-flex;
}

Ceci est également largement pris en charge par les navigateurs.

youngrrrr
la source
C'est ce dont j'avais besoin lorsque j'utilisais déjàdisplay: flex;
Denny
19

Vous pouvez le faire simplement en utilisant display: inline;(ou white-space: nowrap;).

J'espère que vous trouvez ça utile.

miksiii
la source
18

Vous pouvez utiliser en inline-blocktant que @ user473598, mais méfiez-vous des anciens navigateurs.

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

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

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

Mozilla ne prend pas du tout en charge le bloc en ligne, mais ils ont -moz-inline-stackce qui est à peu près le même

Un inline-blockattribut d'affichage croisé autour du navigateur : https://css-tricks.com/snippets/css/cross-browser-inline-block/

Vous pouvez voir certains tests avec cet attribut dans: https://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/

RPichioli
la source
1
Qu'est-ce que tu racontes? Mozilla Firefox prend en charge inline-blockdepuis 3.0 (2008). Source: developer.mozilla.org/en-US/docs/Web/CSS/…
Chazy Chaz
18

Mettez simplement un style dans votre fichier CSS

div { 
    width: fit-content; 
}
Hamza
la source
1
Je ne pense pas que ce soit une option prise en charge par plusieurs navigateurs.
David Rector
2
Ne fonctionne pas actuellement dans Edge: caniuse.com/#search=fit-content
molsson
Vous pouvez utiliser -moz-fit-contentpour FF, sans doute les autres préfixes des fournisseurs autoriseront leur propre ...
Benj
1
C'est la même chose que la réponse 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>

Je sais que les gens n'aiment pas les tables parfois, mais je dois vous dire que j'ai essayé les hacks en ligne css, et ils ont un peu fonctionné dans certaines divisions, mais dans d'autres non, donc, il était vraiment plus facile d'inclure le div en expansion dans un tableau ... et ... il peut avoir ou non la propriété inline et le tableau est toujours celui qui va contenir la largeur totale du contenu. =)

Edward
la source
2
Ce n'est pas la bonne façon, mais IE6 / 7/8 ne joue souvent pas bien quand les choses se compliquent un peu, donc je comprends parfaitement pourquoi vous le feriez de cette façon. Vous avez obtenu mon vote.
Craigo
Je le ferais, mais je dois entourer chaque boîte de saisie, c'est donc beaucoup de code HTML supplémentaire.
NickSoft
15

Une démo de travail est ici-

.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
la source
13

Ma solution flexbox CSS3 en deux versions: celle du haut se comporte comme une travée et celle du bas se comporte comme un div, prenant toute la largeur à l'aide d'un wrapper. Leurs classes sont respectivement "top", "bottom" et "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.

Lloyd Dominic
la source
bravo pour display: inline-flex;. BTW cela fonctionne sans préfixe pour Chrome 62, firefox 57 et safari 11
Horacio
12
<div class="parentDiv" style="display:inline-block">
    // HTML elements
</div>

Cela rendra la largeur de div parent identique à la plus grande largeur d'élément.

Jaimin Dave
la source
existe-t-il un moyen de l'appliquer uniquement pour la taille verticale afin de minimiser et de conserver une largeur horizontale?
Gobliins
12

Essayez display: inline-block;. Pour qu'il soit compatible avec plusieurs navigateurs, veuillez utiliser le code CSS ci-dessous.

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
la source
11

En manipulant Firebug, j'ai trouvé la valeur de la propriété -moz-fit-contentqui fait exactement ce que l'OP voulait et pourrait être utilisée comme suit:

width: -moz-fit-content;

Bien que cela ne fonctionne que sur Firefox, je n'ai trouvé aucun équivalent pour d'autres navigateurs tels que Chrome.

Hamed Momeni
la source
Depuis janvier 2017, IE (toutes les versions, Edge et mobile inclus) et Opera Mini ne prennent pas en charge fit-content. Firefox ne prend en charge que la largeur. D'autres navigateurs le supportent bien.
Gavin
11

Vous pouvez essayer ce code. Suivez le code dans la section 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
la source
7

J'ai résolu un problème similaire (où je ne voulais pas utiliser display: inline-blockcar l'élément était centré) en ajoutant une spanbalise à l'intérieur de la divbalise et en déplaçant la mise en forme CSS de la divbalise extérieure vers la nouvelle spanbalise intérieure . Il suffit de jeter cela là-bas comme une autre idée alternative si ce display: inline blockn'est pas une réponse appropriée pour vous.

Jessica Brown
la source
7

Nous pouvons utiliser l'une des deux manières suivantes sur l' divélément:

display: table;

ou,

display: inline-block; 

Je préfère utiliser display: table;, car il gère, tous les espaces supplémentaires seuls. Bien qu'il ait display: inline-blockbesoin d'un peu d'espace supplémentaire.

Novice
la source
6
div{
  width:auto;
  height:auto;
}
AJchandu
la source
Cela ne fonctionnera pas si div contient des éléments inline (ou inline-block) et qu'ils ont une taille de police et une hauteur de ligne différentes de celles du div lui-même.
quotesBro
5

Si vous avez des conteneurs qui cassent des lignes, après des heures à chercher une bonne solution CSS et à n'en trouver aucune, j'utilise maintenant jQuery à la place:

$('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
la source
Cela est visiblement cassé dans l'extrait de code pour moi dans Chrome; un deuxième clic sur le bouton de correction produit des résultats différents du premier clic.
Mark Amery
@MarkAmery sur mon mac Je viens de l'essayer sur Chrome, Safari et Firefox et tout va bien: pas d'erreurs visibles, rien sur la console, comportement cohérent. c'est peut-être quelque chose avec des fenêtres ...
cregox
5

Révisé (fonctionne si vous avez plusieurs enfants): vous pouvez utiliser jQuery (Regardez le lien JSFiddle)

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


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

N'oubliez pas d'inclure le jQuery ...

Voir le JSfiddle ici

Bondsmith
la source
Ceci est cassé si votre div a plusieurs enfants; il définit simplement la largeur div à celle du premier enfant.
Mark Amery
@MarkAmery Tout d'abord, avant de donner un vote négatif, veuillez lire attentivement la question, ils ont demandé un enfant. Si vous êtes vraiment curieux de savoir comment cela peut être fait avec plusieurs enfants, voyez la réponse révisée.
Bondsmith
4

J'ai essayé div.classname{display:table-cell;}et ça a marché!

UnLoCo
la source