Files
op-packages/luci-theme-footstrap/styles/theme/25-progressbar.css
T

116 lines
6.0 KiB
CSS

@layer theme {
/* One thin meter for every .cbi-progressbar (overview Memory/Storage/Network, Software
* disk space, package manager …): slim rounded track, accent fill, and the LuCI title
* value floated just above the bar's right edge (mono/dim) instead of stuffed inside a fat
* pill. No per-page overrides. */
.cbi-progressbar {
position: relative;
height: 10px;
background: var(--fs-track);
border: 0;
border-radius: var(--fs-radius-pill);
overflow: visible;
min-width: 120px;
margin: 0;
}
.cbi-progressbar > div {
height: 100%;
background: var(--fs-accent);
border-radius: var(--fs-radius-pill);
transition: width var(--fs-dur-fill);
}
.cbi-progressbar::after {
content: attr(title);
/* the gap is a scale step, not a literal 4: every other gap in the theme scales with the
* density axis and this one sat outside it. Identical at the default density. */
position: absolute; inset-inline: auto 0; bottom: calc(100% + var(--fs-space-1)); top: auto;
font-family: var(--fs-font-mono); font-size: var(--fs-type-xs); font-weight: var(--fs-weight-normal);
color: var(--fs-dim); white-space: nowrap; text-shadow: none;
}
/* THE VALUE SITS BESIDE THE BAR wherever the bar already shares its line with a name.
*
* The default above puts it over the bar's far edge, and that assumes the shape the Overview has:
* the meter owns a full-width line and its name sits on the line above, so the value lands at the
* far end of that name's own line and the two read as one row. (Stock bootstrap assumes the same,
* floating the title at `top: -1.4em; left: 0`.) Two shapes are not that, and they are not each
* other either — CSS cannot ask "does this row carry its own label" — so each is named:
*
* `.cbi-value-field > .cbi-progressbar` the meter IS the field of a CBI form row, an app
* building `.cbi-value` with ui.js. Reported against luci-app-modeminfo's Antennas page:
* three such rows per card, every dBm figure reading as though it belonged to the meter above
* it, because the value lands against the row divider rather than beside its own bar.
* `.table:has(.tr.table-titles) .td …` a meter COLUMN in a multi-column data table
* (luci-app-cpu-status's per-CPU load), where the floated value lands on the row divider too.
*
* Both want the same geometry and differ in ONE number, so the geometry is written once and the
* number is the knob: `--fs-meter-value` is the room the out-of-flow value needs. A form row holds
* `-140.0 dBm`, half again as wide as the `100% (1.2 GiB)` of a table cell. The Overview and the
* package manager keep the value above the bar — their meters sit in a `.td` and a bare
* `.controls` div, which is neither shape. */
/* ONE RULE PER SHAPE, not one selector list for both, and the split is not cosmetic: the table
* half needs `:has()`, and an engine that cannot parse a selector discards the WHOLE rule —
* siblings included. Grouped, the form row (which needs nothing new) lost its placement on such
* an engine along with the cell that was unreachable there anyway. The declarations they share
* are @mirror-pinned instead, so the two copies cannot drift. */
.cbi-value-field > .cbi-progressbar {
/* @mirror meter/beside */
margin-inline-end: var(--fs-meter-value);
/* @endmirror */
--fs-meter-value: calc(var(--fs-space-10) * 2);
}
.cbi-value-field > .cbi-progressbar::after {
/* @mirror meter/beside-value */
inset-inline: calc(100% + var(--fs-space-2)) auto; bottom: auto; top: 50%;
transform: translateY(-50%);
/* @endmirror */
}
.cbi-section .table:has(.tr.table-titles) .td .cbi-progressbar {
/* @mirror meter/beside */
margin-inline-end: var(--fs-meter-value);
/* @endmirror */
--fs-meter-value: var(--fs-space-10);
/* narrower than this it stops reading as a meter at all; the column gives up the rest. */
min-width: 60px;
}
.cbi-section .table:has(.tr.table-titles) .td .cbi-progressbar::after {
/* @mirror meter/beside-value */
inset-inline: calc(100% + var(--fs-space-2)) auto; bottom: auto; top: 50%;
transform: translateY(-50%);
/* @endmirror */
}
/* ...AND BACK ABOVE THE BAR ONCE THAT COLUMN BECOMES A CARD.
*
* The rule above puts the value BESIDE the bar because a table column shares its row with other
* columns and a value floated over the bar would land on the row divider. A carded row is not
* that: `.fs-stacked` gives each cell half the card, so "beside" is outside the cell — the value
* ran across the neighbouring column and over the label above it. Reported twice from a phone
* (`RSSI: 52% (-59dBm)` sitting on SIGNAL STRENGTH and on the Transferred figures next to it),
* on luci-mod-dashboard's Wireless list, at every density.
*
* So the card puts it back where the default has it — over the bar's far edge, on the line the
* label already owns — and buys that line: the bar takes a top margin of one --fs-type-xs line,
* so the value sits between the label and the bar instead of on either. Measured at 390px on all
* three densities: 6-9px of overlap before, none after.
*
* The selector carries `:has(.tr.table-titles)` for specificity alone: that is what the beside-rule
* above matches on, and `:has()` counts its argument — (0,6,0) — so a plainer selector here lost
* and the value stayed beside the bar (measured: `margin-inline-end` still 40px). The title row
* is still in the DOM when the table is carded; the card only hides it. */
.cbi-section .table.fs-stacked:has(.tr.table-titles) .td .cbi-progressbar {
margin-inline-end: 0;
margin-block-start: calc(var(--fs-type-xs) * var(--fs-leading));
}
.cbi-section .table.fs-stacked:has(.tr.table-titles) .td .cbi-progressbar::after {
inset-inline: auto 0;
bottom: calc(100% + var(--fs-space-1));
top: auto;
transform: none;
}
/* Progressbar rows in a section table (luci-app-cpu-status): keep the native label | bar
* row, just centre the cells vertically. */
.cbi-section .table:not([id]):not(.cbi-section-table) .tr:has(.cbi-progressbar) .td { vertical-align: middle; }
}