Size and density answer different questions. Size sets the height of the control and the type inside it. Density sets the padding inside the control and the gap between controls. A small control is a shorter control with smaller type. It is not a large control with the air squeezed out.
The failure is a size named "small" that secretly means tight padding. Every layout that asks for small then gets cramped type as well. You cannot add the air back without also making the type larger. Keep the axes apart. Comfortable and compact can share one height and one type size. Only the padding and the gap change. The parent owns the gap. The children do not invent their own margins.
The demo switches Comfortable and Compact on three buttons. The type note stays on 14px. The buttons get tighter, and the words do not.
How to check it
- Switch density and measure the type. The font size and the line height stay put.
- Switch size and measure the padding. The padding and the gap stay put.
- Inspect the stack. The gap is on the parent, not a margin on each button.
.stack {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 16px;
}
.button {
height: 2.5rem;
padding-inline: 16px;
font-size: 0.875rem;
}
.stack[data-density="compact"] {
gap: 4px;
}
.stack[data-density="compact"] .button {
padding-inline: 8px;
}