Cool Blue
Cool Blue

Reputation: 6476

Anonymous text block width for inline-block elements

I am trying to make the width of a container div dynamically collapse onto its inline-block contents. From what I can determine this is imposible per 9.4.2 Inline formatting contexts

In general, the left edge of a line box touches the left edge of its containing block and the right edge touches the right edge of its containing block. However, floating boxes may come between the containing block edge and the line box edge. Thus, although line boxes in the same inline formatting context generally have the same width (that of the containing block), they may vary in width if available horizontal space is reduced due to floats.

The problem is the anonymous text blocks assume the width of their container.

I want the internal elements to respond to width like this...

var demoContainer = d3.select('#demoContainer').style('width', '200px');
function tick() {
	demoContainer.transition().duration(3000).style('width', '300px')
	.transition().duration(2000).style('width', '300px')
	.transition().duration(3000).style('width', '550px')
	.transition().duration(3000).style('width', '300px')
	.transition().duration(2000).style('width', '300px')
	.transition().duration(3000).style('width', '100px')
	.each('end', tick);
};
tick();
#htmlDiv {
      font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;
      font-size: 12px;
      outline: solid 1px black;
      background-color: rgba(0, 0, 0, 0.25);
      display: inline-block;
      box-sizing: border-box;
    }

    .container,
    #bubble-wrapper {
      height: auto;
      position: relative;
      display: inline-block;
      margin: 5px;
      background-color: rgba(0, 38, 255, 0.25);
      outline: solid 1px white;
      text-align: left;
    }

    .bubbles {
      color: #ccc;
    }

    .select-bubbles,
    .bubbles {
      padding: 5px;
      margin: 5px;
      outline: solid 1px white;
      background-color: rgb(114, 114, 114);
      width: 100px;
      display: inline-block;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="demoContainer" style="outline: solid 3px red; padding: 10px">
    <div id="htmlDiv">
      <div class="container">
        display: inline-block;
        <br>position: relative;
        <br />
        <div class="select-bubbles">
          inline-block
        </div>
      </div>
      <br>
      <div id="bubble-wrapper">
        display: inline-block;
        <br>position: relative;
        <br>
        <div class="bubbles bubble1">
          inline-block
        </div>
        <div class="bubbles bubble2">
          inline-block
        </div>
        <div class="bubbles bubble2">
          inline-block
        </div>
      </div>
    </div>
  </div>

But I need the container to shrink-wrap the inner divs...

this is fine
enter image description here
and so is this
enter image description here
but this is not what I'm looking for...
enter image description here

Have I correctly understood the spec and if so is there a way to achieve what I'm looking for?

UPDATE As pointed out by @Alohci the more important reference is

10.3.9 'Inline-block', non-replaced elements in normal flow

If 'width' is 'auto', the used value is the shrink-to-fit width as for floating elements.

Upvotes: 4

Views: 567

Answers (2)

Alohci
Alohci

Reputation: 82996

You've correctly understood the consequence of the spec, though IMHO you've not quoted the critical part. That's the shrink-to-fit algorithm, which says:

... calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur, and also calculate the preferred minimum width, e.g., by trying all possible line breaks. ... Thirdly, find the available width: in this case, this is the width of the containing block minus the used values of 'margin-left', 'border-left-width', 'padding-left', 'padding-right', 'border-right-width', 'margin-right', and the widths of any relevant scroll bars.

Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).

Which resolves to the available width, not the minimum width for your "can't shrink wrap" case.

Unfortunately, CSS uses this algorithm widely, so alternative layouts like floating the boxes, have the same problem.

Upvotes: 3

fcastillo
fcastillo

Reputation: 948

It`s not perfect but you could work whit this: fiddle

Add this to your CSS:

#htmlDiv * { box-sizing: border-box; }

That property inluded padding and border in the element's total width.

Upvotes: 0

Related Questions