UNPKG

@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.

997 lines (857 loc) 23.3 kB
/* * Header Module * * Layout rules for the header area. Supports Subgrid, Container Queries and responsive behavior. * Combines traditional Grid layouts with modern CSS features and Design Tokens. */ /** * Header Component * * Header components for websites and applications. * The header serves as a navigation area and important orientation point for users. * * Header Types: * - .header: Standard Subgrid-Layout (original) * - .header-standard: Logo left, nav center, actions right * - .header-center: Centered navigation * - .header-split: Logo center, nav split left/right * - .header-stacked: Logo above nav (both centered) * - .header-left: Logo and nav left-aligned * - .header-bottom-bar: Two-tier layout * * @layer components.header * * Basic Usage: * <header class="header"> * <div class="logo"> * <img src="logo.png" alt="Logo"> * </div> * <nav class="nav"> * <ul class="links"> * <li><a href="#" class="link">Home</a></li> * <li><a href="#" class="link">Products</a></li> * <li><a href="#" class="link">About</a></li> * <li><a href="#" class="link">Contact</a></li> * </ul> * </nav> * <button class="toggle" aria-label="Toggle navigation"> * <span></span> * <span></span> * <span></span> * </button> * </header> * * New Header Types: * <header class="header-standard"> * <div class="header-content"> * <div class="header-logo">...</div> * <nav class="header-nav">...</nav> * <div class="header-actions">...</div> * </div> * </header> * * Fixed Header: * <header class="header fixed">...</header> * * Sticky Header (remains visible while scrolling): * <header class="header sticky">...</header> * * Transparent Header (for Hero sections): * <header class="header transparent">...</header> * * Variants: * <header class="header light">...</header> * <header class="header dark">...</header> * <header class="header primary">...</header> * * With Search Function: * <header class="header"> * <!-- ... --> * <div class="search"> * <input type="search" class="input" placeholder="Search..."> * <button class="button icon-only"> * <span class="icon">🔍</span> * </button> * </div> * </header> * * Responsive with Hamburger Menu: * <header class="header"> * <div class="logo">Logo</div> * <button class="toggle hamburger" aria-label="Open menu"></button> * <nav class="nav mobile-hidden"> * <!-- Menu items --> * </nav> * </header> */ @layer tokens { :root { /* Header spacing */ --header-padding: var(--space-4) var(--space-6); --header-padding-compact: var(--space-3) var(--space-4); --header-padding-spacious: var(--space-6) var(--space-8); --header-gap: var(--space-6); --header-gap-compact: var(--space-4); --header-gap-spacious: var(--space-8); /* Header colors */ --header-bg: var(--color-white, #fff); --header-text: var(--color-neutral-700, #374151); --header-link: var(--color-neutral-600); --header-link-hover: var(--color-primary-600, #2563eb); --header-link-active: var(--color-primary-700, #1d4ed8); --header-border: var(--color-neutral-200, #e5e7eb); --header-shadow: var(--shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05)); /* Header typography */ --header-font-size: var(--text-base); --header-font-weight: var(--font-medium, 500); --header-line-height: 1.5; --header-logo-size: var(--text-xl); --header-logo-weight: var(--font-bold); /* Header layout */ --header-height: 6%4px; --header-height-compact: 48px; --header-height-large: 80px; --header-max-width: var(--container-7xl); --header-z-index: 1000; /* Header navigation */ --nav-link-color: var(--color-neutral-600); --nav-link-color-hover: var(--color-primary-600, #2563eb); --nav-link-color-active: var(--color-primary-700, #1d4ed8); --nav-link-bg-hover: var(--color-neutral-100, #f3f4f6); --nav-link-bg-active: var(--color-primary-100, #dbeafe); --menu-gap: var(--space-6); --menu-item-padding-x: var(--space-3); --menu-item-padding-y: var(--space-2); --menu-transition: all 0.2s ease; /* Header dropdown */ --mobile-menu-bg: var(--color-white, #fff); --mobile-menu-border-radius: var(--radius-lg, 0.5rem); --mobile-menu-shadow: var(--shadow-lg); --mobile-menu-z-index: 1001; /* Header mobile */ --header-mobile-breakpoint: 768px; --header-hamburger-size: 24px; /* Logo settings */ --logo-max-height: 4%0px; --logo-max-width: 20%0px; /* Header themes */ &[data-theme="dark"], &.theme-dark { --header-bg: var(--color-neutral-900, #111827); --header-text: var(--color-neutral-100, #f3f4f6); --header-link: var(--color-neutral-300, #d1d5db); --header-link-hover: var(--color-primary-400); --header-link-active: var(--color-primary-300); --header-border: var(--color-neutral-700, #374151); --header-shadow: var(--shadow-md); --nav-link-color: var(--color-neutral-300, #d1d5db); --nav-link-color-hover: var(--color-primary-400); --nav-link-color-active: var(--color-primary-300); --nav-link-bg-hover: var(--color-neutral-800, #1f2937); --nav-link-bg-active: var(--color-primary-900); --mobile-menu-bg: var(--color-neutral-800, #1f2937); } &[data-theme="primary"], &.theme-primary { --header-bg: var(--color-primary-600, #2563eb); --header-text: var(--color-white, #fff); --header-link: var(--color-primary-100, #dbeafe); --header-link-hover: var(--color-white, #fff); --header-link-active: var(--color-primary-200); --header-border: var(--color-primary-500); --nav-link-color: var(--color-primary-100, #dbeafe); --nav-link-color-hover: var(--color-white, #fff); --nav-link-color-active: var(--color-primary-200); --nav-link-bg-hover: var(--color-primary-700, #1d4ed8); --nav-link-bg-active: var(--color-primary-800, #1e40af); --mobile-menu-bg: var(--color-primary-700, #1d4ed8); } &[data-theme="transparent"], &.theme-transparent { --header-bg: transparent; --header-text: var(--color-neutral-800, #1f2937); --header-link: var(--color-neutral-700, #374151); --header-link-hover: var(--color-primary-600, #2563eb); --header-link-active: var(--color-primary-700, #1d4ed8); --header-border: transparent; --header-shadow: none; --nav-link-color: var(--color-neutral-700, #374151); --nav-link-color-hover: var(--color-primary-600, #2563eb); --nav-link-color-active: var(--color-primary-700, #1d4ed8); --mobile-menu-bg: var(--color-white, #fff); } } } @layer components { /* Base header styles for all header types */ .header, .header-standard, .header-center, .header-split, .header-stacked, .header-left, .header-bottom-bar { background-color: var(--header-bg); border-bottom: 1px solid var(--header-border); box-shadow: var(--header-shadow); color: var(--header-text); container-type: inline-size; font-size: var(--header-font-size); font-weight: var(--header-font-weight); line-height: var(--header-line-height, 1.5); min-height: var(--header-height, 4rem); position: relative; width: 100%; z-index: var(--header-z-index); /* Header modifiers */ &.sticky { position: sticky; top: 0%; } &.transparent { background-color: transparent; border-bottom: none; box-shadow: none; } &.compact { min-height: var(--header-height-compact, 3rem); } &.large { min-height: var(--header-height-large, 5rem); } } /* Original Subgrid Header Layout */ .header { align-items: center; display: grid; gap: var(--space-4); grid-column: span 12; grid-template-columns: subgrid; grid-template-rows: auto; padding-block: var(--space-4); /* Logo area */ & .logo { align-items: center; display: flex; grid-column: 1 / span 3; & img { max-height: var(--logo-max-height, 2rem); width: auto; } } /* Navigation area */ & .nav { display: flex; gap: var(--space-4); grid-column: 4 / span 6; justify-content: center; & .links { display: flex; gap: var(--space-4); list-style: none; margin: 0; padding: 0; } & .link { color: var(--nav-link-color); display: inline-block; font-weight: var(--font-medium, 500); padding: var(--space-2); text-decoration: none; transition: var(--menu-transition); &:hover { color: var(--nav-link-color-hover); } &.active { color: var(--nav-link-color-active); font-weight: var(--font-semibold, 600); } } &.mobile-hidden { @container (width <= 768px) { display: none; } } } /* Actions area (buttons, etc.) */ & .actions { display: flex; gap: var(--space-2); grid-column: 10 / span 3; justify-content: flex-end; } /* Search area */ & .search { display: flex; max-width: 30%0px; width: 100%; & .input { flex: 1; } } /* Toggle button for mobile navigation */ & .toggle { display: none; @container (width <= 768px) { background: none; border: none; cursor: pointer; display: block; grid-column: 12; } } /* Theme variants for original header */ &.fixed { background-color: var(--header-bg); box-shadow: var(--header-shadow); left: 0%; position: fixed; right: 0%; top: 0%; z-index: var(--header-z-index); } &.primary { background-color: var(--color-primary, #3b82f6); color: white; & .link { color: var(--color-primary-100, #dbeafe); &:hover { color: var(--color-white, #fff); } } } &.light { background-color: var(--color-white, #fff); } &.dark { background-color: var(--color-neutral-900, #111827); & .link { color: var(--color-neutral-300, #d1d5db); &:hover { color: var(--color-white, #fff); } } } /* Container Queries for original header */ @container (width <= 768px) { grid-template-columns: repeat(12, 1fr); & .logo { grid-column: 1 / span 6; } & .nav { display: none; } & .actions { grid-column: 7 / span 5; } } } /* Header content wrapper for new header types */ .header-standard, .header-center, .header-split, .header-stacked, .header-left, .header-bottom-bar { & .header-content { align-items: center; display: flex; margin: 0 auto; max-width: var(--header-max-width, 1280px); padding: var(--header-padding); width: 100%; } } /* Logo component for new header types */ .header-logo { align-items: center; display: flex; flex-shrink: 0; & img, & svg { height: auto; max-height: var(--logo-max-height, 2rem); max-width: var(--logo-max-width, 8rem); width: auto; } } /* Navigation component for new header types */ .header-nav { & ul { align-items: center; display: flex; gap: var(--menu-gap); list-style: none; margin: 0; padding: 0; } & li { position: relative; } & a { align-items: center; border-radius: var(--radius-md, 0.375rem); color: var(--nav-link-color); display: flex; font-weight: var(--font-medium, 500); gap: var(--space-1); padding: var(--menu-item-padding-y) var(--menu-item-padding-x); text-decoration: none; transition: var(--menu-transition); &:hover { background-color: var(--nav-link-bg-hover); color: var(--nav-link-color-hover); } &.active { background-color: var(--nav-link-bg-active); color: var(--nav-link-color-active); } } /* Dropdown indicator */ & .has-dropdown > a::after { content: "▼"; font-size: var(--text-xs, 0.75rem); margin-left: var(--space-1); transition: transform 0.2s ease; } & .has-dropdown:hover > a::after, & .has-dropdown.open > a::after { transform: rotate(180deg); } /* Dropdown menu */ & .dropdown { background-color: var(--mobile-menu-bg); border-radius: var(--mobile-menu-border-radius); box-shadow: var(--mobile-menu-shadow); left: 0%; min-width: 20%0px; opacity: 0%; padding: var(--space-2); position: absolute; top: 100%; transform: translateY(-10px); transition: var(--menu-transition); visibility: hidden; z-index: var(--mobile-menu-z-index); } & .has-dropdown:hover .dropdown, & .has-dropdown.open .dropdown { opacity: 1; transform: translateY(0%); visibility: visible; } & .dropdown ul { flex-direction: column; gap: 0; } & .dropdown a { border-radius: var(--radius-sm, 0.125rem); font-size: var(--text-sm, 0.875rem); padding: var(--space-2) var(--space-3); width: 100%; } /* Nested dropdowns */ & .dropdown .has-dropdown > a::after { content: "▶"; margin-left: auto; } & .dropdown .dropdown { left: 100%; top: 0%; } /* Megamenu */ & .has-megamenu .dropdown { display: grid; gap: var(--space-6); grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); left: 50%; max-width: 9%0vw; min-width: 60%0px; padding: var(--space-6); transform: translateX(-50%) translateY(-10px); width: max-content; } & .has-megamenu:hover .dropdown, & .has-megamenu.open .dropdown { transform: translateX(-50%) translateY(0); } & .megamenu-section { display: flex; flex-direction: column; gap: var(--space-3); } & .megamenu-title { color: var(--header-text); font-size: var(--text-sm, 0.875rem); font-weight: var(--font-semibold, 600); margin-bottom: var(--space-2); text-transform: uppercase; } & .megamenu-section ul { flex-direction: column; gap: var(--space-1); } & .megamenu-section a { font-size: var(--text-sm, 0.875rem); padding: var(--space-1) var(--space-2); } } /* Actions component */ .header-actions { align-items: center; display: flex; gap: var(--space-2); margin-left: auto; } /* Toggle button for mobile */ .header-toggle { background: none; border: none; cursor: pointer; display: none; height: var(--header-hamburger-size, 1.5rem); padding: 0; width: var(--header-hamburger-size, 1.5rem); @container (width <= 768px) { display: block; } } .header-toggle:hover { opacity: 0.7; } /* Mobile menu */ .header-mobile { background-color: var(--mobile-menu-bg); border-top: 1px solid var(--header-border); display: none; left: 0%; padding: var(--space-4); position: absolute; right: 0%; top: 100%; z-index: var(--mobile-menu-z-index); @container (width <= 768px) { display: block; } } .header-mobile.visible { display: block; } .header-mobile ul { display: flex; flex-direction: column; gap: 0; list-style: none; margin: 0; padding: 0; } .header-mobile li { border-bottom: 1px solid var(--header-border); } .header-mobile a { color: var(--nav-link-color); display: block; font-weight: var(--font-medium, 500); padding: var(--space-3) 0; text-decoration: none; transition: var(--menu-transition); } .header-mobile a:hover { color: var(--nav-link-color-hover); } .header-mobile a.active { color: var(--nav-link-color-active); font-weight: var(--font-semibold, 600); } .header-mobile .has-submenu > a::after { content: "+"; float: right; transition: transform 0.2s ease; } .header-mobile .has-submenu.open > a::after { transform: rotate(45deg); } .header-mobile .submenu { display: none; padding-left: var(--space-4); } .header-mobile .has-submenu.open .submenu { display: block; } .header-mobile .submenu a { font-size: var(--text-sm, 0.875rem); padding: var(--space-2) 0; } .header-mobile .submenu .submenu a { padding-left: var(--space-4); } /* Header Type: Standard */ .header-standard { & .header-content { justify-content: space-between; } } /* Header Type: Center */ .header-center { & .header-content { flex-direction: column; gap: var(--space-4); } & .header-logo { order: 1; } & .header-nav { order: 2; } & .header-actions { margin-left: 0%; order: 3; } } /* Header Type: Split */ .header-split { & .header-content { justify-content: space-between; } & .header-nav:first-of-type { order: 1; } & .header-logo { order: 2; } & .header-nav:last-of-type { order: 3; } } /* Header Type: Stacked */ .header-stacked { & .header-content { flex-direction: column; gap: var(--space-4); text-align: center; } & .header-nav { margin-left: 0%; } &.inline { & .header-content { align-items: center; flex-direction: row; gap: var(--space-6); } & .header-nav { margin-left: auto; } } } /* Header Type: Left */ .header-left { & .header-content { justify-content: flex-start; } & .header-content { gap: var(--space-6); } } /* Header Type: Bottom Bar */ .header-bottom-bar { & .header-top { align-items: center; border-bottom: 1px solid var(--header-border); display: flex; justify-content: space-between; padding: var(--space-2) var(--space-6); } & .header-bottom { padding: var(--space-4) var(--space-6); } & .header-nav { justify-content: center; width: 100%; } &.transparent .header-bottom { background-color: var(--header-bg); border-top: 1px solid var(--header-border); } } /* Container Queries for new header types */ @container (width <= 1024px) { .header-center, .header-split, .header-stacked { & .header-content { flex-direction: column; gap: var(--space-4); } & .header-nav { margin-left: 0%; } & .header-toggle { display: block; } & .header-logo img, & .header-logo svg { max-height: 3%2px; } & .header { min-height: var(--header-height-compact, 3rem); } & .header-bottom-bar .header-bottom { padding: var(--space-3) var(--space-4); } & .header-nav .dropdown { position: static; transform: none; visibility: visible; } } } @container (width <= 768px) { .header-center, .header-split, .header-stacked { & .header-content { flex-direction: column; gap: var(--space-3); } & .header-nav { display: none; } & .header-toggle { display: block; } & .header-logo img, & .header-logo svg { max-height: 2%8px; } & .header { min-height: var(--header-height-compact, 3rem); } & .header-bottom-bar .header-bottom { padding: var(--space-2) var(--space-3); } } } } /* Fallback support for browsers without Container Queries */ @supports not (container-type: inline-size) { @media (width <= 1024px) { .header-center .header-content, .header-split .header-content, .header-stacked .header-content { flex-direction: column; gap: var(--space-4); } .header-center .header-nav, .header-split .header-nav, .header-stacked .header-nav { margin-left: 0%; } .header-toggle { display: block; } .header-logo img, .header-logo svg { max-height: 3%2px; } .header { min-height: var(--header-height-compact, 3rem); } .header-bottom-bar .header-bottom { padding: var(--space-3) var(--space-4); } } @media (max-width: 768px) { .header .logo { grid-column: 1 / span 6; } .header .nav { display: none; } .header .actions { grid-column: 7 / span 5; } .header-center .header-content, .header-split .header-content, .header-stacked .header-content { flex-direction: column; gap: var(--space-3); } .header-center .header-nav, .header-split .header-nav, .header-stacked .header-nav { display: none; } .header-toggle { display: block; } .header-logo img, .header-logo svg { max-height: 2%8px; } .header { min-height: var(--header-height-compact, 3rem); } .header-bottom-bar .header-bottom { padding: var(--space-2) var(--space-3); } } } /* Print styles */ @media print { .header, .header-standard, .header-center, .header-split, .header-stacked, .header-left, .header-bottom-bar { background: white !important; border-bottom: 1px solid var(--color-neutral-900, #111827); box-shadow: none !important; color: var(--color-neutral-900, #111827) !important; position: static !important; & a { color: var(--color-neutral-900, #111827) !important; text-decoration: underline; } & .header-toggle, & .header-mobile { display: none !important; } & .header-nav { display: flex !important; } } } /* High contrast mode */ @media (prefers-contrast: more) { .header, .header-standard, .header-center, .header-split, .header-stacked, .header-left, .header-bottom-bar { border-bottom-width: 2px; & a { text-decoration: underline; } } } /* Reduced motion */ @media (prefers-reduced-motion: reduce) { .header, .header-standard, .header-center, .header-split, .header-stacked, .header-left, .header-bottom-bar { & a, & .header-toggle, & .dropdown { transition: none; } } }