65

I'm looking for a CSS solution to the following:-

<div style="display:inline;">
     <div>The content of this div is dynamically created but will always be wider than
              the below div. 
     </div>
     <div> Need this div to have the same width as the above div.
     </div>
</div>

The wrapper div has an inline display and works as expected, both child divs have dynamically generated content. I need the bottom one to take the width of the previous sibling.

Many thanks for any suggestions in advance.

esengineer
  • 9,514
  • 7
  • 45
  • 69
user1278456
  • 651
  • 1
  • 5
  • 4

9 Answers9

86

Here's another Flexbox solution which allows for the second child to wrap to match the width of the variable height sibling.

.wrapper > div {
  border: 1px solid;
}

.child {
  display: flex;
}

.child div {
  flex-grow: 1;
  width: 0;
}

.wrapper {
  display: inline-block;
}
<div class="wrapper">
    <div>This div is dynamically sized based on its content</div>
    <div class="child"><div>This div will always be the same width as the preceding div, even if its content is longer (or shorter too).</div></div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Peter Josling
  • 1,036
  • 8
  • 6
  • Nice solution. I was hoping to not an extra div around the larger div (and do it with purely css), but I'll settle for this for now. Fortunately, in my case I didn't even need the parent `.wrapper` div. I didn't investigate exactly why, but thought it was worth mentioning. – Daniel Waltrip Dec 06 '18 at 19:29
  • Not working on Edge V44.17763.771.0, the strange thing, the same solution is working fine on IE 11.805 – Harsh kurra Dec 02 '19 at 08:32
  • Hi @Peter, If there are multiple div's under .child, then child div's are stretching based on their content, instead of having sibling's width. Please check this link for the same - https://jsfiddle.net/eotfy6w8/1/. Please let me know how to fix the code, so that all child div's will have the same width as it's sibling's width. – Sravan Kumar Jan 05 '20 at 09:34
  • 1
    Improvement: `.child div` should also contain `wordWrap: 'break-word'`. Otherwise, very long words will overflow. – DarkTrick Feb 10 '23 at 06:11
  • fina-freaking-finally, I have been looking for hours for this and beat myself up over it. "It should be so simple, but why can't I get it to work?" Thank you so much for this! – Tom Feb 16 '23 at 16:50
16

Floats and tables are so 2000 and late. With today's browsers we can make the two sibling DIVs match each other's width, regardless which is bigger/smaller.

Here's a Flexbox solution fit for 2016:

.wrapper {
  display: inline-block;
}

.parent {
  display: flex;
  flex-direction: column;
}

/* For visualization */
.child {
  border: 1px solid #0EA2E8;
  margin: 2px;
  padding: 1px 5px;
}
<div class="wrapper">
  <div class="parent">
    <div class="child">Child number one</div>
    <div class="child">Child #2</div>
  </div>
</div>
pilau
  • 6,635
  • 4
  • 56
  • 69
  • 7
    But if you don't want the second child to dictate the width (and it's longer than the first child), this won't work. The first child will become as wide as the second child is. – Skitterm Nov 10 '16 at 18:58
  • 2
    @Skitterm True, but the question reads: *"I need the bottom one to take the width of the previous sibling"*. – pilau Nov 12 '16 at 19:25
  • @pilau yes. And as skitterm stated, this solution wont work if the bottom child has a bigger content than the previous sibling. You know. If there is not written `Child #2`. It can be a rare case, but you know, in real world scenarios, you don't write much Child#2 into content. I mean isn't that obvious? – Toskan Jul 26 '17 at 15:44
  • 2
    Small improvement: you can save the .wrapper div if you use `display: inline-flex` instead of `flex` in .parent – Akronix Oct 28 '17 at 11:25
7

2023 keep it simple...

Use grid and the fr unit. Then you can split up into as many equally sized rows or columns as you want:

.container {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-column-gap: 1em;
}

.container > div {
  border: 1px solid black;
  padding: 0.5em;
}
<div class="container">
  <div>I'm a part of a grid. I will be split up into equal parts with my other sibling(s) depending on how many columns the grid is given.</div>
  <div>I am a sibling element.</div>
</div>
maxshuty
  • 9,708
  • 13
  • 64
  • 77
  • 1
    This doesn't make the bottom div match the width of the top sibling, it just gives both divs equal space of the parent container. Each div will always be 50% width of the parent. They won't adjust and match based on the dynamic content. – TinyTiger Feb 01 '22 at 21:49
  • 1
    To the point ! I will add that if you were using something like "`display:flex; flex-direction:column;`", then you could use: "`grid-template-rows: repeat(1, 1fr);`" – Omar Trkzi Jul 03 '23 at 16:44
4

Set your div to display:inline-block instead, this way your div will expand with the content inside of it.

http://jsfiddle.net/CpKDX/

