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.


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.


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.


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

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.


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


86

Ce qui fonctionne pour moi, c'est:

display: table;

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


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


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.


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;

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

3
Cela devrait. Quel doctype utilisez-vous?
Soviut

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

fonctionne bien pour moi :)


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>



19

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

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


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/


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


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>


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.


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.


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>


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.


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>


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.


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.


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

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>


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


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é!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.