1
0
Fork 0
forked from forgejo/forgejo

[PORT] gitea#29831: Prevent layout shift in <overflow-menu> items

There is a small layout shift in when active tab changes. Notice how the
actions SVG is unstable:

![](a6928e89-5d47-4a91-8f36-1fa22fddbce7)

This is because the active item with bold text is wider then the
inactive one. I have applied [this
trick](https://stackoverflow.com/a/32570813/808699) to prevent this
layout shift. It's only active inside `<overflow-menu>` because I wanted
to avoid changing HTML and doing it in regular JS would cause a flicker.
I don't expect us to introduce other similar menus without
`<overflow-menu>`, so that place is likely fine.

![after](d6089924-8de6-4ee0-8db4-15f16069a131)

I also changed the weight from 500 to 600, slightly reduced horizontal
padding, merged some tab-bar related CSS rules and a added a small
margin below repo-header so it does not look so crammed against the
buttons on top.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>

---

Conflict resolution: Moved an `:focus` selector to the new CSS rule.
Ref: https://codeberg.org/forgejo/forgejo/issues/2776
(cherry picked from commit 99d7ef50917e8d61798715e1b0b3dc1a99709f27)
This commit is contained in:
silverwind 2024-03-20 18:00:35 +01:00 committed by Gusted
parent a11116602e
commit 18d13000e9
No known key found for this signature in database
GPG key ID: FD821B732837125F
3 changed files with 41 additions and 11 deletions

View file

@ -127,6 +127,25 @@ window.customElements.define('overflow-menu', class extends HTMLElement {
});
init() {
// for horizontal menus where fomantic boldens active items, prevent this bold text from
// enlarging the menu's active item replacing the text node with a div that renders a
// invisible pseudo-element that enlarges the box.
if (this.matches('.ui.secondary.pointing.menu, .ui.tabular.menu')) {
for (const item of this.querySelectorAll('.item')) {
for (const child of item.childNodes) {
if (child.nodeType === Node.TEXT_NODE) {
const text = child.textContent.trim(); // whitespace is insignificant inside flexbox
if (!text) continue;
const span = document.createElement('span');
span.classList.add('resize-for-semibold');
span.setAttribute('data-text', text);
span.textContent = text;
child.replaceWith(span);
}
}
}
}
// ResizeObserver triggers on initial render, so we don't manually call `updateItems` here which
// also avoids a full-page FOUC in Firefox that happens when `updateItems` is called too soon.
this.resizeObserver = new ResizeObserver((entries) => {