<!-- This demo still has some accessibility issues, do not use this in production code, one of them is the keyboard navigation, which seems off. also the count of menu items seems to go wrong. These issues have been reported: https://issues.chromium.org/issues/417119055 -->
<label for="emoji-picker">Pick an emoji based on season</label>
<select id="emoji-picker">
<button>
<selectedcontent>Select Tool</selectedcontent>
</button>
<!-- top-right -->
<optgroup value="Winter">
<option value="snowflake">❄️</option>
<option value="xmas">🌲</option>
<option value="gifts">🎁</option>
</optgroup>
<!-- bottom-right -->
<optgroup value="Spring">
<option value="butterfly">🦋</option>
<option value="flowers">🌷</option>
<option value="seeds">🌱</option>
</optgroup>
<!-- bottom-left -->
<optgroup value="Summer">
<option value="bbq">🍖</option>
<option value="hot">🌡️</option>
<option value="fruits">🍉</option>
</optgroup>
<!-- top-left -->
<optgroup value="Fall">
<option value="pumpkin">🎃</option>
<option value="leaf">🍂</option>
<option value="deer">🦌</option>
</optgroup>
</select>
@import url("https://fonts.googleapis.com/css2?family=Yellowtail&display=swap");
:root {
--dark-segment: oklch(35% 0.15 250);
--light-segment: oklch(75% 0.15 220);
--border-color: rgba(255, 255, 255, 0.8);
--text-color: #3a4a5a;
--background-color: radial-gradient(
farthest-corner circle at 0% 0% in oklch,
oklch(92% 0.1 240) 0%,
33%,
oklch(82% 0.15 220) 100%
);
--selected-color: radial-gradient(
circle at center,
oklch(85% 0.2 220) 0%,
oklch(75% 0.15 240) 100%
);
--hover-color: oklch(85% 0.1 220);
--container-size: min(360px, 90vw);
}
@layer select {
select {
--menu-size: 40cqi;
--center-size: 13cqi;
--option-size: 6cqi;
--option-distance: calc(var(--menu-size) / 2 - 4.5cqi);
--label-font-size: 2cqi;
--option-font-size: 4cqi;
position: relative;
z-index: 10;
display: flex;
width: var(--center-size);
height: var(--center-size);
margin: 0;
padding: 0;
justify-content: center;
align-items: center;
font-weight: 700;
text-align: center;
color: var(--text-color);
background: var(--background-color);
border: 2px solid var(--border-color);
border-radius: 50%;
box-shadow: 0 4px 15px rgba(100, 120, 160, 0.15);
appearance: none;
cursor: pointer;
@supports (appearance: base-select) {
&,
&::picker(select) {
appearance: base-select;
}
}
&::picker-icon {
display: none;
}
&::picker(select) {
position: fixed;
top: anchor(center);
left: anchor(center);
z-index: auto;
width: var(--menu-size);
height: var(--menu-size);
max-inline-size: none;
max-block-size: none;
translate: -50% -50%;
position-try-fallbacks: none;
background: rgba(255, 255, 255, 0.4);
border: 2px solid var(--border-color);
border-radius: 50%;
box-shadow: 0 8px 32px rgba(100, 120, 160, 0.15);
backdrop-filter: blur(4px);
opacity: 0;
overflow: hidden;
transform: scale(0);
transition: opacity 0.4s ease-out, transform 0.4s ease-out, overlay 0.4s,
display 0.4s;
transition-behavior: allow-discrete;
}
&:open::picker(select) {
opacity: 1;
transform: scale(1);
@starting-style {
opacity: 0;
transform: scale(0.8);
}
}
&::checkmark {
display: none;
}
}
selectedcontent {
display: block;
font-size: calc(var(--option-font-size) * 2);
text-align: center;
}
}
@layer label {
label {
margin-bottom: 0.8rem;
font-size: 2rem;
opacity: 1;
transition: opacity 0.5s ease-out;
}
label:has(+ select:open) {
opacity: 0;
}
}
@layer segments {
optgroup:nth-of-type(1) {
--text-inline: 52% auto;
--text-block: auto 52%;
background-image: url("https://assets.codepen.io/159218/winter.svg");
clip-path: polygon(50% 0%, 100% 0%, 100% 50%, 50% 50%);
}
optgroup:nth-of-type(2) {
--text-inline: 52% auto;
--text-block: 52% auto;
background-image: url("https://assets.codepen.io/159218/spring.svg");
clip-path: polygon(50% 50%, 100% 50%, 100% 100%, 50% 100%);
}
optgroup:nth-of-type(3) {
--text-inline: auto 52%;
--text-block: 52% auto;
background-image: url("https://assets.codepen.io/159218/summer.svg");
clip-path: polygon(0% 50%, 50% 50%, 50% 100%, 0% 100%);
}
optgroup:nth-of-type(4) {
background-image: url("https://assets.codepen.io/159218/autumn.svg");
clip-path: polygon(0% 0%, 50% 0%, 50% 50%, 0% 50%);
}
optgroup {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
color: transparent;
background: transparent;
background-size: 30%;
overflow: visible;
pointer-events: none;
&::before {
position: absolute;
inset: 0;
z-index: 4;
background: #fff;
content: "";
opacity: 0.8;
pointer-events: auto;
transition: opacity 0.5s ease-out;
}
&::after {
position: absolute;
inset-inline: var(--text-inline, auto 52%);
inset-block: var(--text-block, auto 52%);
z-index: 5;
padding: 5px 15px;
font-family: "Yellowtail", cursive;
font-size: var(--label-font-size);
font-weight: bold;
color: var(--text-color);
background: rgba(255, 255, 255, 0.9);
border-radius: 9cqi;
box-shadow: 0 2px 8px rgba(100, 120, 160, 0.1);
backdrop-filter: blur(3px);
opacity: 0;
content: attr(value);
transition: opacity 0.3s ease-out;
}
&:hover,
&:has(option:hover),
&:has(option:focus) {
&::before {
opacity: 0.2;
}
&::after {
opacity: 1;
}
}
}
optgroup:nth-of-type(1) {
& option:nth-child(1) {
--angle: -75deg;
}
& option:nth-child(2) {
--angle: -45deg;
}
& option:nth-child(3) {
--angle: -15deg;
}
}
optgroup:nth-of-type(2) {
& option:nth-child(1) {
--angle: 15deg;
}
& option:nth-child(2) {
--angle: 45deg;
}
& option:nth-child(3) {
--angle: 75deg;
}
}
optgroup:nth-of-type(3) {
& option:nth-child(1) {
--angle: 105deg;
}
& option:nth-child(2) {
--angle: 135deg;
}
& option:nth-child(3) {
--angle: 165deg;
}
}
optgroup:nth-of-type(4) {
& option:nth-child(1) {
--angle: 195deg;
}
& option:nth-child(2) {
--angle: 225deg;
}
& option:nth-child(3) {
--angle: 255deg;
}
}
}
@layer options {
option {
position: absolute;
top: 50%;
left: 50%;
z-index: 5;
display: flex;
width: var(--option-size);
height: var(--option-size);
margin-top: calc(var(--option-size) / -2);
margin-left: calc(var(--option-size) / -2);
padding: 0;
justify-content: center;
align-items: center;
font-size: var(--option-font-size);
color: #3a4a5a;
background: white;
border-radius: 50%;
box-shadow: 0 2px 10px rgba(100, 120, 160, 0.15);
transform: rotate(var(--angle)) translateX(var(--option-distance))
rotate(calc(-1 * var(--angle)));
transform-origin: center;
transition: transform 0.2s linear, background-color 0.3s ease-out,
box-shadow 0.3s ease-out;
pointer-events: auto;
cursor: pointer;
&::checkmark {
display: none;
}
&:hover {
background: var(--hover-color);
box-shadow: 0 4px 15px rgba(100, 120, 160, 0.2);
transform: rotate(var(--angle)) translateX(var(--option-distance))
rotate(calc(-1 * var(--angle))) scale(1.2);
}
&:checked {
background: var(--selected-color);
box-shadow: 0 4px 15px rgba(100, 120, 160, 0.25);
transform: rotate(var(--angle)) translateX(var(--option-distance))
rotate(calc(-1 * var(--angle))) scale(1.1);
}
}
}
@layer presentation {
body {
position: relative;
display: flex;
min-height: 100vh;
margin: 0;
flex-direction: column;
place-items: center;
place-content: center;
font-family: "Yellowtail", cursive;
color: var(--text-color);
background: linear-gradient(
135deg,
#e6f5f7 0%,
#d8ebf2 20%,
#e1e6f5 40%,
#e8e6f5 60%,
#d8e6f7 80%,
#e1e8f5 100%
);
}
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.