2485

I have a layout similar to:

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

I would like for the div to only expand to as wide as my table becomes.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 109
    the effect is called "shrinkwrapping", and as answered there's a couple of ways to do this (float, inline, min/max-width) all of which have side-effects to choose from – annakata Jan 16 '09 at 16:32
  • Didn't work for me, but I didn't find anything wrong with how the question was answered. – David Spector Jun 24 '23 at 17:01

43 Answers43

2808

The solution is to set your div to display: inline-block.

Stefano Zanini
  • 5,876
  • 2
  • 13
  • 33
user473598
  • 28,281
  • 1
  • 14
  • 2
  • 247
    @leif81 You can use a `span` or a `div` or `ul` or anything else, the important part is for the container you would like to be minimum width have the CSS property `display: inline-block` – miahelf Nov 17 '11 at 08:23
  • 66
    Please make note that once you have `display: inline-block` property set the `margin: 0 auto;` won't work as expected. In that case if the parent container has `text-align: center;` then the `inline-block` element will be horizontally centered. – Savas Vedova Apr 09 '14 at 12:09
  • Adding to @SavasVedova comment, remember to change `auto` in `margin: 0 auto;` to `0` (or whatever value you may choose). – carloswm85 Oct 13 '21 at 22:53
  • 2
    This is not a solution if we want our element to have another display property, like grid, for instance. [@Vitalii Fedorenko's solution](https://stackoverflow.com/a/16765030/10254049) uses a newer `fit-content` property, which works for any display property, doesn't add margin, and [is supported on all browsers](https://developer.mozilla.org/en-US/docs/Web/CSS/fit-content#browser_compatibility). – Coco Liliace Jan 08 '23 at 18:07
  • 1
    This would be great if I wanted my components to flow inline XD. `fit-content` seems to be the modern solution. – nullromo Jan 13 '23 at 00:16
366

You want a block element that has what CSS calls shrink-to-fit width and the spec does not provide a blessed way to get such a thing. In CSS2, shrink-to-fit is not a goal, but means to deal with a situation where browser "has to" get a width out of thin air. Those situations are:

  • float
  • absolutely positioned element
  • inline-block element
  • table element

when there are no width specified. I heard they think of adding what you want in CSS3. For now, make do with one of the above.

The decision not to expose the feature directly may seem strange, but there is a good reason. It is expensive. Shrink-to-fit means formatting at least twice: you cannot start formatting an element until you know its width, and you cannot calculate the width w/o going through entire content. Plus, one does not need shrink-to-fit element as often as one may think. Why do you need extra div around your table? Maybe table caption is all you need.

robocat
  • 5,293
  • 48
  • 65
buti-oxa
  • 11,261
  • 5
  • 35
  • 44
  • 40
    I would say `inline-block` is exactly intended for this and solves the problem perfectly. – miahelf Nov 17 '11 at 08:24
  • @miahelf – Famous last words, at no point was inline-block the perfect way for this, and never will it be considered as such. – thephpdev Nov 30 '21 at 09:57
264

I think using

display: inline-block;

would work, however I'm not sure about the browser compatibility.


Another solution would be to wrap your div in another div (if you want to maintain the block behavior):

HTML:

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

CSS:

.yourdiv
{
    display: inline;
}
mbillard
  • 38,386
  • 18
  • 74
  • 98
  • 23
    To answer the browser compatibility question: this won't work with IE7/8 on DIV elements. You have to use SPAN elements. – Matt Brock Feb 18 '11 at 14:26
  • The link at https://caniuse.com/?search=inline-block says that 99% of browsers support the unprefixed version, which is (when you toggle date-relative) browsers since 2008. (That's more than ES5's support!) – Infigon Feb 03 '23 at 21:00
252

display: inline-block adds an extra margin to your element.

I would recommend this:

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

Bonus: You can also now easily center that fancy new #element just by adding margin: 0 auto.

Samuel Katz
  • 24,066
  • 8
  • 71
  • 57
241

You can try fit-content (CSS3):

div {
  width: fit-content; 
  /* To adjust the height as well */ 
  height: fit-content;
}
Vitalii Fedorenko
  • 110,878
  • 29
  • 149
  • 111
106

There are two better solutions

  1. display: inline-block;

    OR

  2. display: table;

Out of these two display:table; is better, because display: inline-block; adds an extra margin.

For display:inline-block; you can use the negative margin method to fix the extra space

VFDan
  • 831
  • 10
  • 26
Shuvo Habib
  • 2,035
  • 1
  • 20
  • 25
91

What works for me is:

display: table;

in the div. (Tested on Firefox and Google Chrome).

atiquratik
  • 1,296
  • 3
  • 27
  • 34
Sony Santos
  • 5,435
  • 30
  • 41
85
display: -moz-inline-stack;
display: inline-block;
zoom: 1;
*display: inline;

Foo Hack – Cross Browser Support for inline-block Styling (2007-11-19).

nikib3ro
  • 20,366
  • 24
  • 120
  • 181
49

Not knowing in what context this will appear, but I believe the CSS-style property float either left or right will have this effect. On the other hand, it'll have other side effects as well, such as allowing text to float around it.

Please correct me if I'm wrong though, I'm not 100% sure, and currently can't test it myself.

Rob
  • 4,927
  • 12
  • 49
  • 54
falstro
  • 34,597
  • 9
  • 72
  • 86
45

The answer for your question lays in the future my friend ...

namely "intrinsic" is coming with the latest CSS3 update

width: intrinsic;

unfortunately IE is behind with it so it doesn't support it yet

More about it: CSS Intrinsic & Extrinsic Sizing Module Level 3 and Can I Use?: Intrinsic & Extrinsic Sizing.

For now you have to be satisfied with <span> or <div> set to

display: inline-block;
InSync
  • 4,851
  • 4
  • 8
  • 30
trojan
  • 1,465
  • 19
  • 27
40
width:1px;
white-space: nowrap;

works fine for me :)

InSync
  • 4,851
  • 4
  • 8
  • 30
Daft Wullie
  • 433
  • 4
  • 2
39

A CSS2 compatible solution is to use:

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

You can also float your div which will force it as small as possible, but you'll need to use a clearfix if anything inside your div is floating:

.my-div
{
    float: left;
}
InSync
  • 4,851
  • 4
  • 8
  • 30
Soviut
  • 88,194
  • 49
  • 192
  • 260
33

This has been mentioned in comments and is hard to find in one of the answers so:

If you are using display: flex for whatever reason, you can instead use:

div {
    display: inline-flex;
}

This is also widely supported across browsers.

InSync
  • 4,851
  • 4
  • 8
  • 30
youngrrrr
  • 3,044
  • 3
  • 25
  • 42
30

OK, in many cases you even don't need to do anything as by default div has height and width as auto, but if it's not your case, applying inline-block display gonna work for you... look at the code I create for you and it's do what you looking for:

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
  • 100,211
  • 27
  • 269
  • 172
29

just set the width and height to fit-content. it is very simple.

div {

    width: fit-content;
    height: fit-content;
    padding: 10px;

}

I am adding padding: 10px;. if it is left out, the div element will completely stick with the table and it will look a bit clumsy. Padding will create the given space between the border of the element and it's contents. But it is your wish not compulsory.

Coder_Naveed
  • 526
  • 5
  • 5
28

You can try this code. Follow the code in the CSS section.

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>
Sam
  • 15,254
  • 25
  • 90
  • 145
Showrin Barua
  • 1,737
  • 1
  • 11
  • 22
27

Just put a style into your CSS file

div { 
    width: fit-content; 
}
InSync
  • 4,851
  • 4
  • 8
  • 30
Hamza
  • 721
  • 8
  • 8
22

Try to use width: max-content property to adjust the width of the div by it's content size.

Try this example,

<!DOCTYPE html>
<html>
<head>
<style>
div.ex1 {
  width:500px;
  margin: auto;
  border: 3px solid #73AD21;
}

div.ex2 {
  width: max-content;
  margin: auto;
  border: 3px solid #73AD21;
}
</style>
</head>
<body>

<div class="ex1">This div element has width 500px;</div>
<br>
<div class="ex2">Width by content size</div>

</body>
</html>
Codemaker2015
  • 12,190
  • 6
  • 97
  • 81
20

You can do it simply by using display: inline; (or white-space: nowrap;).

I hope you find this useful.

miksiii
  • 2,426
  • 26
  • 22
20

You can use inline-block as @user473598, but beware of older browsers..

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

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

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

Mozilla doesn’t support inline-block at all, but they have -moz-inline-stack which is about the same

Some cross-browser around inline-block display attribute: https://css-tricks.com/snippets/css/cross-browser-inline-block/

You can see some tests with this attribute in: https://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/

RPichioli
  • 3,245
  • 2
  • 25
  • 29
20
<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>

I know people don't like tables sometimes, but I gotta tell you, I tried the css inline hacks, and they kinda worked in some divs but in others didn't, so, it was really just easier to enclose the expanding div in a table...and...it can have or not the inline property and still the table is the one that's gonna hold the total width of the content. =)

RPichioli
  • 3,245
  • 2
  • 25
  • 29
Edward
  • 615
  • 1
  • 5
  • 12
15

An working demo is here-

.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
  • 13,970
  • 24
  • 112
  • 161
12

My CSS3 flexbox solution in two flavors: The one on top behaves like a span and the one at the bottom behaves like a div, taking all the width with the help of a wrapper. Their classes are "top", "bottom" and "bottomwrapper" respectively.

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
  • 778
  • 8
  • 25
  • kudos for `display: inline-flex;`. BTW this works without prefix for Chrome 62, firefox 57, and safari 11 – Horacio Nov 24 '17 at 03:06
11

Tampering around with Firebug I found the property value -moz-fit-content which exactly does what the OP wanted and could be used as follow:

width: -moz-fit-content;

Although it only works on Firefox, I couldn't find any equivalent for other browsers such as Chrome.

2hamed
  • 8,719
  • 13
  • 69
  • 112
  • As of January 2017, IE (all versions, Edge and mobile included) and Opera Mini have no support for `fit-content`. Firefox supports width only. Other browsers support it well. – Gavin Jan 11 '17 at 22:30
11
<div class="parentDiv" style="display:inline-block">
    // HTML elements
</div>

This will make parent div width same as the largest element width.

Jaimin Dave
  • 1,224
  • 10
  • 18
11

Try display: inline-block;. For it to be cross browser compatible please use the below css code.

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>
Let Me Tink About It
  • 15,156
  • 21
  • 98
  • 207
James
  • 337
  • 4
  • 12
11

div{
width:fit-content;
}
<div>
    <table>
    </table>
</div>
Awabil George
  • 310
  • 6
  • 12
10
    .outer{
          width:fit-content;   
          display: flex;
          align-items: center;
    }
    .outer .content{
         width: 100%;
    }
        
        
        
        
<div class=outer>
    <div class=content>
       Add your content here


    </div>
        
</div>
Trupti M Panchal
  • 250
  • 3
  • 10
7

I have solved a similar problem (where I didn't want to use display: inline-block because the item was centered) by adding a span tag inside the div tag, and moving the CSS formatting from the outer div tag to the new inner span tag. Just throwing this out there as another alternative idea if display: inline block isn't a suitable answer for you.

Rob
  • 4,927
  • 12
  • 49
  • 54
Jessica Brown
  • 8,222
  • 7
  • 46
  • 82
7

We can use any of the two ways on the div element:

display: table;

or,

display: inline-block; 

I prefer to use display: table;, because it handles, all extra spaces on its own. While display: inline-block needs some extra space fixing.

Novice
  • 558
  • 2
  • 9
  • 21
6
div{
  width:auto;
  height:auto;
}
DreamTeK
  • 32,537
  • 27
  • 112
  • 171
AJchandu
  • 141
  • 2
  • 9
  • This will not work if div contains inline (or inline-block) elements and they have different font-size and line-height than the div itself. – quotesBro Feb 13 '18 at 10:15
5

Revised (works if you have multiple children): You can use jQuery (Look at the JSFiddle link)

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


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

Do not forget to include the jQuery...

See the JSfiddle here

Bondsmith
  • 1,343
  • 3
  • 13
  • 27
  • This is broken if your div has multiple children; it simply sets the div width to that of the *first* child. – Mark Amery Sep 28 '16 at 17:32
  • @MarkAmery First of all, before you give it a negative vote, please read the question carefully, they asked for one child. If you are really curious how it can be done with multiple children see the revised answer. – Bondsmith Sep 30 '16 at 13:08
5

If you have containers breaking lines, after hours looking for a good CSS solution and finding none, I now use jQuery instead:

$('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>
Community
  • 1
  • 1
cregox
  • 17,674
  • 15
  • 85
  • 116
  • This is visibly broken in the snippet for me in Chrome; clicking the fix button a second time produces different results to clicking it the first time. – Mark Amery Sep 28 '16 at 17:29
  • @MarkAmery on my mac I just tried it on chrome, safari and firefox and it's all fine: no visible errors, nothing on the console, consistent behavior. maybe it's something with windows... – cregox Sep 28 '16 at 19:17
4

I tried div.classname{display:table-cell;} and it worked!

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
unloco
  • 6,928
  • 2
  • 47
  • 58
4

You could use display: flex for parent element

#parentElement {
   display: flex;
   flex-direction: column;
   align-items: flex-start;
 }
ZhenyaUsenko
  • 393
  • 4
  • 8
3

I would just set padding: -whateverYouWantpx;

NathanielSantley
  • 299
  • 1
  • 16
3

I've a span inside a div and just setting margin: auto to the container div worked for me.

Vinay Mehta
  • 137
  • 2
  • 10
1

Personnaly, I simply do this :

HTML code:

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

CSS code:

div {
    display: inline;
}

If you apply a float on your div, it works too but obviously, you need to apply a "clear both" CSS rules at the next HTML element.

Nicolas Talichet
  • 309
  • 3
  • 16
1

Simply

<div style="display: inline;">
    <table>
    </table>
</div>
Zeke
  • 562
  • 4
  • 14
1

What if we define a global variable and use that for both.

:root {
    --table-width: 400px;
}

.container{
     width:var(--table-width);
     border: 1px solid black;   // easy visualization
}
.inner-table {
     width:var(--table-width);
     border: 1px solid red;   // easy visualization
}
<div class="container">
    <table class="inner-table">
       <tr>
           <td>abc</td>
       </tr>
    </table>
</div>
Harshana
  • 524
  • 3
  • 16
-3

Seems it's a 13 years old question.

.div{
display:inline-block;
}

or

.div{
display:inline-flex;
}

would work now a days without any compatibility issues.

Rajilesh Panoli
  • 770
  • 10
  • 17
-4

This seems to work fine for me on all browsers. Example is an actual ad i use online and in newsletter. Just change the content of the div. It will adjust and shrinkwrap with the amount of padding you specify.

<div style="float:left; border: 3px ridge red; background: aqua; padding:12px">
    <font color=red size=4>Need to fix a birth certificate? Learn <a href="http://www.example.com">Photoshop in a Day</a>!
    </font>
</div>
sebagomez
  • 9,501
  • 7
  • 51
  • 89
DearWebby
  • 601
  • 5
  • 2
  • 2
    font is utterly deprecated. probably renders as on any current engine. – zanlok Apr 02 '13 at 04:13
  • 2
    @zanlok He's talking about a newsletter, `` still seems to be fair game in email land despite its deprecation (2nd answer): http://stackoverflow.com/questions/8012799/do-we-still-need-to-use-font-tags-in-html-emails – Pabbles Apr 24 '14 at 15:43
-5

You can use height: 100% and width for your choice. This makes the div not larger than its content.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131