Skitterm Skitterm - 28 days ago 8
CSS Question

Making one element's width dependent upon its sibling's width

I'm trying to make a widget such that a subtitle can never be longer than a title. So the title would control the width of the widget, and the subtitle would wrap if it got wider than the title. And I'm trying to do it without JavaScript if possible.

I got close (see snippet below). I was able to make the subtitle artificially short, but even in that case, the row it's in for some reason expanded to fit the whole space of the container, instead of just the space used by its child! in fact, the space it took up is exactly what it would be if it weren't wrapped.



#container {
background: #DDD;
display: flex;
flex-direction: column;
align-items: flex-start;
}

.row {
display: flex;
}

#subtitle {
flex-basis: 0;
}

<div id="container">
<div class="row">
<h1 id="title">Title that is fairly long</h1>
</div>
<div class="row">
<h3 id="subtitle">Subtitle that is a long subtitle and that is even longer and oh it is just so super!</h3>
</div>
</div>





I need to keep subtitle in the flow (not
position:absolute
), and the title needs to be able to wrap if it gets super long (so it won't just spill off the page).
Is there any way to have two rows, one below the other, and the one can only ever be as long as the other one is?

Answer

Sounds like a CSS table to me:

#container {
  background: #DDD; 
  display: table;
  width: 100%;
}
.row {
  display: table-row;
}
.row > * {
  display: table-cell;
}
.row:after {
  content: " ";
  display: table-cell;
}
#title {
  width: 1px;
  white-space: nowrap;
}
<div id="container">
  <div class="row">
    <h1 id="title">Title that is fairly long</h1>
  </div>
  <div class="row">
    <h3 id="subtitle">Subtitle that is a long subtitle and that is even longer and oh it is just so super!</h3>
  </div>        
</div>

width:1px on the title causes that column to collapse. white-space:nowrap prevents the title from wrapping. Since it's using table layout, this combination causes the width of the column to be determined by the title and so the subtitle follows along. :after provides us with a flexible column to fill out the table.

(Once CSS Grid becomes available, that might be preferable.)


You mentioned long titles. With that possibility, you'll need to switch to Javascript. (The Javascript below needs to be either somewhere after the section being affected or be run on page load.)

var title = document.getElementById('title'),
    subtitle = document.getElementById('subtitle'),
    subtitleResize = function() {
      subtitle.style.width = title.clientWidth + 'px';
    };
window.addEventListener('resize', subtitleResize, false);
subtitleResize();
#container {
  background: #DDD; 
}

#title {
  display:inline-block;
}
<div id="container">
  <div class="row">
    <h1 id="title">Title that is fairly long</h1>
  </div>
  <div class="row">
    <h3 id="subtitle">Subtitle that is a long subtitle and that is even longer and oh it is just so super!</h3>
  </div>        
</div>