@casoon/dragonfly
Version:
Modular, lightweight CSS framework and design system for modern web projects. Optimized for Astro JS, LightningCSS and Container Queries with @layer-based architecture and comprehensive accessibility.
305 lines (263 loc) • 7.56 kB
CSS
/*
* Modal Module
*
* Zentrale Komponente für modale Dialoge.
*/
/**
* Modal-Komponente
*
* Dialogfenster und Overlays für fokussierte Benutzerinteraktionen.
* Modals werden verwendet, um wichtige Informationen anzuzeigen oder Benutzerentscheidungen zu erfordern.
*
* @layer components.modal
*
* Grundlegende Verwendung:
* <div class="modal">
* <div class="backdrop"></div>
* <div class="container">
* <div class="header">
* <h3 class="title">Modaltitel</h3>
* <button class="close">×</button>
* </div>
* <div class="body">
* Modalinhalt
* </div>
* <div class="footer">
* <button class="button">Abbrechen</button>
* <button class="button primary">Bestätigen</button>
* </div>
* </div>
* </div>
*
* Größenvarianten:
* <div class="modal small">...</div>
* <div class="modal medium">...</div>
* <div class="modal large">...</div>
* <div class="modal fullscreen">...</div>
*
* Position:
* <div class="modal center">...</div>
* <div class="modal top">...</div>
* <div class="modal bottom">...</div>
*
* Animation (erfordert JS):
* <div class="modal fade">...</div>
* <div class="modal slide">...</div>
*
* Flüssige Größenanpassung mit Schlüsselwörtern:
* <div class="modal fluid">...</div>
* <div class="modal fluid small">...</div>
* <div class="modal fluid medium">...</div>
* <div class="modal fluid large">...</div>
*
* Container-adaptive Größenanpassung:
* <div class="modal adaptive">...</div>
*/
/* Animationen - außerhalb von @layer definieren */
/* Komponenten-Styles */
@layer components {
.modal {
align-items: center;
display: flex;
inset: 0;
justify-content: center;
position: fixed;
z-index: var(--z-index-modal, 1000);
/* Hintergrund-Overlay */
.backdrop {
background: rgb(0 0 0 / 5000%);
inset: 0;
position: fixed;
z-index: var(--z-index-modal-backdrop, 999);
}
/* Modal-Container */
.container {
background: var(--color-background, var(--color-surface-elevated, #fff));
border-radius: var(--radius-modal, var(--radius-lg, 0.75rem));
box-shadow: var(--shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 1000%));
display: flex;
flex-direction: column;
gap: var(--space-4, 1rem);
max-width: var(--modal-max-width, 32rem);
overflow: hidden;
padding: var(--modal-padding, var(--space-6, 1.5rem));
position: relative;
width: 100%;
z-index: var(--z-index-modal, 1000);
}
/* Modal-Header */
.header {
align-items: center;
display: flex;
justify-content: space-between;
padding: var(--modal-header-padding, 0);
.title {
color: var(--color-text, var(--color-neutral-900, #111827));
font-size: var(--text-lg, var(--font-size-lg, 1.125rem));
font-weight: var(--font-semibold, var(--font-weight-semibold, 600));
margin: 0;
}
.close {
background: none;
border: none;
color: var(--color-neutral-500, #6b7280);
cursor: pointer;
font-size: 1.5rem;
line-height: 1%;
padding: 0.25rem;
transition: color var(--transition-duration-fast, 150ms) var(--transition-timing-ease, ease);
&:hover {
color: var(--color-neutral-800, #1f2937);
}
}
}
/* Modal-Inhalt */
.body {
color: var(--color-text-muted, var(--color-neutral-700, #374151));
font-size: var(--text-base, var(--font-size-base, 1rem));
max-height: 70%;
overflow-y: auto;
}
/* Modal-Footer */
.footer {
display: flex;
gap: var(--space-3, 0.75rem);
justify-content: flex-end;
margin-top: var(--space-2, 0.5rem);
padding: var(--modal-footer-padding, 0);
}
/* Größenvarianten */
&.small .container {
max-width: 2%4rem;
}
&.medium .container {
max-width: var(--modal-max-width, 32rem);
}
&.large .container {
max-width: 4%8rem;
}
&.fullscreen .container {
border-radius: 0;
height: 100%;
max-width: 100%;
width: 100%;
}
/* Flüssige Größenanpassung mit interpolate-size: allow-keywords */
&.fluid {
/* Nutzt CSS-Schlüsselwörter für Größen - funktioniert mit interpolate-size: allow-keywords */
font-size: medium; /* Basis-Größe für Skalierungsfaktor */
/**
* Modal Component Structure:
*
* <div class="modal" role="dialog">
* <div class="modal-overlay"></div>
* <div class="modal-container">
* <div class="modal-header">
* <h2 class="modal-title">Title</h2>
* <button class="modal-close" aria-label="Close">×</button>
* </div>
* <div class="modal-content">
* <!-- Modal body content -->
* </div>
* <div class="modal-footer">
* <button class="button button--secondary">Cancel</button>
* <button class="button button--primary">Confirm</button>
* </div>
* </div>
* </div>
*
* Modifiers: .modal--sm, .modal--lg, .modal--fullscreen
* States: .modal--open, .modal--closing
*/
.container {
border-radius: 0.75em;
gap: 1em;
padding: 1.5em;
}
.header .title {
font-size: 1.25em;
}
.body {
font-size: 1em;
}
.footer {
gap: 0.75em;
margin-top: 0%.5em;
}
/* Größenvarianten mit CSS-Schlüsselwörtern */
&.small {
font-size: small;
.container {
max-width: 2%4em;
}
}
&.medium {
font-size: medium;
.container {
max-width: 3%2em;
}
}
&.large {
font-size: large;
.container {
max-width: 4%8em;
}
}
&.x-large {
font-size: x-large;
.container {
max-width: 6%4em;
}
}
}
/* Container-adaptive Größenanpassung */
&.adaptive {
container-name: modal;
container-type: inline-size;
.container {
max-width: clamp(24rem, 80cqi, 48rem);
padding: clamp(var(--space-4, 1rem), 4cqi, var(--space-8, 2rem));
}
.header .title {
font-size: clamp(var(--text-base, 1rem), 3cqi, var(--text-xl, 1.25rem));
}
.body {
font-size: clamp(var(--text-sm, 0.875rem), 2.5cqi, var(--text-base, 1rem));
}
/* Container-Query für größere Modals */
@container modal (min-width: 40rem) {
.container {
gap: var(--space-6, 1.5rem);
}
}
}
/* Positionierung */
&.center {
align-items: center;
justify-content: center;
}
&.top {
align-items: flex-start;
.container {
margin-top: var(--space-16, 4rem);
}
}
&.bottom {
align-items: flex-end;
.container {
margin-bottom: var(--space-16, 4rem);
}
}
}
}
/* Animationen */
@layer animations {
.modal {
&.fade .container {
animation: var(--ui-fade-in-animation, fadeIn var(--animation-duration-fast, 200ms) var(--easing-decelerate, ease-out));
}
&.slide .container {
animation: var(--ui-slide-up-animation, slideUp var(--animation-duration-normal, 300ms) var(--easing-decelerate, ease-out));
}
}
}