Stacks on paper, side by side on screen.
Validation groups
Wrap a label, a control, and its message in .bf-form-group.
Touch the field with a bad value and the whole group tints while .bf-error-text appears —
:has(:user-invalid) does it, no script. The message is wired with
aria-describedby so it stays announced.
Sticky table
.bf-table-sticky is the scroll container, the pinned header,
the pinned leading column, and the fade edge in one class. The wrapper carries
tabindex="0" and a name so keyboard users can scroll it.
| Month | Revenue | Costs | Net |
|---|---|---|---|
| Jan | 12,400 | 8,100 | 4,300 |
| Feb | 11,900 | 7,950 | 3,950 |
| Mar | 14,200 | 8,400 | 5,800 |
| Apr | 13,800 | 8,350 | 5,450 |
| May | 15,600 | 9,100 | 6,500 |
| Jun | 16,100 | 9,300 | 6,800 |
The opt-in print.css flattens container layouts, restores plain tables,
prints link destinations, and hides screen-only chrome (.bf-no-print).
Open print preview to see it — on screen nothing changes.
Read the full documentation screen only
One readable column when printed.