fix: avoid content shift caused by scrollbar

This commit is contained in:
Björn Fromme
2026-08-17 16:14:25 +02:00
parent f00351706e
commit 8271a69f45
18 changed files with 26 additions and 18 deletions
+7
View File
@@ -0,0 +1,7 @@
@layer utilities {
/* Reserve the scrollbar gutter so content does not shift width when a
scrollbar appears (e.g. when a collapsible section is opened). */
.scroll-stable {
scrollbar-gutter: stable;
}
}
+2 -1
View File
@@ -4,4 +4,5 @@
@import "tailwindcss/components"; @import "tailwindcss/components";
@import "_components.css"; @import "_components.css";
@import "tailwindcss/utilities"; @import "tailwindcss/utilities";
@import "_utilities.css";
+1 -1
View File
@@ -19,7 +19,7 @@
</div> </div>
{# Content - toggleable on mobile, always visible on desktop #} {# Content - toggleable on mobile, always visible on desktop #}
<div class="hidden lg:block flex-1 min-h-0 bg-white shadow-lg lg:shadow-none overflow-y-auto px-4 lg:px-8 py-8" <div class="hidden lg:block flex-1 min-h-0 bg-white shadow-lg lg:shadow-none overflow-y-auto scroll-stable px-4 lg:px-8 py-8"
data-toggle-target="content"> data-toggle-target="content">
{% include 'booking/_summary_travel_info.html.twig' with { {% include 'booking/_summary_travel_info.html.twig' with {
'bookingDto': bookingDto, 'bookingDto': bookingDto,
+1 -1
View File
@@ -57,7 +57,7 @@
<div class="hidden lg:block shrink-0"> <div class="hidden lg:block shrink-0">
{% include 'booking/_pagination.html.twig' with { 'current_step': 1 } %} {% include 'booking/_pagination.html.twig' with { 'current_step': 1 } %}
</div> </div>
<div class="flex-1 overflow-y-auto px-4 lg:px-8 py-8"> <div class="flex-1 overflow-y-auto scroll-stable px-4 lg:px-8 py-8">
<h2 class="pb-4"> <h2 class="pb-4">
Unterkunft Unterkunft
</h2> </h2>
+1 -1
View File
@@ -30,7 +30,7 @@
<div class="hidden lg:block shrink-0"> <div class="hidden lg:block shrink-0">
{% include 'booking/_pagination.html.twig' with { 'current_step': 2 } %} {% include 'booking/_pagination.html.twig' with { 'current_step': 2 } %}
</div> </div>
<div class="flex-1 overflow-y-auto px-4 lg:px-8 py-8"> <div class="flex-1 overflow-y-auto scroll-stable px-4 lg:px-8 py-8">
<h2 class="pb-4"> <h2 class="pb-4">
Teilnehmer:innen Teilnehmer:innen
</h2> </h2>
@@ -27,7 +27,7 @@
<div class="hidden lg:block shrink-0"> <div class="hidden lg:block shrink-0">
{% include 'booking/_pagination.html.twig' with { 'current_step': 2 } %} {% include 'booking/_pagination.html.twig' with { 'current_step': 2 } %}
</div> </div>
<div id="main-content" class="flex-1 overflow-y-auto px-4 lg:px-8 py-8"> <div id="main-content" class="flex-1 overflow-y-auto scroll-stable px-4 lg:px-8 py-8">
{# Flash messages - must be inside main-content for HTMX swap to display them #} {# Flash messages - must be inside main-content for HTMX swap to display them #}
{% include '_partials/_flashes.html.twig' %} {% include '_partials/_flashes.html.twig' %}
{% include 'booking/_participant_form.html.twig' with { {% include 'booking/_participant_form.html.twig' with {
+1 -1
View File
@@ -32,7 +32,7 @@
<div class="hidden lg:block shrink-0"> <div class="hidden lg:block shrink-0">
{% include 'booking/_pagination.html.twig' with { 'current_step': 3 } %} {% include 'booking/_pagination.html.twig' with { 'current_step': 3 } %}
</div> </div>
<div class="flex-1 overflow-y-auto px-4 lg:px-8 py-8"> <div class="flex-1 overflow-y-auto scroll-stable px-4 lg:px-8 py-8">
<h2 class="pb-4"> <h2 class="pb-4">
Zahlungsart Zahlungsart
</h2> </h2>
+2 -2
View File
@@ -26,7 +26,7 @@
<span class="block uppercase font-semibold">Buchungsübersicht</span> <span class="block uppercase font-semibold">Buchungsübersicht</span>
</div> </div>
</div> </div>
<div class="overflow-y-auto px-4 lg:px-8 py-8"> <div class="overflow-y-auto scroll-stable px-4 lg:px-8 py-8">
{% include 'booking/_summary_travel_info.html.twig' with { {% include 'booking/_summary_travel_info.html.twig' with {
'bookingDto': bookingCreateContext.bookingDto, 'bookingDto': bookingCreateContext.bookingDto,
'summaryData': bookingCreateContext.summaryData, 'summaryData': bookingCreateContext.summaryData,
@@ -42,7 +42,7 @@
<div class="hidden lg:block shrink-0"> <div class="hidden lg:block shrink-0">
{% include 'booking/_pagination.html.twig' with { 'current_step': 4 } %} {% include 'booking/_pagination.html.twig' with { 'current_step': 4 } %}
</div> </div>
<div class="flex-1 overflow-y-auto px-4 lg:px-8 py-8"> <div class="flex-1 overflow-y-auto scroll-stable px-4 lg:px-8 py-8">
<h2 class="pb-4"> <h2 class="pb-4">
Bitte bestätige deine Buchung Bitte bestätige deine Buchung
</h2> </h2>
+1 -1
View File
@@ -42,7 +42,7 @@
</div> </div>
{# Scrollable content #} {# Scrollable content #}
<div class="flex-1 overflow-y-auto px-4 lg:px-8 py-8"> <div class="flex-1 overflow-y-auto scroll-stable px-4 lg:px-8 py-8">
{% block participant_cards %} {% block participant_cards %}
<h2 class="pb-4">Teilnehmer:innen</h2> <h2 class="pb-4">Teilnehmer:innen</h2>
+1 -1
View File
@@ -24,7 +24,7 @@
<div class="hidden lg:flex shrink-0 px-4 lg:px-8 h-16 items-center shadow-md relative z-10 bg-white"> <div class="hidden lg:flex shrink-0 px-4 lg:px-8 h-16 items-center shadow-md relative z-10 bg-white">
<h1 class="text-xl font-semibold uppercase">Buchung bearbeiten</h1> <h1 class="text-xl font-semibold uppercase">Buchung bearbeiten</h1>
</div> </div>
<div id="main-content" class="flex-1 overflow-y-auto px-4 lg:px-8 py-8"> <div id="main-content" class="flex-1 overflow-y-auto scroll-stable px-4 lg:px-8 py-8">
{# Flash messages - must be inside main-content for HTMX swap to display them #} {# Flash messages - must be inside main-content for HTMX swap to display them #}
{% include '_partials/_flashes.html.twig' %} {% include '_partials/_flashes.html.twig' %}
{% include 'booking/_participant_form.html.twig' with { {% include 'booking/_participant_form.html.twig' with {
+1 -1
View File
@@ -10,7 +10,7 @@
</div> </div>
{# Scrollable content area #} {# Scrollable content area #}
<div class="flex-1 overflow-y-auto p-4 lg:p-8 bg-primary-bg"> <div class="flex-1 overflow-y-auto scroll-stable p-4 lg:p-8 bg-primary-bg">
{% include '_partials/_flashes.html.twig' %} {% include '_partials/_flashes.html.twig' %}
<div class="space-y-8 pb-8"> <div class="space-y-8 pb-8">
@@ -26,7 +26,7 @@
</div> </div>
{# Content #} {# Content #}
<div class="hidden lg:block flex-1 min-h-0 bg-white shadow-lg lg:shadow-none overflow-y-auto px-4 lg:px-8 py-8" <div class="hidden lg:block flex-1 min-h-0 bg-white shadow-lg lg:shadow-none overflow-y-auto scroll-stable px-4 lg:px-8 py-8"
data-toggle-target="content"> data-toggle-target="content">
{# Accommodation info #} {# Accommodation info #}
+1 -1
View File
@@ -27,7 +27,7 @@
</div> </div>
{# Content #} {# Content #}
<div class="hidden lg:block flex-1 min-h-0 bg-white shadow-lg lg:shadow-none overflow-y-auto px-4 lg:px-8 py-8" <div class="hidden lg:block flex-1 min-h-0 bg-white shadow-lg lg:shadow-none overflow-y-auto scroll-stable px-4 lg:px-8 py-8"
data-toggle-target="content"> data-toggle-target="content">
{# Accommodation info #} {# Accommodation info #}
+1 -1
View File
@@ -47,7 +47,7 @@
</div> </div>
{# Main area #} {# Main area #}
<div class="flex-1 order-2 lg:order-1 lg:col-span-3 bg-white flex flex-col gap-y-8 min-h-0 overflow-y-auto px-4 lg:px-8 py-8"> <div class="flex-1 order-2 lg:order-1 lg:col-span-3 bg-white flex flex-col gap-y-8 min-h-0 overflow-y-auto scroll-stable px-4 lg:px-8 py-8">
{% include '_partials/_flashes.html.twig' %} {% include '_partials/_flashes.html.twig' %}
<hgroup> <hgroup>
+1 -1
View File
@@ -37,7 +37,7 @@
{% include 'groups/booking/_pagination.html.twig' with { 'current_step': 1 } %} {% include 'groups/booking/_pagination.html.twig' with { 'current_step': 1 } %}
</div> </div>
<div class="flex-1 overflow-y-auto px-4 lg:px-8 py-8"> <div class="flex-1 overflow-y-auto scroll-stable px-4 lg:px-8 py-8">
<h2 class="pb-2"> <h2 class="pb-2">
Gewünschter Zeitraum Gewünschter Zeitraum
+1 -1
View File
@@ -43,7 +43,7 @@
{# The scroll container itself must survive the htmx refresh — only its contents {# The scroll container itself must survive the htmx refresh — only its contents
are swapped, so assets/loading.js can restore the scroll position. #} are swapped, so assets/loading.js can restore the scroll position. #}
<div id="booking-form" <div id="booking-form"
class="flex-1 overflow-y-auto px-4 lg:px-8 py-8" class="flex-1 overflow-y-auto scroll-stable px-4 lg:px-8 py-8"
hx-post="{{ path('app_groups_booking_step_2_refresh') }}" hx-post="{{ path('app_groups_booking_step_2_refresh') }}"
hx-trigger="change delay:300ms" hx-trigger="change delay:300ms"
hx-target="#booking-form" hx-target="#booking-form"
+1 -1
View File
@@ -36,7 +36,7 @@
{% include 'groups/booking/_pagination.html.twig' with { 'current_step': 3 } %} {% include 'groups/booking/_pagination.html.twig' with { 'current_step': 3 } %}
</div> </div>
<div id="booking-form" class="flex-1 overflow-y-auto px-4 lg:px-8 py-8"> <div id="booking-form" class="flex-1 overflow-y-auto scroll-stable px-4 lg:px-8 py-8">
<h2 class="pb-4"> <h2 class="pb-4">
Persönliche Daten Persönliche Daten
</h2> </h2>
+1 -1
View File
@@ -27,7 +27,7 @@
{% include 'groups/booking/_pagination.html.twig' with { 'current_step': 4 } %} {% include 'groups/booking/_pagination.html.twig' with { 'current_step': 4 } %}
</div> </div>
<div class="flex-1 overflow-y-auto px-4 lg:px-8 py-8"> <div class="flex-1 overflow-y-auto scroll-stable px-4 lg:px-8 py-8">
<h2 class="pb-4"> <h2 class="pb-4">
Bitte bestätige deine Angaben Bitte bestätige deine Angaben
</h2> </h2>