Andres I Perez
  • 75,075
  • 21
  • 157
  • 138
  • 2
    http://jsfiddle.net/CpKDX/5/ in the above example, I want the second child div to take the width of the first child div i.e. it's previous sibling. – user1278456 Mar 19 '12 at 12:57
  • @user1278456 you can set your container div to `display:inline-block` instead of `display:inline` and you get those results, http://jsfiddle.net/CpKDX/6/ – Andres I Perez Mar 19 '12 at 13:06
  • that isn't giving me the desired result. What i want is the bottom div to take the height of the top div which it doesn't in the above fiddle. – user1278456 Mar 19 '12 at 13:15
  • @user1278456 aah, just understood your question, try this: http://jsfiddle.net/CpKDX/7/ .. Using the general sibling selector you can apply a style to the div that follows the first. – Andres I Perez Mar 19 '12 at 13:20
3

Here is still a flexbox-based approach.

The essential idea: in an outermost wrapper, elements that need to be of equal width are wrapped into another wrapper.

.wrapper {
  display: inline-block;
}

.flex-wrapper {
  display: flex;
  flex-direction: column;
}

.demo-bar {
  height: 4px;
  background-color: deepskyblue;
}
<div class="wrapper">
  <div class="flex-wrapper">
    <div contenteditable>Some editable text.</div>
    <div class="demo-bar"></div>
  </div>
</div>

Another practical example: an adaptive progress bar with the same width below a media (video or audio) element.

video.addEventListener("timeupdate", () =>
  progress.style.width = `${video.currentTime / video.duration * 100}%`
)
.wrapper {
  display: flex;
  flex-direction: column;
  position: relative;
  align-items: center;
}

video {
  display: block;
  max-width: 100%;
}

.progress-bar {
  height: 0.25rem;
  background: #555;
}

#progress {
  width: 0%;
  height: 100%;
  background-color: #595;
}
<div class="wrapper">
  <div data-css-role="wrapper">
    <video id="video" controls>
      <source src="https://raw.githubusercontent.com/mdn/interactive-examples/master/live-examples/media/cc0-videos/flower.webm">
    </video>
    <div class="progress-bar">
      <div id="progress"></div>
    </div>
  </div>
</div>
keep
  • 53
  • 2
  • 4
  • An excellent answer! If I may add, both wrapper `div` elements can also be swapped out for the `span` elements (if the DOM becomes too overloaded with block-sized elements), provided the outermost `span` has a display style defined as "inline-block". – leonidos79 Aug 12 '22 at 22:35
1

you can try using { width: min-content; min-width: 100%;} on the second div and {display: inline-block} on the parent div

kelsny
  • 23,009
  • 3
  • 19
  • 48
danny
  • 31
  • 5
0

UPDATE: This works with me, I've just tried it:

<div style="max-width:980px;border:1px solid red;">
   <div style="background:#EEE;float:left;">
     <div style="width:auto;border:1px solid blue;float:left;">If you use 100% here, it will fit to the width of the mother div automatically.</div>
     <div style="border:1px solid green;"> The div will be 100% of the mother div too.</div>
   </div>
     <div style="clear:both;"></div>
</div>

Is this what you want? The borders and background are just to show the divs ;)


Just go like this:

Let's say you want the whole divs be max. 980px (otherwise just leave that out or replace with 100%)...

<div style="max-width:980px;">
     <div style="width:100%;">If you use 100% here, it will fit to the width of the mother div automatically.
     </div>
     <div style="width:100%;"> The div will be 100% of the mother div too.
     </div>
</div>

The second option would be, to use one more div... or you use style="width:auto;" for the dynamic div...

Chris
  • 3,756
  • 7
  • 35
  • 54
  • Ahh i am afraid this doesn't produce the desired effect either. – user1278456 Mar 19 '12 at 14:37
  • because it is 100% of the mother's div, right? If it is not what you want, use width:auto for both inner divs.. does this work you want it? – Chris Mar 19 '12 at 15:06
  • @user1278456: I've just updated it, it works for me... please let me know if it is what you were looking for :) – Chris Mar 19 '12 at 15:29
-3

If your willing to give up on a couple of <div>s then I have the solution for you:

<div style=“display: inline-block;”>
  <table>
    <tr>
      <td>The table automatically makes its siblings the same width</td>
    </tr>
    <tr>
      <td>So this will be as wide</td>
    </tr>
  </table>
</div>

Remember to set the div display:inline-block;

MaxiGui
  • 6,190
  • 4
  • 16
  • 33
-3

Not sure if I understood what you are trying to do, but looks like setting a 100% width to the last div should work:

<div style="width:100%;"> 

BTW the style in the first div is not well defined, you should use a colon instead of a equal sign in the properties definition:

<div style="display:inline;">
arraintxo
  • 484
  • 2
  • 12
  • there no need to define width:100% because div is a block element & it's take auto width – sandeep Mar 19 '12 at 11:58
  • This forces the wrapper div to take up the whole screen rather than setting the child div to 100% of the wrapper div... Yep ;) well spotted. – user1278456 Mar 19 '12 at 12:00
  • After having spent lots of time messing around with CSS, I have decided to spare myself some time and go with using a table. half a minute = job done. http://jsfiddle.net/XdLku/1/ Now don't all scream and shout at once! Thank you for the contributions. – user1278456 Mar 19 '12 at 14:56