fix: the ribbon reserved height for air above every button
The band was a round 108px while its tallest control measured 65, so each tab carried a strip of empty chrome above its buttons. Padding, gaps and the caret slot come in, the band is cut to what the controls actually need, and the style gallery stops short of the group label it was sitting on: 144px of chrome to 118px. Line-heights are pinned in px — as ratios they hand the band's height to whatever font resolves, and the group footers hang out of it.
This commit is contained in:
1 parent
d773801b43
commit
c469759e69
7 files changed
+41
-27
No files matched your search
@@ -46,13 +46,18 @@ so the split is invisible there.
|
||||
Ribbon.svelte
|
||||
├─ .ribbon-tabs File pill · quick access (save, undo, redo) · tabs · contextual tabs
|
||||
│ · spacer · document name · appearance · UI language
|
||||
└─ .ribbon-body the active tab's groups, a fixed --w-ribbon-h (108px) band
|
||||
└─ .ribbon-body the active tab's groups, a fixed --w-ribbon-h (84px) band
|
||||
```
|
||||
|
||||
The band's height never changes: it scrolls horizontally with a hidden scrollbar instead of
|
||||
collapsing groups into popovers the way Word does when the window narrows. That is the single
|
||||
biggest simplification here, and the reason two things below are necessary.
|
||||
|
||||
84px is the tallest control in any tab — Table Layout's two-line `Insert above`, 65px — plus the
|
||||
group footer and the band's padding, so no tab carries dead space above its buttons. Every metric
|
||||
feeding that sum is pinned in px, line-heights included: a ratio hands the band's height to
|
||||
whatever font resolves, and the group footers then hang out of the band.
|
||||
|
||||
A chevron in the tab strip drops the band entirely, leaving the strip (`odf-editor-ribbon-collapsed`).
|
||||
Clicking any tab brings it back — Word instead floats it over the document until the next click
|
||||
lands in the text, which is the part not built.
|
||||
@@ -86,7 +91,7 @@ at every height. A flex row cannot reserve width in part of its height, so it mo
|
||||
| `selection.ts` | `saveRange` / `withRange` — a popover steals focus, so the range is replayed before the command |
|
||||
| `fontList.svelte.ts` | Recent, web-safe and detected fonts, shared by every font picker |
|
||||
| `controls/` | Font family box, font size box, style gallery |
|
||||
| `.rb-captioned` (global.css) | Wraps a reused picker standing alone in a group: its trigger grows to the big button's 34px box and 28px glyph, so a group of pickers and a group of buttons are the same size |
|
||||
| `.rb-captioned` (global.css) | Wraps a reused picker standing alone in a group: its trigger grows to the big button's 32px box and 28px glyph, so a group of pickers and a group of buttons are the same size |
|
||||
| `tabs/` | One file per tab |
|
||||
|
||||
Reading what the selection formats is **not** here: `utils/selectionFormat.ts` answers it
|
||||
|
||||
@@ -379,14 +379,14 @@
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
padding: 5px 10px 0;
|
||||
padding: 3px 10px 0;
|
||||
}
|
||||
|
||||
.ribbon-tab {
|
||||
position: relative;
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 7px 9px 6px;
|
||||
padding: 5px 9px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
color: var(--w-text);
|
||||
font-family: inherit;
|
||||
@@ -433,7 +433,7 @@
|
||||
background: var(--w-accent-fill);
|
||||
color: #fff;
|
||||
border-radius: 4px;
|
||||
padding: 6px 16px;
|
||||
padding: 5px 14px;
|
||||
margin-right: 6px;
|
||||
font-family: inherit;
|
||||
font-size: 13px;
|
||||
@@ -448,8 +448,8 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
height: 26px;
|
||||
border: none;
|
||||
background: none;
|
||||
border-radius: 4px;
|
||||
@@ -512,7 +512,7 @@
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
height: var(--w-ribbon-h);
|
||||
padding: 6px 12px;
|
||||
padding: 3px 10px;
|
||||
/* Fixed height, scroll instead of Word's responsive group collapsing — the
|
||||
scrollbar is hidden so the band stays clean. */
|
||||
overflow-x: auto;
|
||||
|
||||
@@ -119,8 +119,8 @@
|
||||
picker beside it answer the pointer the same way. */
|
||||
.rb-big {
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
padding: 4px 7px 6px;
|
||||
gap: 2px;
|
||||
padding: 2px 6px 3px;
|
||||
}
|
||||
|
||||
.rb-big .rb-face {
|
||||
@@ -128,7 +128,7 @@
|
||||
min-height: 28px;
|
||||
flex: 1;
|
||||
border-radius: 4px;
|
||||
padding: 3px 4px;
|
||||
padding: 2px 4px;
|
||||
margin: 0 -4px;
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
.rb-small {
|
||||
gap: 5px;
|
||||
border-radius: 3px;
|
||||
padding: 3px 8px;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
|
||||
.rb-icon {
|
||||
@@ -158,14 +158,17 @@
|
||||
.rb-small.active,
|
||||
.rb-icon.active { background: var(--w-active); }
|
||||
|
||||
/* Word wraps a two-word label onto two lines; at the default line-height that
|
||||
button alone would set the band's height. */
|
||||
.rb-label {
|
||||
line-height: 14px;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* Rides closer to the label than the 4px column gap: the two read as one line. */
|
||||
.rb-stack-caret {
|
||||
display: flex;
|
||||
height: 10px;
|
||||
height: 8px;
|
||||
margin-top: -3px;
|
||||
color: var(--w-text-dim);
|
||||
}
|
||||
@@ -197,12 +200,12 @@
|
||||
and the caret under it open the menu. Icon, label and caret each get their
|
||||
own line — abreast, the caret widens the button by its own width. */
|
||||
.rb-split-col { flex-direction: column; }
|
||||
.rb-split-col .rb-big { padding: 3px 7px 0; }
|
||||
.rb-split-col .rb-big { padding: 2px 6px 0; }
|
||||
|
||||
.rb-split-col .rb-caret {
|
||||
flex-direction: column;
|
||||
width: auto;
|
||||
padding: 0 7px 2px;
|
||||
padding: 0 6px 1px;
|
||||
border-radius: 0 0 3px 3px;
|
||||
color: var(--w-text);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
padding: 2px 4px 0;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
/* Takes the slack down to a floor of two gallery tiles plus its chevron; past
|
||||
@@ -55,7 +55,7 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 2px;
|
||||
height: 15px;
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
/* Stays inside its own group, so a label longer than the controls above it reads
|
||||
@@ -64,6 +64,7 @@
|
||||
min-width: 0;
|
||||
font-family: var(--w-font);
|
||||
font-size: 11px;
|
||||
line-height: 13px;
|
||||
color: var(--w-text-dim);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
@@ -74,8 +75,8 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
border: none;
|
||||
background: none;
|
||||
border-radius: 2px;
|
||||
|
||||
@@ -123,7 +123,8 @@
|
||||
|
||||
<style>
|
||||
/* The group centres its controls; a gallery tile is Word's full-height card, so
|
||||
it opts out and fills the band instead. */
|
||||
it opts out and fills the band instead — short of the group label, which a
|
||||
tile edge would otherwise sit straight on top of. */
|
||||
.gallery-wrap {
|
||||
position: relative;
|
||||
display: flex;
|
||||
@@ -132,6 +133,7 @@
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
gap: 3px;
|
||||
margin: 2px 0 5px;
|
||||
}
|
||||
|
||||
/* Scrolls rather than wrapping, so the group keeps the band's fixed height. */
|
||||
|
||||
@@ -259,7 +259,9 @@
|
||||
width: min-content;
|
||||
white-space: normal;
|
||||
text-align: center;
|
||||
line-height: 1.15;
|
||||
/* The two lines make this the band's tallest control, so --w-ribbon-h is cut
|
||||
to fit it: a ratio would put that height at the mercy of the font. */
|
||||
line-height: 13px;
|
||||
}
|
||||
|
||||
.inserts :global(.rb-stack-caret) { display: none; }
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
--w-font: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
|
||||
/* Body height: three control rows plus the group-label row, and a big button's
|
||||
label may take two of them. A tuning knob. */
|
||||
--w-ribbon-h: 108px;
|
||||
--w-ribbon-h: 84px;
|
||||
}
|
||||
|
||||
/* Word's dark mode: the Fluent dark neutrals, and the accent lightened because
|
||||
@@ -451,8 +451,8 @@
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
padding: 4px 7px 6px;
|
||||
gap: 2px;
|
||||
padding: 2px 6px 3px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
--toolbar-btn-size: 28px;
|
||||
@@ -466,8 +466,8 @@
|
||||
.rb-captioned > * { display: flex; }
|
||||
|
||||
.rb-captioned :is(.table-trigger, .char-trigger, .dt-trigger, .tsp-trigger, .bp-trigger, .lang-picker) {
|
||||
height: 34px;
|
||||
min-height: 34px;
|
||||
height: 32px;
|
||||
min-height: 32px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -475,7 +475,7 @@
|
||||
.rb-captioned::after {
|
||||
content: '';
|
||||
display: block;
|
||||
height: 10px;
|
||||
height: 8px;
|
||||
margin-top: -3px;
|
||||
}
|
||||
|
||||
@@ -508,6 +508,7 @@
|
||||
.rb-caption {
|
||||
font-family: var(--w-font);
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
color: var(--w-text);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user