Why does the outer <div> here not completely surround the inner <div>?

What you want can be done using a combination of inline-block and min-width:100%. A block element has its width defined based on its parent element (containing block) while inline-block will have its width defined by its content.

Adding the min-width:100% will make it behave as block element. it's not mandatory in this case since you already have a lot of content so you are sure to cover all the width:

body {
  margin: 4em;
}

.demo {
  background-color: #BFC;
  box-sizing: border-box;
  margin: 0;
  padding: 1em;
  position: relative;
  display:inline-block;
  min-width:100%;
}

.demo p:first-child {
  margin-top: 0;
}

.other-stuff {
  align-items: center;
  display: flex;
}

button {
  margin-right: 1em;
}

.square {
  display: inline-block;
  background-color: #699;
  height: 80px;
  margin-right: 1em;
  min-width: 80px;
  width: 80px;
}

.circle {
  border-radius: 50px;
  display: inline-block;
  background-color: #969;
  height: 100px;
  margin-right: 1em;
  min-width: 100px;
  width: 100px;
}
<div class="demo">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  <div class="other-stuff">
    <button>One&nbsp;button</button>
    <div class="square"></div>
    <button>Another&nbsp;button</button>
    <div class="circle"></div>
    <button>Don't&nbsp;click!</button>
  </div>
</div>

Reduce the text on the top and min-width:100% will become mandatory to have full width behavior.

Run the snippet on full page

body {
  margin: 4em;
}

.demo {
  background-color: #BFC;
  box-sizing: border-box;
  margin: 0;
  padding: 1em;
  position: relative;
  display:inline-block;
}

.demo p:first-child {
  margin-top: 0;
}

.other-stuff {
  align-items: center;
  display: flex;
}

button {
  margin-right: 1em;
}

.square {
  display: inline-block;
  background-color: #699;
  height: 80px;
  margin-right: 1em;
  min-width: 80px;
  width: 80px;
}

.circle {
  border-radius: 50px;
  display: inline-block;
  background-color: #969;
  height: 100px;
  margin-right: 1em;
  min-width: 100px;
  width: 100px;
}
<div class="demo">
  <p>Lorem ipsum </p>
  <div class="other-stuff">
    <button>One&nbsp;button</button>
    <div class="square"></div>
    <button>Another&nbsp;button</button>
    <div class="circle"></div>
    <button>Don't&nbsp;click!</button>
  </div>
</div>

<div class="demo" style="min-width:100%;">
  <p>Lorem ipsum </p>
  <div class="other-stuff">
    <button>One&nbsp;button</button>
    <div class="square"></div>
    <button>Another&nbsp;button</button>
    <div class="circle"></div>
    <button>Don't&nbsp;click!</button>
  </div>
</div>

From the specification:

Block-level, non-replaced elements in normal flow

The following constraints must hold among the used values of the other properties:

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block

Note how the content play no role in defining the width.

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

If 'width' is 'auto', the used value is the shrink-to-fit width

Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm. Roughly: 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

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

Note how the content is used to define the width.


The same apply to any kind of display value (grid, flex, table, etc) and the trick is to replace it with the inline-* equivalent (inline-grid, inline-flex, inline-table, etc)