CSS sizing with min-width, max-width and box-sizing
Up to now each button has been exactly as wide as its text plus padding and border. That is fine for one button, but in a row of three, "Copy code" and "Parts list" end up narrower than "Read the guide", and the row looks uneven. This lesson adds a minimum width, a safety limit for small screens, and the box-sizing rule that makes widths mean what you expect.
The code
Put the first rule at the very top of the <style> element, above .btn-row, and add the sizing group to .btn:
/* Lesson 9: measure boxes from border to border */
*,
*::before,
*::after {
box-sizing: border-box;
}
.btn {
/* ...lessons 2 to 8 as before... */
/* Lesson 9: sizing */
min-width: 10rem;
max-width: 100%;
}
The box-sizing rule is a page-wide default, and defaults go first so every rule after them can rely on them. The selector * matches every element, and *::before and *::after cover the extra content that CSS can generate before or after an element. You will find this rule, or something very close to it, near the top of most modern stylesheets.
Sizing properties at a glance
| Property | Initial value | What the browser does with it |
|---|---|---|
width |
auto |
Sets the width; auto lets content and context decide |
min-width |
auto |
The box may grow past it but never shrinks below it |
max-width |
none |
The box may shrink below it but never grows past it |
height |
auto |
Sets the height; auto means as tall as the content needs |
min-height, max-height |
auto, none |
The same limits, vertically |
When these disagree, min-width beats max-width, and both beat width. A box with width: 5rem and min-width: 10rem ends up 10rem wide.
The difference between a fixed width and a minimum is easy to see side by side:
/* Fixed: every button exactly 10rem, long labels wrap or spill out */
.btn { width: 10rem; }
/* Flexible: at least 10rem, wider when the label needs it */
.btn { min-width: 10rem; }
We use min-width instead of width because the buttons should be at least 10rem wide but still grow when a label is long. max-width: 100% stops a button from ever being wider than its container, so on a phone a long label wraps inside the button instead of pushing it off the screen.
Height stays alone. Lesson 6 showed that the 48px comes from line-height, padding and border working together, and a fixed height would stop matching the moment the font size changed.
box-sizing, worked through
By default the browser uses box-sizing: content-box, where width and min-width measure the content area only and padding and border are added on top. Here is the arithmetic for our buttons at the default 16px font size:
| content-box (the default) | border-box | |
|---|---|---|
| min-width measures | The content only | Content, padding and border |
| Padding, left plus right | 24 + 24 = 48px, added on top | 48px, inside the 160px |
| Border, left plus right | 2 + 2 = 4px, added on top | 4px, inside the 160px |
| Smallest total width | 160 + 48 + 4 = 212px | 160px |
| Room left for the text | 160px | 160 - 48 - 4 = 108px |
With border-box, the number you write is the width you see on screen. That makes layouts far easier to plan: a box set to width: 100% with padding still fits inside its parent instead of overflowing it by the padding.
What you see, and what you do not
Reload. The <button> labeled "Copy code" grows to 160px, because browsers display buttons as inline-block and inline-block boxes accept a width. Its text stays centered, since buttons center their content by default.
The two links do not change at all. They are still inline elements, and MDN's width page lists the exception plainly: width applies to all elements except non-replaced inline elements, table rows and row groups. The same goes for min-width and max-width. Nothing is wrong with the rule; the browser is ignoring it on purpose.
That is the last of the inline surprises. The next lesson, the display property, turns the links into inline-block boxes, and the margin, padding and width you have written since lesson 2 all start to apply to them.
Common questions
Why 10rem?
It is wide enough that the short labels in this project come out the same width, so the row looks even. There is nothing special about the number. Measure your longest common label and choose a value just above it.
px, rem or percent for widths?
Use rem for sizes tied to text, like a button, and percent for sizes tied to the container, like the max-width here. A fixed px width ignores the reader's font size setting, so a button sized in px can end up too small for its own label.
Does box-sizing affect height too?
Yes. With border-box, a height or min-height also includes padding and border. We do not set a height, so it changes nothing in this project.
Try it: in the online HTML editor, wrap the box-sizing rule in /* and */ to switch it off, reload, and inspect the button: it jumps from 160px to 212px wide. Then remove the comment marks again.