Targets
I am trying to accomplish the following:
- When the screen is enough wide, the
.firstItem(red) and.lastItem(blue) elements, whose widths are unknown in advance, are on left and right part of parent.layoutrespectively.
- When the screen becomes narrower and horizontal spacing between items reduced to
$minimalHorizontalSpaceBetweenItems, the layout collapses to column, but the.firstItemis still justified to left and.lastItemto right:
The vertical space between items
$verticalSpaceBetweenItemsmust not affect the layout in the single row configuration.The below CSS rule for the yellow
.preceedingElementblock above.firstItemand.lastItemmust work:
.preceedingElement + .layout {
margin-top: Npx;
}
Basic MWE
<div class="preceedingElement"></div>
<div class="layout">
<div class="firstItem"></div>
<div class="lastItem"></div>
</div>
SCSS:
.preceedingElement{
width: 100%;
height: 30px;
background: #FAD7A0;
}
@mixin TwoSpacedItemsComposition(
$minimalHorizontalSpaceBetweenItems: 0,
$verticalSpaceBetweenItems: 0
) {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-top: -$verticalSpaceBetweenItems;
margin-right: -$minimalHorizontalSpaceBetweenItems;
> *{
margin-top: $verticalSpaceBetweenItems;
margin-right: $minimalHorizontalSpaceBetweenItems;
&:last-child {
margin-left: auto;
}
}
}
.layout {
@include TwoSpacedItemsComposition(
$minimalHorizontalSpaceBetweenItems: 12px,
$verticalSpaceBetweenItems: 24px
)
}
.firstItem {
width: 200px;
height: 34px;
background: #EC7063;
}
.lastItem {
width: 400px;
height: 24px;
background: #7FB3D5;
}
Flex solution attempt
Below SASS mixin implements all targets except fourth:
@mixin TwoSpacedItemsComposition(
$minimalHorizontalSpaceBetweenItems: 0,
$verticalSpaceBetweenItems: 0
) {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-top: -$verticalSpaceBetweenItems;
margin-right: -$minimalHorizontalSpaceBetweenItems;
> *{
margin-top: $verticalSpaceBetweenItems;
margin-right: $minimalHorizontalSpaceBetweenItems;
&:last-child {
margin-left: auto;
}
}
}
The interference is margin-top: -$verticalSpaceBetweenItems; for parent and margin-top: $verticalSpaceBetweenItems; for child.
Grid solution attempt
The grid always renders 2 rows.
@mixin TwoSpacedItemsComposition(
$minimalHorizontalSpaceBetweenItems: 0,
$verticalSpaceBetweenItems: 0
) {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(0, auto));
grid-gap: $verticalSpaceBetweenItems $verticalSpaceBetweenItems;
align-items: center;
>* {
&:first-child {
justify-self: start;
}
&:last-child {
justify-self: end;
}
}

