The effect you're seeing is due to the fact that HTML lays out inline-blocks (indeed all inline elements) with any amount of white-space between them recognized as a single space character with a width given by the font-size and family of the inline context.
So even though each inline-block is precisely 25% of its container's width, the spaces between them force the total width of 4 of them together to exceed 100% of the container's width, so the 4th one drops to the next line.
This is the bane of using inline-blocks for layout purposes. There are some suggestions for how to deal with this here:
Ignore whitespace in HTML. Highlights include:
- Setting the font-size of the container to 0, then resetting it on the children to what it needs to be.
- Keeping all the child elements in one line of text (line-breaks are read as white-space) with no space between them. Note: if you're using a back- or font-end templating system, there may be tools to support this so that your source code has line breaks, but what's sent or rendered in the browser does not.
- Use of HTML comments to exclude the line-breaks and tabs/spaces that you leave between between inline-blocks in your source code (inelegant and hard to maintain).
Some of the other answers to that question suggest techniques where something other than inline-blocks are used to handle the layout, e.g. float
and flex
. Those are fine, too, however there are certain aspects of inline-blocks that may make it worth the effort to get them to work, namely:
- You can use
vertical-align
property to control vertical alignment (advantage over floats)
- Items of variable height will appear predictably next to each other (advantage over float)
- The width of each element may be left to determine the spacing between each (advantage over flex)