<div class="topbar">
<i class="fa-solid fa-paw"></i>
<span class="logo-text">MEOWATAR</span>
</div>
<form class="container">
<!-- Eyes -->
<input type="radio" name="eyes" id="eyes_round" class="hidden" checked />
<input type="radio" name="eyes" id="eyes_droopy" class="hidden" />
<input type="radio" name="eyes" id="eyes_border" class="hidden" />
<!-- Mouth -->
<input type="radio" name="mouth" id="mouth_w" class="hidden" checked />
<input type="radio" name="mouth" id="mouth_inverted-y" class="hidden" />
<input type="radio" name="mouth" id="mouth_smile" class="hidden" />
<input type="radio" name="mouth" id="mouth_triangle" class="hidden" />
<!-- Hat -->
<input type="radio" name="hat" id="hat_none" class="hidden" checked />
<input type="radio" name="hat" id="hat_top-hat" class="hidden" />
<input type="radio" name="hat" id="hat_ribbon" class="hidden" />
<!-- Dress -->
<!-- <input type="radio" name="dress" id="dress_none" class="hidden" checked />
<input type="radio" name="dress" id="dress_tie" class="hidden" checked />
<input type="radio" name="dress" id="dress_skirt" class="hidden" checked /> -->
<!-- Fur -->
<input type="radio" name="fur" id="fur_white" class="hidden" checked />
<input type="radio" name="fur" id="fur_orange" class="hidden" />
<input type="radio" name="fur" id="fur_brown" class="hidden" />
<input type="radio" name="fur" id="fur_gray" class="hidden" />
<input type="radio" name="fur" id="fur_blue" class="hidden" />
<div class="avatar-container">
<div class="avatar-frame">
<div class="avatar">
<div class="body">
<div class="arm left"></div>
<div class="arm right"></div>
</div>
<div class="head">
<div class="ear left"></div>
<div class="ear right"></div>
<div class="eye left"></div>
<div class="eye right"></div>
<div class="nose"></div>
<div class="mouth"></div>
<div class="whisker top left"></div>
<div class="whisker middle left"></div>
<div class="whisker bottom left"></div>
<div class="whisker top right"></div>
<div class="whisker middle right"></div>
<div class="whisker bottom right"></div>
<div class="hat"></div>
</div>
<div class="leg left"></div>
<div class="leg right"></div>
</div>
</div>
<div class="buttons-container">
<button type="button" id="btn_save" title="Ain't working lol">
<i class="fa-regular fa-floppy-disk"></i>
Save changes
</button>
<button type="reset" id="btn_discard" title="No JavaScript so, no confirmation">
<i class="fa-solid fa-xmark"></i>
Discard changes
</button>
</div>
</div>
<div class="selection-container">
<div class="selection-list">
<a href="#eyes_selection" class="selection-link">
<i class="fa-regular fa-eye"></i>
<span class="selection-link-text">Eyes</span>
</a>
<a href="#mouth_selection" class="selection-link">
<i class="fa-regular fa-face-smile"></i>
<span class="selection-link-text">Mouth</span>
</a>
<a href="#hat_selection" class="selection-link">
<i class="fa-solid fa-hat-cowboy"></i>
<span class="selection-link-text">Hat</span>
</a>
<!-- <a href="#dress_selection" class="selection-link">
<i class="fa-solid fa-shirt"></i>
<span class="selection-link-text">Dress</span>
</a> -->
<a href="#fur_selection" class="selection-link">
<i class="fa-solid fa-circle"></i>
<span class="selection-link-text">Fur</span>
</a>
</div>
<div class="selections">
<div id="eyes_selection" class="selection">
<label for="eyes_round" class="selection-item">
<span class="eyes round"></span>
</label>
<label for="eyes_droopy" class="selection-item">
<span class="eyes droopy"></span>
</label>
<label for="eyes_border" class="selection-item">
<span class="eyes border"></span>
</label>
</div>
<div id="mouth_selection" class="selection">
<label for="mouth_w" class="selection-item">
<span class="selection-mouth w"></span>
</label>
<label for="mouth_inverted-y" class="selection-item">
<span class="selection-mouth inverted-y"></span>
</label>
<label for="mouth_smile" class="selection-item">
<span class="selection-mouth smile"></span>
</label>
<label for="mouth_triangle" class="selection-item">
<span class="selection-mouth triangle"></span>
</label>
</div>
<div id="hat_selection" class="selection">
<label for="hat_none" class="selection-item">
<span class="selection-hat none"></span>
</label>
<label for="hat_top-hat" class="selection-item">
<span class="selection-hat top-hat"></span>
</label>
<label for="hat_ribbon" class="selection-item">
<span class="selection-hat ribbon"></span>
</label>
</div>
<!-- <div id="dress_selection" class="selection">
<label for="dress_none" class="selection-item">
<span class="selection-dress none"></span>
</label>
</div> -->
<div id="fur_selection" class="selection">
<label for="fur_white" class="selection-item">
<span class="fur white"></span>
</label>
<label for="fur_orange" class="selection-item">
<span class="fur orange"></span>
</label>
<label for="fur_brown" class="selection-item">
<span class="fur brown"></span>
</label>
<label for="fur_gray" class="selection-item">
<span class="fur gray"></span>
</label>
<label for="fur_blue" class="selection-item">
<span class="fur blue"></span>
</label>
</div>
</div>
</div>
</form>
@import url('https://fonts.googleapis.com/css?family=Montserrat:400,400i,700');
$selections: ['eyes', 'mouth', 'hat', 'dress', 'fur'];
$eyes: ['round', 'droopy', 'border'];
$mouths: ['w', 'inverted-y', 'smile', 'triangle'];
$hats: ['none', 'top-hat', 'ribbon'];
$dresses: ['none', 'tie', 'skirt'];
$furs: [
('white', #ededed),
('orange', #e8813c),
('brown', #8a5846),
('gray', #c2c2c2),
('blue', #3c4259),
];
$sm: 512px;
$md: 768px;
$lg: 960px;
$xl: 1024px;
$bg-color: #2f2f2f;
$main-color: #fed235;
$sub-color: #fafafa;
$selection-color: #272727;
$spacing-ss: 0.5rem;
$spacing-xs: 0.75rem;
$spacing-sm: 1rem;
$spacing-md: 1.25rem;
$spacing-lg: 2rem;
$transition-72: 72ms;
$avatar-frame-width: 24rem;
$avatar-frame-width-sm: 16rem;
$avatar-frame-shadow: 0 1.5rem 3.75rem rgba(#000000, 0.75) inset;
$avatar-frame-shadow-sm: 0 1rem 3rem rgba(#000000, 0.3) inset;
$head-size: 10rem;
$body-width: 4rem;
$body-height: 5rem;
$selection-item-height: 7.5rem;
$eyes-round-size: 0.5rem;
$eyes-droopy-width: 2rem;
$eyes-droopy-height: 1rem;
$eyes-droopy-pupil-width: 1.1rem;
$eyes-droopy-pupil-height: 0.6rem;
$eyes-border-size: 1rem;
$eyes-border-border-width: 0.15rem;
$ear-width: 4.5rem;
$ear-height: 4.5rem;
$ear-x: -0.9rem;
$ear-y: -2rem;
$ear-angle: 26deg;
$eye-x: 2.5rem;
$eye-y: 4.25rem;
$nose-width: 1.25rem;
$nose-height: 0.75rem;
$nose-y: 5.5rem;
$mouth-border-width: 0.2rem;
$mouth-y: 7rem;
$mouth-w-width: 2.5rem;
$mouth-w-height: 0.5rem;
$mouth-w-skew: 10deg;
$mouth-inverted-y-height: 1rem;
$mouth-inverted-y-sin-45: 0.70710678118;
$mouth-inverted-y-cos-45: 0.70710678118;
$mouth-smile-width: 2.5rem;
$mouth-smile-height: 0.75rem;
$whisker-width: 3.5rem;
$whisker-height: 0.2rem;
$whisker-x: -1.5rem;
$whisker-top-y: 5.25rem;
$whisker-middle-y: 6.5rem;
$whisker-bottom-y: 7.75rem;
$whisker-top-angle: 10deg;
$whisker-middle-angle: 3deg;
$whisker-bottom-angle: -5deg;
$mouth-triangle-width: 1.75rem;
$mouth-triangle-height: 1.25rem;
$arm-width: 1.5rem;
$arm-height: 2.25rem;
$arm-x: 0.2rem;
$arm-y: 1.1rem;
$arm-angle: 65deg;
$arm-idle-angle: 75deg;
$leg-width: 2.15rem;
$leg-height: 1.25rem;
$leg-x: 2.25rem;
$leg-y: calc(100% + 0.05rem);
$idle-y: 0.2rem;
$idle-animation: idle 512ms ease-out infinite;
$arm-left-idle-animation: arm-left-idle 512ms ease-out infinite;
$arm-right-idle-animation: arm-right-idle 512ms ease-out infinite;
$hat-top-hat-color: #000000;
$hat-top-hat-width: 8rem;
$hat-top-hat-height: 8rem;
$hat-top-hat-y: -4.25rem;
$hat-top-hat-base-width: 12rem;
$hat-top-hat-base-height: 1rem;
$hat-top-hat-ribbon-color: #c92424;
$hat-top-hat-ribbon-height: 1rem;
$selection-none-size: 4rem;
$selection-none-color: #ffffff;
$selection-none-width: 0.5rem;
$hat-ribbon-color: #de6291;
$hat-ribbon-width: 1.75rem;
$hat-ribbon-height: 1.75rem;
$hat-ribbon-depth: 0.75rem;
$hat-ribbon-x: 8.5rem;
$hat-ribbon-y: 0.75rem;
$hat-ribbon-angle: 25deg;
@mixin eye-round() {
background-color: #000000;
width: $eyes-round-size;
height: $eyes-round-size;
border-radius: 99999px;
}
@mixin eye-droopy() {
background-color: #ffffff;
width: $eyes-droopy-width;
height: $eyes-droopy-height;
display: flex;
justify-content: center;
align-items: flex-start;
border-radius: 0 0 99999px 99999px;
&::before {
content: '';
background-color: #000000;
width: $eyes-droopy-pupil-width;
height: $eyes-droopy-pupil-height;
display: block;
border-radius: 0 0 99999px 99999px;
}
}
@mixin eye-border() {
background-color: #ffffff;
width: $eyes-border-size;
height: $eyes-border-size;
border: solid $eyes-border-border-width #000000;
border-radius: 99999px;
}
@mixin mouth-w() {
display: flex;
&::before, &::after {
content: '';
width: $mouth-w-width / 2;
height: $mouth-w-height;
border: solid $mouth-border-width #000000;
border-top: none;
display: block;
border-radius: 0% 0% 50% 50% / 0% 0% 100% 100%;
}
&::before {
transform: translateX($mouth-border-width / 2) skewY(-$mouth-w-skew);
}
&::after {
transform: translateX($mouth-border-width / -2) skewY($mouth-w-skew);
}
}
@mixin mouth-inverted-y() {
background-color: #000000;
width: $mouth-border-width;
height: $mouth-inverted-y-height;
position: relative;
&::before {
// HACK: 1rem * cos(45) or 1rem * sin(45) causes invalid operation
$width: $mouth-inverted-y-height * $mouth-inverted-y-cos-45;
$height: $mouth-inverted-y-height * $mouth-inverted-y-sin-45;
content: '';
width: $width;
height: $height;
border: solid $mouth-border-width #000000;
border-bottom: none;
border-right: none;
display: block;
position: absolute;
top: calc(100% - #{$mouth-border-width});
left: calc(50% - #{$width / 2});
transform-origin: $mouth-border-width / 2;
transform: rotate(45deg);
}
}
@mixin mouth-smile() {
width: $mouth-smile-width;
height: $mouth-smile-height;
border: solid $mouth-border-width #000000;
border-top: none;
border-radius: 0% 0% 50% 50% / 0% 0% 100% 100%;
}
@mixin mouth-triangle() {
width: 0;
height: 0;
border-bottom: solid $mouth-triangle-height #000000;
border-left: solid $mouth-triangle-width / 2 transparent;
border-right: solid $mouth-triangle-width / 2 transparent;
}
@mixin hat-top-hat($set-position) {
background-color: $hat-top-hat-color;
width: $hat-top-hat-width;
height: $hat-top-hat-height;
@if $set-position {
top: $hat-top-hat-y;
left: 50%;
transform: translateX(-50%);
}
&::before, &::after {
content: '';
display: block;
position: absolute;
}
&::before {
background-color: $hat-top-hat-ribbon-color;
width: 100%;
height: $hat-top-hat-ribbon-height;
position: absolute;
left: 0;
bottom: $hat-top-hat-base-height;
}
&::after {
background-color: $hat-top-hat-color;
width: $hat-top-hat-base-width;
height: $hat-top-hat-base-height;
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
}
@mixin hat-ribbon($set-position) {
transform: rotate($hat-ribbon-angle);
@if $set-position {
top: $hat-ribbon-y;
left: $hat-ribbon-x;
}
&::before, &::after {
content: '';
width: 0;
height: $hat-ribbon-depth;
position: absolute;
}
&::before {
border-top: solid ($hat-ribbon-height / 2) transparent;
border-bottom: solid ($hat-ribbon-height / 2) transparent;
border-left: solid $hat-ribbon-width $hat-ribbon-color;
right: 0;
}
&::after {
border-top: solid ($hat-ribbon-height / 2) transparent;
border-bottom: solid ($hat-ribbon-height / 2) transparent;
border-right: solid $hat-ribbon-width $hat-ribbon-color;
left: 0;
}
}
@mixin selection-none() {
width: $selection-none-size;
height: $selection-none-size;
border: solid $selection-none-width $selection-none-color;
display: flex;
justify-content: center;
border-radius: 99999px;
&::before {
content: '';
background-color: $selection-none-color;
width: $selection-none-width;
height: 100%;
display: block;
transform: rotate(45deg);
}
}
:root, button {
font-family: Montserrat, sans-serif;
font-size: 16px;
}
* {
box-sizing: border-box;
}
body {
background-color: $bg-color;
}
.topbar {
color: #ffffff;
font-size: 2rem;
font-weight: bold;
background-color: #0a0a0a;
padding: $spacing-sm;
margin-bottom: $spacing-sm;
}
.logo-text {
display: none;
}
.container {
width: 100%;
display: flex;
flex-direction: column;
}
.avatar-container {
display: flex;
flex-direction: column;
}
.avatar-frame {
background-color: $bg-color;
width: 100%;
height: $avatar-frame-width;
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
position: sticky;
top: 0;
box-shadow: $avatar-frame-shadow;
}
.avatar {
display: flex;
flex-direction: column;
align-items: center;
position: relative;
}
.head {
width: $head-size;
height: $head-size;
order: 1;
position: relative;
border-radius: 99999px;
animation: $idle-animation;
}
.ear {
width: 0;
height: 0;
border-bottom: solid $ear-width;
border-left: solid ($ear-height / 2) transparent;
border-right: solid ($ear-height / 2) transparent;
position: absolute;
top: $ear-y;
&.left {
left: $ear-x;
transform: rotate(-$ear-angle);
}
&.right {
right: $ear-x;
transform: rotate($ear-angle);
}
}
.eye {
position: absolute;
top: $eye-y;
&.left {
left: $eye-x;
transform: translateX(-50%);
}
&.right {
right: $eye-x;
transform: translateX(50%);
}
}
.nose {
background-color: #000000;
width: $nose-width;
height: $nose-height;
position: absolute;
top: $nose-y;
left: 50%;
transform: translateX(-50%);
border-radius: 50% 50% 50% 50% / 25% 25% 75% 75%;
}
.mouth {
position: absolute;
top: $mouth-y;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
.whisker {
background-color: #000000;
width: $whisker-width;
height: $whisker-height;
position: absolute;
&.top {
top: $whisker-top-y;
&.left {
transform: rotate($whisker-top-angle);
}
&.right {
transform: rotate(-$whisker-top-angle);
}
}
&.middle {
top: $whisker-middle-y;
&.left {
transform: rotate($whisker-middle-angle);
}
&.right {
transform: rotate(-$whisker-middle-angle);
}
}
&.bottom {
top: $whisker-bottom-y;
&.left {
transform: rotate($whisker-bottom-angle);
}
&.right {
transform: rotate(-$whisker-bottom-angle);
}
}
&.left {
left: $whisker-x;
}
&.right {
right: $whisker-x;
}
}
.hat {
position: absolute;
}
.body {
width: $body-width;
height: $body-height;
margin-top: -1rem;
order: 2;
position: relative;
border-radius: 99999px;
animation: $idle-animation;
}
.arm {
width: $arm-width;
height: $arm-height;
position: absolute;
top: $arm-y;
border-radius: 0 0 99999px 99999px;
&.left {
left: $arm-x;
transform-origin: top left;
transform: rotate($arm-angle);
animation: $arm-left-idle-animation;
}
&.right {
right: $arm-x;
transform-origin: top right;
transform: rotate(-$arm-angle);
animation: $arm-right-idle-animation;
}
}
.leg {
width: $leg-width;
height: $leg-height;
position: absolute;
top: $leg-y;
border-radius: 99999px 99999px 0 0;
&.left {
left: $leg-x;
}
&.right {
right: $leg-x;
}
}
.buttons-container {
width: 100%;
padding: $spacing-md;
display: flex;
flex-direction: column;
& > button {
padding: $spacing-sm $spacing-lg;
border: 0;
margin-bottom: $spacing-md;
cursor: pointer;
border-radius: $spacing-ss;
transition: background-color $transition-72 ease-out;
&:last-child {
margin-bottom: 0;
}
}
}
#btn_save {
background-color: $main-color;
&:hover {
background-color: darken($main-color, 10%);
}
&:active {
background-color: darken($main-color, 20%);
}
}
#btn_discard {
background-color: $sub-color;
&:hover {
background-color: darken($sub-color, 10%);
}
&:active {
background-color: darken($sub-color, 20%);
}
}
.selection-container {
width: 100%;
}
.selection-list {
display: flex;
}
.selection-link {
color: #ffffff;
text-align: center;
text-decoration: none;
width: 100%;
padding: $spacing-sm $spacing-md;
transition:
color $transition-72 ease-out,
background-color $transition-72 ease-out;
cursor: pointer;
&:hover {
background-color: rgba(#000000, 0.15);
}
}
.selection-link-text {
display: none;
margin-top: $spacing-ss;
}
.selections {
position: relative;
}
.selection {
width: 100%;
padding: $spacing-md;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: $spacing-xs;
position: absolute;
top: 0;
left: 0;
opacity: 0;
pointer-events: none;
&:target {
opacity: 1;
pointer-events: auto;
}
}
.selection-item {
background-color: $selection-color;
height: $selection-item-height;
border-radius: $spacing-xs;
display: grid;
justify-content: center;
align-items: center;
transition: background-color $transition-72 ease-out;
cursor: pointer;
&:hover {
background-color: darken($selection-color, 5%);
}
&:active {
background-color: darken($selection-color, 10%);
}
}
.eyes {
&.round {
@include eye-round();
}
&.droopy {
@include eye-droopy();
}
&.border {
@include eye-border();
}
}
.selection-mouth {
&.w {
@include mouth-w();
}
&.inverted-y {
@include mouth-inverted-y();
}
&.smile {
@include mouth-smile();
}
&.triangle {
@include mouth-triangle();
}
}
.selection-hat {
&.none {
@include selection-none();
}
&.top-hat {
@include hat-top-hat(false);
position: relative;
transform: scale(0.5);
}
&.ribbon {
@include hat-ribbon(false);
position: relative;
}
}
.fur {
display: block;
width: $spacing-lg;
height: $spacing-lg;
border-radius: 99999px;
}
@each $selection in $selections {
.container:has(##{$selection}_selection:target) {
a[href="##{$selection}_selection"] {
color: #000000;
background-color: $main-color;
}
}
}
@each $eye in $eyes {
.container:has(#eyes_#{$eye}:checked) {
label[for="eyes_#{$eye}"] {
background-color: $main-color;
}
.eye {
// HACK: meta.get-mixin and meta.apply doesn't work
@if $eye == 'round' {
@include eye-round();
} @else if $eye == 'droopy' {
@include eye-droopy();
} @else if $eye == 'border' {
@include eye-border();
}
}
}
}
@each $mouth in $mouths {
.container:has(#mouth_#{$mouth}:checked) {
label[for="mouth_#{$mouth}"] {
background-color: $main-color;
}
.avatar > .head > .mouth {
@if $mouth == 'w' {
@include mouth-w();
} @else if $mouth == 'inverted-y' {
@include mouth-inverted-y();
} @else if $mouth == 'smile' {
@include mouth-smile();
} @else if $mouth == 'triangle' {
@include mouth-triangle();
}
}
}
}
@each $hat in $hats {
.container:has(#hat_#{$hat}:checked) {
label[for="hat_#{$hat}"] {
background-color: $main-color;
}
.hat {
@if $hat == 'top-hat' {
@include hat-top-hat(true);
} @else if $hat == 'ribbon' {
@include hat-ribbon(true);
}
}
}
}
@each $fur, $color in $furs {
.container:has(#fur_#{$fur}:checked) {
label[for="fur_#{$fur}"] {
background-color: $main-color;
}
.avatar {
& > div:is(.head, .body, .leg) {
background-color: $color;
& > div:is(.arm) {
background-color: $color;
}
}
& > .head > .ear {
border-bottom-color: $color;
}
}
}
.fur.#{$fur} {
background-color: $color;
}
}
.hidden {
display: none;
}
@keyframes idle {
0% {
transform: translateY(0rem);
}
50% {
transform: translateY($idle-y);
}
0% {
transform: translateY(0rem);
}
}
@keyframes arm-left-idle {
0% {
transform: rotate($arm-angle);
}
50% {
transform: rotate($arm-idle-angle);
}
0% {
transform: rotate($arm-angle);
}
}
@keyframes arm-right-idle {
0% {
transform: rotate(-$arm-angle);
}
50% {
transform: rotate(-$arm-idle-angle);
}
0% {
transform: rotate(-$arm-angle);
}
}
@media screen and (width >= $sm) {
.logo-text {
display: inline-block;
}
.avatar-frame {
width: $avatar-frame-width-sm;
}
.avatar-container {
flex-direction: row;
}
.avatar-frame {
box-shadow: $avatar-frame-shadow-sm;
}
.buttons-container {
padding-top: 0;
}
.selection-container {
margin-top: $spacing-md;
}
.selection-link-text {
display: block;
}
}
@media screen and (width >= $md) {
.container {
max-width: $lg;
margin: auto;
flex-direction: row;
align-items: flex-start;
}
.avatar-container {
flex-direction: column;
}
.buttons-container {
padding-top: $spacing-md;
}
.selection-container {
margin-top: 0;
}
.selection-list {
padding-left: $spacing-md;
padding-right: $spacing-md;
}
.selection {
min-width: $sm;
}
}
@media screen and (width >= $lg) {
.buttons-container {
padding-left: 0;
padding-right: 0;
}
}
View Compiled
This Pen doesn't use any external JavaScript resources.