The BB element is an in-flow flex item and is confined to its container (.row
).
To make it overflow its parent and take the remaining width of the viewport, you can try this:
.container > .row:first-child > .col-xs-10 { /* 1 */
position: absolute; /* 2 */
width: 100%; /* 3 */
margin-left: 16.7% /* 4 */
}
.container > .row:first-child {
position: relative; /* 5 */
}
body {
background-color: lightgreen;
}
[class^="col"] {
background: gold;
border: 1px solid tomato;
}
<link href="https://cask.scotch.io/bootstrap-4.0-flex.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="col-xs-2">AA</div>
<div class="col-xs-10">BB</div>
</div>
<div class="row">
<div class="col-xs-6">CC</div>
<div class="col-xs-6">DD</div>
</div>
</div>
revised fiddle
Notes:
- Target the BB element.
- Remove BB from the document flow
- Arbitrary full width
- Position BB to start immediately at the right of AA (which has a width of
flex: 0 0 16.66667%
)
- Make container the bounding box (nearest positioned ancestor) for absolutely positioned children.
Of course, a (potential) problem with this method is item #3.
Because BB is absolutely positioned relative to its parent, we don't know the exact length to the viewport edge. Giving too much width can result in a horizontal scroll bar, as in my example.
One workaround is to apply overflow-x: hidden
to the body
element, which will remove the scrollbar, simply clipping BB at the viewport edge.
Or we can remove position: relative
from the parent, therefore making BB relative to the viewport. This method can precisely size BB to the viewport edge, but at the expense of item #4: margin-left
will no longer be precise.
But let's give it a try:
EDIT: Aside from the margin-left
deficiency, there's another flaw with this method. Instead of removing the example, I'm keeping it for learning purposes. See if you can find the problem before reaching the end :-)
.container > .row:first-child > .col-xs-10 {
position: absolute;
width: 75%; /* 6 */
margin-left: 25%; /* 6 */
left: 0; /* 6 */
}
.container > .row:first-child > .col-xs-2 { /* 7 */
flex-grow: 1;
}
body {
background-color: lightgreen;
}
[class^="col"] {
background: gold;
border: 1px solid tomato;
}
<link href="https://cask.scotch.io/bootstrap-4.0-flex.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="col-xs-2">AA</div>
<div class="col-xs-10">BB</div>
</div>
<div class="row">
<div class="col-xs-6">CC</div>
<div class="col-xs-6">DD</div>
</div>
</div>
revised fiddle
Notes:
- BB is sized, aligned and positioned relative to the initial containing block (i.e., the viewport).
- AA, which is sized in the original code with
flex: 0 0 16.666667%
, is given flex-grow: 1
to fill any gaps between itself and BB.
Now BB ends precisely at the viewport edge. However, we've had to make AA "flex" a bit to prevent any gaps due to BB margin-left
imprecision.
EDIT: The problem with the method above is this: Because BB is absolutely-positioned it is removed from the document flow. This means that AA doesn't even know it exists. Hence, flex-grow
on AA will expand it all the way to the edge of the container, not to the start of BB..
Other alternatives include:
Making the container full width, then managing the length and margins of flex items. (This would involve major alterations to the Bootstrap framework, which is why I didn't pursue it.)
JavaScript