Skip to content

Commit

Permalink
Prevent layout shift in <overflow-menu> items (go-gitea#29831)
Browse files Browse the repository at this point in the history
There is a small layout shift in when active tab changes. Notice how the
actions SVG is unstable:


![](https://github.com/go-gitea/gitea/assets/115237/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](https://github.com/go-gitea/gitea/assets/115237/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 <[email protected]>
  • Loading branch information
silverwind and wxiaoguang committed Mar 20, 2024
1 parent 0db1944 commit d2e7f19
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
32 changes: 21 additions & 11 deletions web_src/css/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -1778,15 +1778,6 @@ table th[data-sortt-desc] .svg {
border-color: var(--color-secondary);
}

.ui.tabular.menu .item {
padding: 11px 12px;
color: var(--color-text-light-2);
}

.ui.tabular.menu .item:hover {
color: var(--color-text);
}

.ui.tabular.menu .active.item,
.ui.tabular.menu .active.item:hover {
background: var(--color-body);
Expand All @@ -1803,17 +1794,36 @@ table th[data-sortt-desc] .svg {
border-color: var(--color-secondary);
}

.ui.tabular.menu .item,
.ui.secondary.pointing.menu .item {
padding: 11px 12px !important;
color: var(--color-text-light-2);
}

.ui.tabular.menu .item:hover,
.ui.secondary.pointing.menu a.item:hover {
color: var(--color-text);
}

.ui.secondary.pointing.menu .active.item,
.ui.secondary.pointing.menu .active.item:hover,
.ui.secondary.pointing.menu .dropdown.item:hover,
.ui.secondary.pointing.menu a.item:hover {
.ui.secondary.pointing.menu .dropdown.item:hover {
color: var(--color-text-dark);
}

.ui.tabular.menu .active.item,
.ui.secondary.pointing.menu .active.item,
.resize-for-semibold::before {
font-weight: var(--font-weight-semibold);
}

.resize-for-semibold::before {
content: attr(data-text);
visibility: hidden;
display: block;
height: 0;
}

.ui.header {
color: var(--color-text);
}
Expand Down
1 change: 1 addition & 0 deletions web_src/css/repo/header.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
flex-flow: row wrap;
justify-content: space-between;
gap: 0.5rem;
margin-bottom: 4px;
}

.repo-header .flex-item {
Expand Down
19 changes: 19 additions & 0 deletions web_src/js/webcomponents/overflow-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down

0 comments on commit d2e7f19

Please sign in to comment.