So I have a very simple set of divs in a container.
<div class="container">
<div id="box1" class="corner"></div>
<div id="box2" class="corner right"></div>
<div id="box3" class="corner"></div>
<div id="boxAlways" class="corner right"></div>
</div>
I currently have some CSS that makes these boxes only take up half the width of the container so they display in a 2×2 grid (it works like this, but I’m unsure if I’ve got the display elements wrong):
.container {
display: block;
}
.corner {
width: 50%;
display: inline-block;
position: relative;
}
.right {
float: right
}
Finally, I have some JS that hides any boxes if they contain no text. There are some rules:
- BoxAlways ALWAYS contains text and will never disappear
- Other boxes will not have text starting from the last box, so only the following circumstances can occur:
- all three boxes can be empty
- box1 can contain text whilst box2 and 3 can be empty
- box1 and 2 can contain text whilst box3 can be empty
- all three boxes can contain text
Here’s what I want to do with the CSS, which I can’t work out. If there is an odd number of boxes, I want the box that’s on its own to fill 100% of the width instead of just 50%. I believe this requires a full rewrite of the CSS rather than just a tweak, but I can’t get my head around how this could work, but knowing how clever CSS is, I’m sure it can be done.
It must be done without fixed sizes, as this CSS will affect multiple HTML pages. If it can’t be done in the CSS, I’m sure I can do something with the JS, but didn’t want to go down that route and potentially miss a simple solution. Thanks all!
3
Answers
To achieve the layout where a single box fills 100% width when there’s an odd number of boxes, you can adjust your CSS approach. Instead of relying solely on display: inline-block, which doesn’t handle the odd/even scenario gracefully, you can use Flexbox which provides better control over layout and alignment. Here’s how you can modify your CSS:
Explanation:
Flex Container Setup:
display: flex;
on.container
makes it a flexcontainer, allowing flex items (
.corner
) to adjust their widthsbased on available space.
Flex Wrap:
flex-wrap: wrap;
allows items to wrap to the next line if there isn’t enough space horizontally.Flex Item Properties:
.corner
initially set towidth: 50%;
ensures two items per row.box-sizing: border-box;
includes padding and border in the element’s total width..right
usesmargin-left: auto;
to push items to the right within their flex container.Implementation Notes:
Adjust
.corner
styles (like padding, margins, etc.) as per your design needs. This approach avoids JavaScript for layout adjustments, leveraging CSS’s flexbox for responsive and flexible layouts.By using Flexbox, you achieve a dynamic layout that adapts to different numbers of boxes without relying on fixed widths, meeting your requirement for a flexible and responsive design.
CSS Grid can manage that. [Sizes are for demo purposes]
Since you’ve only got four boxes, the simplest thing is to just enumerate the possibilities and write the css for each. There’s only four cases and of those, and assuming you intend for box1 and boxAlways to share a row when box2 and box3 are empty, only two cases require a box to have 100% width, and in each case it’s only boxAlways that can have that 100% width.
The first case is when only box3 is empty and the other is when box1, box2, and box3 are empty. So if you’ve marked the empty boxes with a "hide" class, you can describe the selector like this:
Or, if you just want to measure emptyness, use the
:empty
pseudo-classOn the other hand, if you intend that box1 and boxAlways should remain on different rows and each of them should take up 100%, then just extend the css of the cases sightly:
I have used `display:inline-block` because that’s what you used. You can of course use flexbox or grid as suggested in the other answers if you prefer, but neither are necessary to meet the requirements.