UNPKG

@fylgja/base

Version:

Base provides a streamlined starting point for any web project. It’s a collection of class-less solutions, allowing you to focus on building your site.

630 lines (551 loc) 16.1 kB
/** * Fylgja (https://fylgja.dev) * Licensed under MIT Open Source */ *, ::before, ::after { box-sizing: border-box; border: 0 solid; } :root { --root-bg: hsl(0, 0%, 100%); --root-fg: hsl(0, 0%, 8%); --family-system: system-ui, sans-serif; --family-mono: ui-monospace, Menlo, Consolas, monospace; --select-light-scheme: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke="hsl(0 0% 0%)"><path d="m6 9 6 6 6-6"/></svg>'); --select-dark-scheme: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke="hsl(0 0% 100%)"><path d="m6 9 6 6 6-6"/></svg>'); --outline-transition: outline-offset 150ms cubic-bezier(0.25, 0, 0.4, 1); --surface-color: color-mix(in srgb, var(--root-bg) 94%, var(--root-fg)); } :where(:focus-visible) { outline: var(--outline-size, 2px) solid; outline-offset: var(--outline-offset, 2px); } :where(:active:focus-visible) { outline-offset: 0; transition: var(--outline-transition); } :target { scroll-margin-block: var(--anchor-offset, 6ex); } :where(html) { block-size: 100%; font-family: var(--family-system); tab-size: 4; -webkit-text-size-adjust: none; text-size-adjust: none; scrollbar-gutter: stable; } @media (prefers-reduced-motion: no-preference) { :where(html):has(:target) { scroll-behavior: smooth; } } :where(body) { min-block-size: 100%; margin: 0; background-color: var(--root-bg); color: var(--root-fg); font-size: var(--font-size, 1rem); line-height: var(--line-height, 1.6); } :where(:any-link, button, input, label[for], select, summary, textarea, [tabindex]:not([tabindex^="-"])) { touch-action: manipulation; } :where(:any-link, button, label[for], label:has(input:is([type=radio], [type=checkbox]):enabled), select:has(option:enabled), summary) { cursor: pointer; } :where([type=button], [type=submit], [type=reset], button), ::file-selector-button { appearance: button; } :where(summary) { display: list-item; } :where(summary > *) { display: inline; } :disabled { cursor: not-allowed; } :where(img, svg, video, canvas, audio, iframe, embed, object) { display: block; max-inline-size: 100%; } :where(img, svg, iframe) { block-size: auto; } :where(iframe) { aspect-ratio: var(--aspect-ratio, 16/9); } [hidden]:not([hidden=until-found]) { display: none; } :root { --text-flow: 1em 1rem; --separator-flow: 2.5em; --list-flow: 0.5em; --h-size: 1.125rem; --h-weight: 700; --h-line: 1.1; --h1-size: 3rem; --h2-size: 2rem; --h3-size: 1.625rem; --h4-size: 1.375rem; } :where(h1, h2, h3, h4, h5, h6, p, dl, ul, ol, pre, hgroup) { margin-block: var(--text-flow); } :where(blockquote, figure, hr) { margin-block: var(--separator-flow); margin-inline: 0; } :where(h1, h2, h3, h4, h5, h6) { font-size: var(--h-size); font-weight: var(--h-weight); line-height: var(--h-line); text-wrap: balance; } :where(h1) { --h-size: var(--h1-size); } :where(h2) { --h-size: var(--h2-size); } :where(h3) { --h-size: var(--h3-size); } :where(h4) { --h-size: var(--h4-size); } :where(p, li, dd) { text-wrap: pretty; } :where(:any-link) { color: inherit; } :where(mark, :not(pre) > code) { padding: 0.0625em 0.25em; } :where(blockquote) { border-inline-start: 4px solid; padding-inline-start: 1.5em; padding-block: 0.25em; } :where(pre) { padding: 0.5em 1em; white-space: pre; overflow: auto; } :where(input, button, textarea, select, address), ::file-selector-button { font: inherit; } :where(:is(ul, ol)[role=list], nav :is(ul, ol)) { --list-flow: 0; list-style: none; margin-block: 0; padding-inline-start: 0; } :where(hgroup > *), :where(dl, ol, ul) :where(dl, ol, ul) { margin-block: 0; } :where(dt) { font-weight: 500; } :where(li + li, dd + dt) { margin-block-start: var(--list-flow); } :where(dd) { margin-inline-start: 0; } :where(hr) { height: auto; border-block-end-width: 2px; color: inherit; } :where(sub, sup) { position: relative; font-size: 0.75em; line-height: 0; vertical-align: baseline; } :where(sub) { bottom: -0.25em; } :where(sup) { top: -0.5em; } :where(code, pre, kbd, samp) { font-family: var(--family-mono); } :where(code, pre) { writing-mode: lr; direction: ltr; } :where(pre, :not(pre) > code) { border-radius: var(--code-radius, 0.3em); border: 1px solid var(--code-stroke, rgba(0, 0, 0, 0.2)); background: var(--code-bg, var(--surface-color)); color: var(--code-color); } :where(table) { border-spacing: 0; border-color: var(--table-stroke, #777); } :where(thead, tbody, tfoot, tr, th, td) { border-color: inherit; text-align: inherit; } :where(th, td) { padding-block: var(--table-py, 0.875em); padding-inline: var(--table-px, 0.625em); background: var(--root-bg); color: var(--root-fg); } :where(tr + tr :is(th, td)) { border-block-start-width: 1px; } :where(thead tr:last-child :is(th, td)) { border-block-end-width: 2px; } :where(tfoot tr:first-child :is(th, td)) { border-block-start-width: 2px; } :where(input:not([type=range], [type=button], [type=reset], [type=submit]), textarea, select, .form-input) { appearance: none; margin: 0; padding-block: var(--form-py, 0.4375rem); padding-inline: var(--form-px, 0.8rem); border-width: var(--form-border-width, 1px); border-color: var(--form-stroke); border-radius: var(--form-radius, 0.35rem); background: var(--form-bg, var(--root-bg)); color: var(--form-color, var(--root-fg)); transition: color 250ms, background-color 250ms, border-color 250ms, box-shadow 250ms; } :where(input:not([type=range], [type=button], [type=reset], [type=submit]), textarea, select):placeholder-shown { text-overflow: ellipsis; } :where(input:not([type=range], [type=button], [type=reset], [type=submit]), textarea, select):focus-visible { border-color: var(--form-active-color); } :where(input:not([type=range], [type=button], [type=reset], [type=submit]), textarea, select):disabled { box-shadow: none; cursor: not-allowed; } :where(input:not([type=checkbox], [type=radio], [type=range], [type=button], [type=reset], [type=submit]), textarea, select) { --outline-size: 1px; --outline-offset: calc( (var(--form-border-width, 1px) + 1px) * -1 ); display: block; max-inline-size: 100%; inline-size: 100%; } :where(input:not([type=checkbox], [type=radio], [type=range], [type=button], [type=reset], [type=submit]), textarea, select):is(:disabled, [readonly]:not(:focus)) { border-style: var(--form-disabled-border-style, dashed); } :where(input[type=checkbox], input[type=radio]) { --_gap: var(--icon-gap, 2px); block-size: var(--control-size, 1.25em); inline-size: var(--control-size, 1.25em); border-radius: var(--control-radius, 0.35rem); border-width: var(--control-border-width, 2px); padding: var(--_gap); user-select: none; } :where(input[type=checkbox], input[type=radio]):not(:disabled) { cursor: pointer; } :where(input[type=checkbox], input[type=radio])::after { content: ""; display: block; block-size: 100%; inline-size: 100%; border-radius: inherit; background-color: var(--icon-color, currentcolor); scale: var(--_show-icon, 0); opacity: var(--_show-icon, 0); transition: translate 0.15s, scale 0.15s, opacity 0.15s; forced-color-adjust: none; -webkit-mask: var(--_icon) center/contain no-repeat; mask: var(--_icon) center/contain no-repeat; } :where(input[type=checkbox], input[type=radio]):checked { --_show-icon: 1; outline-color: var(--control-checked-stroke, var(--root-fg)); border-color: var(--control-checked-stroke, var(--root-fg)); background-color: var(--control-checked-bg, var(--root-fg)); color: var(--control-checked-color, var(--root-bg)); } :where(input[type=radio]) { --_gap: 3px; --control-radius: 50%; } :where(input[type=checkbox]:not([role=switch])) { --_gap: 1px; --_icon: url("#"); --checked-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='4'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E %3C/svg%3E"); --indeterminate-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='4'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E"); } :where(input[type=checkbox]:not([role=switch])):indeterminate { --_show-icon: 1; --_icon: var(--indeterminate-icon); } :where(input[type=checkbox]:not([role=switch])):checked { --_icon: var(--checked-icon); } :where(input[type=checkbox][role=switch]) { --_show-icon: 1; --control-radius: 1.25em; inline-size: var(--switch-size, 2em); } :where(input[type=checkbox][role=switch])::after { inline-size: auto; aspect-ratio: 1; } :where(input[type=checkbox][role=switch]):checked { --_offset-x: calc( var(--switch-size, 2em) - var(--control-size, 1.25em) ); } :where(input[type=checkbox][role=switch]):checked::after { translate: var(--_offset-x) 0%; } :where(input[type=checkbox][role=switch]):checked:dir(rtl)::after { translate: calc(var(--_offset-x) / -1) 0%; } :where(input[type=color]) { --form-py: 3px; --form-px: 3px; block-size: var(--block-size, 2.5em); inline-size: var(--inline-size, 2.5em); } :where(input[type=color])::-webkit-color-swatch-wrapper { padding: 0; border-radius: inherit; } :where(input[type=color])::-moz-color-swatch { border: 0; border-radius: inherit; } :where(input[type=color])::-webkit-color-swatch { border: 0; border-radius: inherit; } :where(input[type=file]) { --form-py: 0; --form-px: 0 0.8rem; --btn-radius: 0; --btn-border-width: 0; overflow: clip; } :where(input[type=file])::file-selector-button { margin-inline-end: 1em; } :where(select) { inline-size: auto; word-wrap: normal; } :where(select:not([size]:not([size="1"]), [multiple])) { --icon-size: var(--select-icon-size, 1.25em); --icon-offset: var(--select-icon-offset, 0.8rem); padding-inline-end: calc(var(--icon-size) + var(--icon-offset) + 0.5ch); background: var(--select-icon, var(--select-light-scheme)) var(--form-bg, var(--root-bg)) var(--icon-position, right) var(--icon-offset) center/var(--icon-size) no-repeat; -webkit-print-color-adjust: exact; print-color-adjust: exact; } :where(select:not([size]:not([size="1"]), [multiple])):dir(rtl) { --icon-position: left; } :where(textarea) { resize: vertical; } :where(textarea:not([row])) { min-block-size: var(--textarea-min-size, calc(3.5lh + var(--form-py, 0.4375rem))); field-sizing: content; } ::placeholder { opacity: 1; color: color-mix(in srgb, currentcolor 54%, transparent); } :where(fieldset) { min-inline-size: 0; margin: 0; padding: 0; } :where(legend) { padding: 0; } ::-webkit-search-decoration { -webkit-appearance: none; } ::-webkit-datetime-edit, ::-webkit-datetime-edit-fields-wrapper, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field { display: inline; padding-block: 0; } ::-webkit-date-and-time-value { min-height: 1lh; text-align: inherit; } ::-webkit-calendar-picker-indicator { line-height: 1; } :where([list]:not([type*=date], [type=month], [type=week], [type=time])) { --datalist-icon: var(--select-icon, var(--chevron-light-scheme)); } :where([list]:not([type*=date], [type=month], [type=week], [type=time]))::-webkit-calendar-picker-indicator { display: block !important; background: var(--datalist-icon) center/contain no-repeat; opacity: 1; } :where([list]:not([type*=date], [type=month], [type=week], [type=time]))::-webkit-list-button { appearance: none; block-size: 1em; inline-size: 1em; padding: 3px; align-self: center; background: var(--datalist-icon) center/contain no-repeat; } :where(button, [type=button], [type=submit], [type=reset], .btn), ::file-selector-button { display: inline-flex; justify-content: center; align-items: center; gap: var(--btn-gap, 0.5em); padding-block: var(--btn-py, 0.375rem); padding-inline: var(--btn-px, 0.8rem); border-radius: var(--btn-radius, 0.5rem); border-width: var(--btn-border-width, 2px); border-color: var(--btn-stroke); background: var(--btn-bg, transparent); color: var(--btn-color, currentcolor); font-weight: var(--btn-font-weight, 500); text-decoration: none; transition: color 0.2s, background-color 0.2s, border-color 0.2s, box-shadow 0.2s, var(--outline-transition); user-select: none; cursor: pointer; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } :where(button, [type=button], [type=submit], [type=reset], .btn) { vertical-align: middle; } :where(button, [type=button], [type=submit], [type=reset], .btn):hover, ::file-selector-button:hover { border-color: var(--btn-hover-stroke, var(--btn-stroke)); background-color: var(--btn-hover-bg, var(--btn-bg, color-mix(in srgb, currentcolor, transparent 86%))); color: var(--btn-hover-color, var(--btn-color, currentcolor)); } :where(button, [type=button], [type=submit], [type=reset], .btn):is(:active, .is-active, [aria-current=page], [aria-current=true], [aria-selected=true], :where(:has(input:checked))) { border-color: var(--btn-active-stroke, var(--btn-stroke)); background-color: var(--btn-active-bg, var(--btn-bg, color-mix(in srgb, currentcolor, transparent 78%))); color: var(--btn-active-color, var(--btn-color, currentcolor)); } :where(button, [type=button], [type=submit], [type=reset], .btn):is(:disabled [aria-disabled=true]), :disabled::file-selector-button { box-shadow: none; border-color: var(--btn-disabled-stroke); background-color: var(--btn-disabled-bg, color-mix(in srgb, var(--root-bg) 90%, var(--root-fg))); color: var(--btn-disabled-color, color-mix(in srgb, var(--root-fg) 40%, var(--root-bg))); cursor: not-allowed; } :where(dialog) { --backdrop: hsla(0, 0%, 0%, 0.3); --ty: var(--dialog-translate-y, 2rem); --tx: var(--dialog-translate-x, 0); --speed: var(--dialog-close-speed, 300ms); --screen-y: 2rem; --screen-x: 2rem; --my: auto; --mx: auto; position: fixed; max-block-size: calc(100% - var(--screen-y)); max-inline-size: calc(100% - var(--screen-x)); background-color: var(--dialog-bg, color-mix(in oklab, var(--root-bg) 88%, white)); color: var(--dialog-color, var(--root-fg)); border-radius: 1rem; margin-block: var(--my); margin-inline: var(--mx); padding: 1.5rem; box-shadow: var(--dialog-shadow, 0 3px 5px hsla(0, 0%, 0%, 0.18)); translate: var(--tx) var(--ty); opacity: 0; } :where(dialog)::backdrop { background-color: var(--backdrop); } @media (prefers-reduced-motion: no-preference) { :where(dialog) { transition-property: translate, opacity, display, overlay; transition-duration: var(--speed); transition-behavior: allow-discrete; } } :where(dialog:is([open], :popover-open)) { --speed: var(--dialog-open-speed, 400ms); opacity: 1; translate: 0 0; } @starting-style { :where(dialog:is([open], :popover-open)) { opacity: 0; translate: var(--tx) var(--ty); } } :where(:root:has(dialog[open]:modal)) { overflow: hidden; } @media print { :root { --root-bg: white; --root-fg: black; } :is(h1, h2, h3, h4, h5, h6) { page-break-after: avoid; } :is(h2, h3, h4, h5, h6, p) { orphans: 3; widows: 3; } :is(tr, img, svg, pre, blockquote) { page-break-inside: avoid; } abbr[title]::after { content: " (" attr(title) ")"; } a[href^="https://"]::after { content: " (" attr(href) ")"; } thead { display: table-header-group; } :is(input, select, textarea, button, .btn) { -webkit-print-color-adjust: exact; print-color-adjust: exact; } }