Skip to content

Instantly share code, notes, and snippets.

@allmarkedup
Created July 29, 2026 23:48
Show Gist options
  • Select an option

  • Save allmarkedup/4822b386c3613adc71904f39ee4fe5de to your computer and use it in GitHub Desktop.

Select an option

Save allmarkedup/4822b386c3613adc71904f39ee4fe5de to your computer and use it in GitHub Desktop.
Button with CSS property theme values
@theme {
--button-icon-size: 1em;
--button-border-radius: --spacing(11);
--button-border-width: 0;
--button-focus-ring-width: 2px;
--button-focus-ring-offset: 2px;
--button-focus-ring-opacity: 30%;
--button-opacity-disabled: 1;
--button-font-size: var(--text-sm);
--button-padding-block: --spacing(2);
--button-padding-inline: --spacing(3);
--button-width: fit-content;
--button-transition-duration: 200ms;
--button-transition-easing: ease-in-out;
}
@layer components {
.cb-button {
--tw-inset-ring-shadow: inset 0 0 0 var(--button-border-width)
var(--button-border-color, transparent);
/* Sizes */
@variant size-xs {
--button-font-size: var(--text-sm);
--button-padding-block: --spacing(2);
--button-padding-inline: --spacing(3);
--button-icon-size: --spacing(4);
}
@variant size-sm {
--button-font-size: var(--text-sm);
--button-padding-block: --spacing(2.5);
--button-padding-inline: --spacing(4);
--button-icon-size: --spacing(4);
}
@variant size-md {
--button-font-size: var(--text-base);
--button-padding-block: --spacing(3);
--button-padding-inline: --spacing(5);
--button-icon-size: --spacing(5);
}
@variant size-lg {
--button-font-size: var(--text-lg);
--button-padding-block: --spacing(4);
--button-padding-inline: --spacing(6);
--button-icon-size: --spacing(6);
}
@variant no-size {
/*
* Buttons without a `data-size` attribute are sized `sm`
* at screens < 1200 and `md` at screens >= 1200px
*/
--button-font-size: var(--text-sm);
--button-padding-block: --spacing(2.5);
--button-padding-inline: --spacing(4);
--button-icon-size: --spacing(4);
@media (width >= theme(--breakpoint-xl)) {
--button-font-size: var(--text-base);
--button-padding-block: --spacing(3);
--button-padding-inline: --spacing(5);
--button-icon-size: --spacing(5);
}
}
/* Themes */
@variant no-theme, theme-primary, theme-positive {
--button-fg: var(--color-content-light-1);
--button-bg: var(--color-background-positive);
--button-bg-hover: var(--color-positive-600);
--button-bg-active: var(--color-positive-700);
--button-bg-disabled: var(--color-positive-200);
}
@variant theme-secondary {
--button-border-width: 1px;
--button-border-color: var(--color-coco-gray-300);
--button-fg: var(--color-content-dark-1);
--button-bg: var(--color-content-light-1);
--button-bg-hover: var(--color-coco-gray-50);
--button-bg-active: var(--color-coco-gray-100);
--button-bg-disabled: var(--button-bg);
--button-opacity-disabled: 0.3;
--button-focus-ring-base-color: var(--button-fg);
}
@variant theme-negative {
--button-fg: var(--color-content-light-1);
--button-bg: var(--color-background-negative);
--button-bg-hover: var(--color-negative-700);
--button-bg-active: var(--color-negative-800);
--button-bg-disabled: var(--color-negative-200);
}
@variant theme-warning {
--button-fg: var(--color-content-light-1);
--button-bg: var(--color-background-warning);
--button-bg-hover: var(--color-warning-700);
--button-bg-active: var(--color-warning-800);
--button-bg-disabled: var(--color-warning-200);
}
@variant theme-info {
--button-fg: var(--color-content-light-1);
--button-bg: var(--color-background-info);
--button-bg-hover: var(--color-info-700);
--button-bg-active: var(--color-info-800);
--button-bg-disabled: var(--color-info-200);
}
@variant theme-neutral-dark {
--button-fg: var(--color-content-light-1);
--button-bg: var(--color-background-dark-1);
--button-bg-hover: var(--color-coco-gray-700);
--button-bg-active: var(--color-coco-gray-800);
--button-bg-disabled: var(--color-coco-gray-200);
}
@variant theme-neutral-light {
--button-fg: var(--color-content-dark-1);
--button-bg: var(--color-background-light-1);
--button-bg-hover: var(--color-background-light-2);
--button-bg-active: var(--color-background-light-3);
--button-bg-disabled: var(--color-background-light-1);
--button-focus-ring-opacity: 10%;
--button-focus-ring-base-color: var(--button-fg);
}
@variant theme-blank {
/* No background/text/border colors, but uses button padding/sizing */
--button-fg: currentColor;
--button-bg: transparent;
--button-bg-hover: transparent;
--button-bg-active: transparent;
--button-bg-disabled: transparent;
--button-border-color: transparent;
--button-focus-ring-opacity: 20%;
--button-focus-ring-base-color: var(--button-fg);
}
/* Text button themes */
&[data-theme^="text-"] {
--button-bg: transparent;
--button-bg-hover: var(--color-coco-gray-50);
--button-bg-active: var(--color-coco-gray-100);
--button-bg-disabled: transparent;
--button-opacity-disabled: 0.3;
--button-focus-ring-base-color: var(--button-fg);
background-blend-mode: var(--button-bg-blend-hover, hard-light);
}
@variant theme-text-primary, theme-text-positive {
--button-fg: var(--color-content-positive);
}
@variant theme-text-secondary {
--button-fg: var(--color-content-dark-1);
--button-focus-ring-opacity: 10%;
@variant disabled {
opacity: 0.3;
}
}
@variant theme-text-negative {
--button-fg: var(--color-content-negative);
}
@variant theme-text-warning {
--button-fg: var(--color-content-warning);
}
@variant theme-text-info {
--button-fg: var(--color-content-info);
}
@variant icon-only {
--button-padding-inline: var(--button-padding-block);
}
cursor: pointer;
user-select: none;
font-size: var(--button-font-size);
font-weight: 500;
text-decoration: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
position: relative;
display: flex;
align-items: center;
justify-content: center;
column-gap: --spacing(2);
flex: none;
width: var(--button-width);
height: fit-content;
padding-block: var(--button-padding-block);
padding-inline: var(--button-padding-inline);
min-height: calc(
var(--button-icon-size) + (2 * var(--button-padding-block))
);
color: var(--button-fg, currentColor);
background-color: var(--button-bg, transparent);
/* Button borders are set via --tw-inset-ring-shadow */
box-shadow:
var(--tw-inset-shadow), var(--tw-inset-ring-shadow),
var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
border-radius: var(--button-border-radius);
outline-width: var(--button-focus-ring-width);
outline-color: transparent;
outline-offset: var(--button-focus-ring-offset);
outline-style: solid;
white-space: nowrap;
transition: all var(--button-transition-duration)
var(--button-transition-easing);
.coco-icon {
width: var(--button-icon-size);
height: auto;
aspect-ratio: 1 / 1;
display: block;
flex: none;
order: 0;
&[data-position="end"] {
order: 1;
& + .button-label {
order: 0;
}
}
}
> .button-label {
cursor: pointer;
display: flex;
order: 2;
flex: none;
align-items: center;
justify-content: center;
width: fit-content;
min-height: var(--button-icon-size);
line-height: 1;
font-size: 1em;
font-weight: 500;
text-decoration: none;
white-space: nowrap;
}
/* Display a chevron for buttons with labels that have a popover */
&[popovertarget]:has(> *:not(.coco-icon))::after {
content: "";
display: block;
width: 1em;
height: 1em;
mask: var(--button-toggle) center center / 100% auto no-repeat;
background: currentColor;
order: 100;
}
@variant hidden {
display: none !important;
}
@variant hover {
background-color: var(--button-bg-hover, var(--button-bg, transparent));
color: var(--button-fg-hover, var(--button-fg, currentColor));
}
@variant active {
background-color: var(--button-bg-active, var(--button-bg, transparent));
color: var(--button-fg-active, var(--button-fg, currentColor));
}
@variant focus-visible {
outline-color: color-mix(
in srgb,
var(--button-focus-ring-base-color, var(--button-bg))
var(--button-focus-ring-opacity),
transparent
);
}
@variant disabled {
pointer-events: none; /* The `disabled` attribute is inert on <a> buttons so needs enforcing */
transition: none;
background-color: var(
--button-bg-disabled,
var(--button-bg, transparent)
);
color: var(--button-fg-disabled, var(--button-fg, currentColor));
opacity: var(--button-opacity-disabled);
}
}
}
@utility toggleless-button {
&::after {
display: none !important;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment