/* Mixin for disabling any and all browser-defaulted button styling */ .blank-button { padding: 0; border: none; outline: none; font: inherit; color: inherit; background: none; } .button { /* Default background color */ --button-color: white; /* Background color for disabled buttons */ --disabled-color: grey; /* Background color for hovered and/or active buttons */ --hover-color: cyan; cursor: pointer; position: relative; background-position: center; background-repeat: no-repeat; background-size: contain; mask-size: contain; box-sizing: border-box; user-select: none; } .button-horizontal { display: grid; overflow: hidden; align-items: center; justify-items: center; column-gap: 0.3em; grid-template-rows: auto; grid-template-columns: min-content auto; grid-template-areas: "image label"; /* fallback for browsers that lack `:has()` support */ } .button:has(.button-label-right) { grid-template-areas: "image label"; } .button:has(.button-label-left) { grid-template-areas: "label image"; } .button-horizontal .button-image { position: static; transform: unset; width: 96%; height: 96%; max-height: 221px; max-width: 221px; } /* Delegate the background/border styling to a separate class in order to ease their removal when a greater degree of element styling is desired */ .button-styling { background-color: var(--button-color); border: min(0.2vh, 0.1vw) solid black; } .button-tooltip { --tooltip-gap: min(1vh, 0.5vw); cursor: auto; background-color: #FFFF88; color: black; border: min(0.2vh, 0.1vw) solid black; box-shadow: min(0.4vh, 0.2vw) min(0.4vh, 0.2vw) min(2vh, 1vw) 0 rgb(0 0 0 / 50%); box-sizing: border-box; padding: 0.3em 0.6em 0.3em 0.6em; position: absolute; text-align: center; visibility: hidden; width: fit-content; text-wrap: nowrap; z-index: 1; } .button-tooltip-justify { text-align: justify; text-wrap: wrap; text-indent: 1em hanging each-line; } .button-tooltip-craft { list-style-type: none; padding: unset; margin: unset; padding-left: 1em; } .button-image { grid-area: image; position: absolute; pointer-events: none; top: 2%; left: 50%; transform: translateX(-50%); width: min(221px, 96%); max-height: min(221px, 96%); aspect-ratio: 1 /1; } .button-image[data-hidden] { display: none; opacity: 20%; } .button[data-hidden] > .button-image[data-hidden] { display: inline; } .button[data-hidden] > .button-image:not([data-hidden]) { display: none; } .button[data-vibrating] > .button-image:not([data-hidden]) { animation: button-shake calc(1s / 6); animation-iteration-count: infinite; } @keyframes button-shake { 0% { transform: translate(-49.666%, 0.333%); } 10% { transform: translate(-50.333%, -0.666%); } 20% { transform: translate(-51%, 0%); } 30% { transform: translate(-49%, 0.666%); } 40% { transform: translate(-49.666%, -0.333%); } 50% { transform: translate(-50.333%, 0.666%); } 60% { transform: translate(-51%, 0.333%); } 70% { transform: translate(-49%, 0.333%); } 80% { transform: translate(-50.333%, -0.333%); } 90% { transform: translate(-49.666%, 0.666%); } 100% { transform: translate(-49.666%, -0.666%); } } .button-label { grid-area: label; position: absolute; left: 2%; width: 96%; max-height: 98%; pointer-events: none; cursor: inherit; overflow: hidden; } .button-image ~ .button-label { font-size: 0.65em; } .button-styling > .button-label { background-color: inherit; } .button-icon-grid { --icon-size: min(50px, 5vh, 2.5vw); display: grid; position: absolute; pointer-events: none; top: min(0.3vh, 0.15vw); left: min(0.3vh, 0.15vw); grid-template-rows: repeat(4, var(--icon-size)); gap: calc(var(--icon-size) / 8); } .button-icon { width: var(--icon-size); height: var(--icon-size); } .button-icon-tooltip-ul { text-align: left; margin: 0; padding-left: 0.5em; } .button-icon-tooltip-li { display: flex; list-style: none; background-repeat: no-repeat; background-size: contain; padding-left: 1.5em; } .button-tooltip-left { top: 50%; transform: translateY(-50%); right: calc(100% + var(--tooltip-gap)); } .button-tooltip-right { top: 50%; transform: translateY(-50%); left: calc(100% + var(--tooltip-gap)); } .button-tooltip-top { bottom: calc(100% + var(--tooltip-gap)); left: 50%; transform: translateX(-50%); } .button-tooltip-bottom { top: calc(100% + var(--tooltip-gap)); left: 50%; transform: translateX(-50%); } .button-label-top { top: 1%; } .button-label-center { top: 50%; transform: translateY(-50%); } .button-label-left, .button-label-right { position: static; width: unset; left: unset; } .button-label-bottom { bottom: 1%; } /* selectors */ .button-styling[aria-checked="true"] { background-color: var(--hover-color); } .button-styling[aria-checked="true"]::before, .button-styling:active::before, .button-styling[data-active]::before { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border: min(0.4vh, 0.2vw) inset black; } .button-styling:disabled::before, .button-styling[aria-disabled="true"]::before { border: unset; } .button-styling[aria-checked="true"]::before { border: min(0.4vh, 0.2vw) inset black; } .button-styling:active, .button-styling[data-active] { background-color: var(--hover-color); } /* Keep hover-related styling on mobile disabled as it has a tendency to stick even after the click has ended */ @media (hover: hover) { @supports selector(:has(*)) { .button-styling:hover:not(:has(.button-tooltip:hover)) { background-color: var(--hover-color); } .button:hover:not(:has(.button-tooltip:hover)) > .button-tooltip { visibility: visible; } } @supports not selector(:has(*)) { .button-styling:hover { background-color: var(--hover-color); } .button:hover > .button-tooltip { visibility: visible; } } .button:focus > .button-tooltip { visibility: visible; } } @media (hover: none) { .button:focus[data-show-tooltip] > .button-tooltip { visibility: visible; } } /* Only show a focus outline when the element is explicitly focused (i.e. via tab-selection) */ @supports selector(:focus-visible) { .button:focus-visible { outline: 2px solid rgb(0, 96, 223); box-shadow: 0 0 0 3px white; border-radius: 1px; } } @supports not selector(:focus-visible) { .button:focus { outline: 2px solid rgb(0, 96, 223); box-shadow: 0 0 0 3px white; border-radius: 1px; } } .button:disabled, .button[aria-disabled="true"], *[role="radiogroup"][aria-required="true"] .button[role="radio"][aria-checked="true"], *[role="menubar"][aria-required="true"] .button[role="menuitemradio"][aria-checked="true"], *[role="menu"][aria-required="true"] .button[role="menuitemradio"][aria-checked="true"] { cursor: auto; } .button-styling:disabled, .button-styling[aria-disabled="true"] { background-color: var(--disabled-color) !important; } *[role="menubar"][aria-required="true"] .button-styling[role="menuitemradio"][aria-checked="true"], *[role="menu"][aria-required="true"] .button-styling[role="menuitemradio"][aria-checked="true"], *[role="radiogroup"][aria-required="true"] .button-styling[role="radio"][aria-checked="true"] { background-color: var(--disabled-color) !important; } *[role="menubar"][aria-required="true"] .button-styling[role="menuitemradio"][aria-checked="true"] > .button-label, *[role="menu"][aria-required="true"] .button-styling[role="menuitemradio"][aria-checked="true"] > .button-label, *[role="radiogroup"][aria-required="true"] .button-styling[role="radio"][aria-checked="true"] > .button-label { background-color: var(--disabled-color) !important; } .button-tooltip:empty, .button-label:empty { display: none !important; } @supports (height: 100dvh) { .button-tooltip { --tooltip-gap: min(1dvh, 0.5dvw); } .button-icon-grid { --icon-size: min(50px, 5dvh, 2.5dvw); top: min(0.3dvh, 0.15dvw); left: min(0.3dvh, 0.15dvw); } .button-styling[aria-checked="true"]::before, .button-styling:active::before, .button-styling[data-active]::before { border: min(0.4dvh, 0.2dvw) inset black; } .button-styling:disabled::before, .button-styling[aria-disabled="true"]::before { border: unset; } .button-styling[aria-checked="true"]::before { border: min(0.4dvh, 0.2dvw) inset black; } } @supports (background-color: color-mix(in srgb, black 50%, transparent)) { .button-styling > .button-label { background-color: color-mix(in srgb, var(--button-color) 50%, transparent); } .button-styling[aria-checked="true"] { background-color: color-mix(in srgb, var(--button-color) 66%, var(--hover-color) 34%); } .button-styling[aria-checked="true"] > .button-label { background-color: color-mix( in srgb, color-mix(in srgb, var(--button-color) 66%, var(--hover-color) 34%) 50%, transparent ); } .button-styling:active > .button-label, .button-styling[data-active] > .button-label { background-color: color-mix(in srgb, var(--hover-color) 50%, transparent); } @media (hover: hover) { .button-styling:hover:not(:has(.button-tooltip:hover)) > .button-label { background-color: color-mix(in srgb, var(--hover-color) 50%, transparent); } } .button-styling:disabled > .button-label, .button-styling[aria-disabled="true"] > .button-label { background-color: color-mix(in srgb, var(--disabled-color) 50%, transparent) !important; } *[role="menubar"][aria-required="true"] .button-styling[role="menuitemradio"][aria-checked="true"], *[role="menu"][aria-required="true"] .button-styling[role="menuitemradio"][aria-checked="true"], *[role="radiogroup"][aria-required="true"] .button-styling[role="radio"][aria-checked="true"] { background-color: color-mix(in srgb, var(--disabled-color) 50%, var(--hover-color) 50%) !important; } *[role="menubar"][aria-required="true"] .button-styling[role="menuitemradio"][aria-checked="true"] > .button-label, *[role="menu"][aria-required="true"] .button-styling[role="menuitemradio"][aria-checked="true"] > .button-label, *[role="radiogroup"][aria-required="true"] .button-styling[role="radio"][aria-checked="true"] > .button-label { background-color: var(--disabled-color) !important; background-color: color-mix( in srgb, color-mix(in srgb, var(--disabled-color) 50%, var(--hover-color) 50%), transparent ) !important; } }