Skip to content

Commit bfef8ab

Browse files
committed
style: styling improvements
1 parent 80b3292 commit bfef8ab

3 files changed

Lines changed: 59 additions & 25 deletions

File tree

static/css/v3/content-modal.css

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
* .dialog-modal.content-modal — full-screen overlay (hidden by default)
1010
* .dialog-modal__backdrop — close link covering the overlay
1111
* .content-modal__container — centered card (role="dialog")
12-
* .content-modal__header — top row: prev/next + title + close
13-
* .content-modal__header-main — left cluster (carousel buttons + title)
12+
* .content-modal__header — top row: close + title + prev/next
13+
* (title wraps to its own row on mobile)
1414
* .content-modal__title — heading text
1515
* .content-modal__close — close (×) link, top-right of card
1616
* .content-modal__subtitle — byline / secondary text row
@@ -38,34 +38,30 @@
3838
}
3939

4040
/* ============================================
41-
HEADER (prev/next + title on the left, close on the right)
41+
HEADER (close on the left, title in the middle, prev/next on the right)
4242
============================================ */
4343
.content-modal__header {
4444
flex: 0 0 auto;
4545
display: flex;
4646
align-items: center;
47-
justify-content: space-between;
48-
gap: var(--space-large);
4947
padding: 0 var(--space-large);
5048
}
5149

52-
.content-modal__header-main {
53-
display: flex;
54-
align-items: center;
55-
gap: var(--space-large);
56-
min-width: 0;
57-
}
58-
5950
.content-modal__title {
60-
margin: 0;
51+
flex: 1 1 auto;
52+
min-width: 0;
53+
margin: 0 var(--space-large);
6154
padding: 0;
6255
font-family: var(--font-display);
6356
font-size: var(--font-size-large);
6457
font-weight: var(--font-weight-medium);
6558
line-height: var(--line-height-tight);
6659
letter-spacing: var(--letter-spacing-display-regular);
6760
color: var(--color-text-primary);
68-
min-width: 0;
61+
}
62+
63+
.content-modal__header .carousel-buttons {
64+
flex-shrink: 0;
6965
}
7066

7167
/* ============================================
@@ -284,11 +280,28 @@
284280
max-width: calc(100vw - 2 * var(--space-default));
285281
max-height: calc(100vh - 2 * var(--space-large));
286282
border-radius: var(--border-radius-l);
287-
gap: var(--space-default);
283+
gap: var(--space-large);
284+
}
285+
286+
/* Wrap the title onto its own row, leaving close + carousel on row 1.
287+
`order: 1` pushes it after both siblings; `flex-basis: 100%` forces a wrap.
288+
Negative horizontal margin lets the divider above the title span the
289+
full container width past the header's left/right padding. */
290+
.content-modal__header {
291+
flex-wrap: wrap;
292+
row-gap: var(--space-large);
293+
}
294+
295+
.content-modal__header .carousel-buttons {
296+
margin-left: auto;
288297
}
289298

290299
.content-modal__title {
291-
font-size: var(--font-size-medium);
300+
order: 1;
301+
flex-basis: 100%;
302+
margin: 0 calc(-1 * var(--space-large));
303+
padding: var(--space-large) var(--space-large) 0;
304+
border-top: 1px solid var(--color-stroke-weak);
292305
}
293306

294307
.content-modal__subtitle {

static/css/v3/dialog.css

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,29 @@
3939
display: flex !important;
4040
}
4141

42+
/* Reserve the scrollbar gutter permanently so removing the scrollbar (via
43+
the scroll-lock rule below) doesn't reflow the page horizontally. */
44+
html {
45+
scrollbar-gutter: stable;
46+
}
47+
48+
/* Third-party scroll-lock libraries (e.g.Boost Gecko search widget)
49+
add inline padding-right to <body> to compensate for a
50+
disappearing scrollbar. Our html-level scrollbar-gutter already reserves
51+
that space, so the third-party compensation is double-padding and shifts
52+
the page. Force body padding-right to zero to neutralise it. */
53+
body {
54+
padding-right: 0 !important;
55+
}
56+
57+
/* Lock background page scroll while any dialog is open. CSS-only via :has(),
58+
so it works without JavaScript. Covers both hash-based dialogs
59+
(.dialog-modal:target) and checkbox-based ones (library filter). */
60+
html:has(.dialog-modal:target),
61+
html:has(.library-filter__toggle:checked) {
62+
overflow: hidden;
63+
}
64+
4265
/* ============================================
4366
BACKDROP CLOSE LINK
4467
Fills the overlay; clicking outside the container closes the dialog.

templates/v3/includes/_content_modal.html

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,13 @@
2424
aria-modal="true"
2525
aria-labelledby="{{ modal_id }}-title">
2626
<div class="content-modal__header">
27-
<div class="content-modal__header-main">
28-
<a class="content-modal__close"
29-
role="button"
30-
href="{{ close_url|default:'#_' }}"
31-
aria-label="Close">
32-
{% include "includes/icon.html" with icon_name="close" icon_class="content-modal__close-icon" icon_size=24 %}
33-
</a>
34-
<h2 class="content-modal__title" id="{{ modal_id }}-title">{{ title }}</h2>
35-
</div>
27+
<a class="content-modal__close"
28+
role="button"
29+
href="{{ close_url|default:'#_' }}"
30+
aria-label="Close">
31+
{% include "includes/icon.html" with icon_name="close" icon_class="content-modal__close-icon" icon_size=24 %}
32+
</a>
33+
<h2 class="content-modal__title" id="{{ modal_id }}-title">{{ title }}</h2>
3634
{% include "v3/includes/_carousel_buttons.html" with as_links=True prev_url=prev_url|default:"" next_url=next_url|default:"" only %}
3735
</div>
3836
{% if subtitle %}

0 commit comments

Comments
 (0)