Files
Gitea/web_src/css/modules/label.css
T
silverwind 5c69d5710a fix(ui): consistent spacing between labels (#40261) (#40330)
Backport https://github.com/go-gitea/gitea/pull/40261

The issue reference popup showed its labels without any spacing, and the
other label lists each used their own gap, with wrapped rows spaced
differently from columns.

`.labels-list` is now a wrapping flex list with `--gap-inline` by
default, giving the popup, issue sidebar and project cards equal gaps in
both directions. Lists inline with text, in issue list titles and
timeline events, stay inline so their labels still wrap one by one.

<img width="600" alt="Issue reference popup, issue sidebar and issue
list labels, before and after"
src="https://github.com/user-attachments/assets/fc4f0b9e-2b9d-4060-a2fb-c1bd3b7391db"
/>

Assisted-by: Claude Code:claude-opus-5-5
2026-11-11 14:39:45 +00:00

308 lines
7.3 KiB
CSS

/* based on Fomantic UI label module, with just the parts extracted that we use. If you find any
unused rules here after refactoring, please remove them. */
.ui.label {
display: inline-flex;
align-items: center;
vertical-align: middle;
gap: var(--gap-inline);
min-width: 0;
max-width: 100%;
background: var(--color-label-bg);
color: var(--color-label-text);
padding: 2px 6px;
font-size: var(--font-size-label);
font-weight: var(--font-weight-medium);
border: 0 solid transparent;
border-radius: var(--border-radius);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
a.ui.label {
cursor: pointer;
}
.ui.label > .icon {
width: auto;
margin: 0 0.75em 0 0;
}
.ui.label > .detail {
font-weight: var(--font-weight-medium);
margin-left: 0.5em; /* our .ui.label already provides flex gap, so the margin here shouldn't be too large */
opacity: 0.8;
}
.ui.label > .delete.icon {
cursor: pointer;
font-size: 0.92857143em;
opacity: 0.5;
}
.ui.label > .delete.icon:hover {
opacity: 1;
}
.ui.label:not(.icon) > .delete.icon {
margin: 0 0 0 0.5em;
}
a.ui.label:hover {
background: var(--color-label-hover-bg);
border-color: var(--color-label-hover-bg);
color: var(--color-label-text);
}
.ui.basic.label {
background: var(--color-button);
border: 1px solid var(--color-light-border);
color: var(--color-text-light);
}
a.ui.basic.label:hover {
text-decoration: none;
color: var(--color-text);
border-color: var(--color-secondary-dark-2);
background: var(--color-hover);
}
.ui.ui.ui.primary.label {
background: var(--color-primary);
border-color: var(--color-primary-dark-2);
color: var(--color-primary-contrast);
}
a.ui.ui.ui.primary.label:hover {
background: var(--color-primary-dark-3);
border-color: var(--color-primary-dark-3);
color: var(--color-primary-contrast);
}
.ui.ui.ui.basic.primary.label {
background: transparent;
border-color: var(--color-primary);
color: var(--color-primary);
}
a.ui.ui.ui.basic.primary.label:hover {
background: var(--color-hover);
border-color: var(--color-primary-dark-1);
color: var(--color-primary-dark-1);
}
.ui.ui.ui.red.label {
background: var(--color-red);
border-color: var(--color-red);
color: var(--color-white);
}
a.ui.ui.ui.red.label:hover {
background: var(--color-red-dark-1);
border-color: var(--color-red-dark-1);
color: var(--color-white);
}
.ui.ui.ui.basic.red.label {
background: transparent;
border-color: var(--color-red);
color: var(--color-red);
}
a.ui.ui.ui.basic.red.label:hover {
background: transparent;
border-color: var(--color-red-dark-1);
color: var(--color-red-dark-1);
}
.ui.ui.ui.orange.label {
background: var(--color-orange);
border-color: var(--color-orange);
color: var(--color-white);
}
a.ui.ui.ui.orange.label:hover {
background: var(--color-orange-dark-1);
border-color: var(--color-orange-dark-1);
color: var(--color-white);
}
.ui.ui.ui.basic.orange.label {
background: transparent;
border-color: var(--color-orange);
color: var(--color-orange);
}
a.ui.ui.ui.basic.orange.label:hover {
background: transparent;
border-color: var(--color-orange-dark-1);
color: var(--color-orange-dark-1);
}
.ui.ui.ui.yellow.label {
background: var(--color-yellow);
border-color: var(--color-yellow);
color: var(--color-white);
}
a.ui.ui.ui.yellow.label:hover {
background: var(--color-yellow-dark-1);
border-color: var(--color-yellow-dark-1);
color: var(--color-white);
}
.ui.ui.ui.basic.yellow.label {
background: transparent;
border-color: var(--color-yellow);
color: var(--color-yellow);
}
a.ui.ui.ui.basic.yellow.label:hover {
background: transparent;
border-color: var(--color-yellow-dark-1);
color: var(--color-yellow-dark-1);
}
.ui.ui.ui.green.label {
background: var(--color-green);
border-color: var(--color-green);
color: var(--color-white);
}
a.ui.ui.ui.green.label:hover {
background: var(--color-green-dark-1);
border-color: var(--color-green-dark-1);
color: var(--color-white);
}
.ui.ui.ui.basic.green.label {
background: transparent;
border-color: var(--color-green);
color: var(--color-green);
}
a.ui.ui.ui.basic.green.label:hover {
background: transparent;
border-color: var(--color-green-dark-1);
color: var(--color-green-dark-1);
}
.ui.ui.ui.purple.label {
background: var(--color-purple);
border-color: var(--color-purple);
color: var(--color-white);
}
a.ui.ui.ui.purple.label:hover {
background: var(--color-purple-dark-1);
border-color: var(--color-purple-dark-1);
color: var(--color-white);
}
.ui.ui.ui.grey.label {
background: var(--color-label-bg);
border-color: var(--color-label-bg);
color: var(--color-label-text);
}
a.ui.ui.ui.grey.label:hover {
background: var(--color-label-hover-bg);
border-color: var(--color-label-hover-bg);
color: var(--color-white);
}
/* "horizontal label" is actually "fat label" which has enough padding spaces to be used standalone in headers */
.ui.horizontal.label {
margin: 0 0.5em 0 0;
padding: 0.4em 0.833em;
min-width: 3em;
text-align: center;
}
.ui.circular.label {
min-width: 2em;
min-height: 2em;
padding: 0.5em !important;
line-height: 1;
text-align: center;
border-radius: 500rem;
justify-content: center;
}
.ui.mini.label {
font-size: 0.64285714rem;
}
.ui.tiny.label {
font-size: 0.71428571rem;
}
.ui.small.label {
font-size: 0.78571429rem;
}
.ui.large.label {
font-size: 1rem;
}
/* labels-list layout: span.labels-list > a.item > span.ui.label,
by default, the labels list is rendered as a wrapping flex list,
lists flowing inline with text (issue title, comment event) are rendered as "display: inline" below */
.labels-list {
display: flex;
flex-wrap: wrap;
gap: var(--gap-inline);
font-size: var(--font-size-label); /* must match the label font size, otherwise the height mismatches */
}
.labels-list > .item {
max-width: 100%; /* for ellipsis */
}
.labels-list a:hover {
text-decoration: none;
}
.labels-list .ui.label {
display: flex; /* block-level, so items have no line box and wrapped rows get the same gap as columns */
min-height: 20px;
padding-top: 0;
padding-bottom: 0;
}
#issue-list .labels-list,
.timeline-item .labels-list {
display: inline;
}
#issue-list .labels-list .ui.label,
.timeline-item .labels-list .ui.label {
display: inline-flex;
}
/* to align with different font sizes, these styles need to be written separately */
#issue-list .labels-list > .item {
margin-right: var(--gap-inline); /* margin-right (not margin-left) keeps wrapped labels left-aligned */
vertical-align: 2.5px; /* compensates inline-flex baseline so labels center with text */
}
.timeline-item .labels-list > .item {
margin-right: var(--gap-inline);
vertical-align: 1.5px;
}
/* Scoped labels with different colors on left and right */
.ui.label.scope-parent {
background: none !important;
padding: 0 !important;
gap: 0 !important;
}
.ui.label.scope-parent > .ui.label {
margin: 0 !important; /* scoped label's margin is handled by the parent */
}
.ui.label.scope-left {
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
.ui.label.scope-middle {
border-radius: 0;
}
.ui.label.scope-right {
border-bottom-left-radius: 0;
border-top-left-radius: 0;
}
.ui.label.archived-label {
filter: grayscale(0.5);
opacity: 0.5;
}
@media (forced-colors: active) {
.ui.label {
outline: 1px solid CanvasText;
outline-offset: -1px;
}
}