Last active
April 1, 2026 23:42
-
-
Save greggman/99780b1a6c7235d083e7a812bb494e40 to your computer and use it in GitHub Desktop.
CSS face element
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| :root { | |
| --face-size: 100px; | |
| --line-color: #333; | |
| --line-width: 4px; | |
| --skin-color: #ffcc00; | |
| } | |
| body { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| min-height: 100vh; | |
| margin: 0; | |
| } | |
| /* --- THE SINGLE ELEMENT FACE --- */ | |
| face, .face { | |
| display: block; | |
| width: var(--face-size); | |
| height: var(--face-size); | |
| border: var(--line-width) solid var(--line-color); | |
| border-radius: 50%; | |
| background-color: var(--skin-color); | |
| position: relative; | |
| box-sizing: border-box; | |
| transition: all 0.3s ease; | |
| /* Background layers for EYES */ | |
| background-repeat: no-repeat; | |
| } | |
| /* 1. EYES (Background Gradients on the main element) */ | |
| .eyes-open { | |
| background-image: | |
| radial-gradient(circle, var(--line-color) 50%, transparent 55%), | |
| radial-gradient(circle, var(--line-color) 50%, transparent 55%); | |
| background-size: 16% 16%; | |
| background-position: 30% 55%, 70% 55%; | |
| } | |
| .eyes-closed-up { | |
| background-image: | |
| radial-gradient(ellipse at 50% 100%, transparent 45%, var(--line-color) 46%, var(--line-color) 64%, transparent 65%), | |
| radial-gradient(ellipse at 50% 100%, transparent 45%, var(--line-color) 46%, var(--line-color) 64%, transparent 65%); | |
| background-size: 32% 16%; | |
| background-position: 25% 55%, 75% 55%; | |
| } | |
| .eyes-closed-down { | |
| background-image: | |
| radial-gradient(ellipse at 50% 0%, transparent 45%, var(--line-color) 46%, var(--line-color) 64%, transparent 65%), | |
| radial-gradient(ellipse at 50% 0%, transparent 45%, var(--line-color) 46%, var(--line-color) 64%, transparent 65%); | |
| background-size: 32% 16%; | |
| background-position: 25% 55%, 75% 55%; | |
| } | |
| .eyes-wink { | |
| background-image: | |
| radial-gradient(circle, var(--line-color) 50%, transparent 55%), | |
| linear-gradient(0deg, transparent 40%, var(--line-color) 41%, var(--line-color) 59%, transparent 60%); | |
| background-size: 16% 16%, 16% 16%; | |
| background-position: 30% 55%, 65% 55%; | |
| } | |
| /* 2. EYEBROWS (::before) */ | |
| face::before { | |
| content: ''; | |
| position: absolute; | |
| top: 15%; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| width: 80%; | |
| height: 30px; /* Taller box allows slant to be visible */ | |
| background-repeat: no-repeat; | |
| background-size: 25px 100%; | |
| transition: all 0.3s ease; | |
| } | |
| .brows-up::before { | |
| background-image: | |
| linear-gradient(-25deg, transparent 40%, var(--line-color) 41%, var(--line-color) 56%, transparent 57%), | |
| linear-gradient(25deg, transparent 40%, var(--line-color) 41%, var(--line-color) 56%, transparent 57%); | |
| background-position: 15% 50%, 85% 50%; | |
| } | |
| .brows-down::before { | |
| background-image: | |
| linear-gradient(25deg, transparent 40%, var(--line-color) 41%, var(--line-color) 56%, transparent 57%), | |
| linear-gradient(-25deg, transparent 40%, var(--line-color) 41%, var(--line-color) 56%, transparent 57%); | |
| background-position: 15% 50%, 85% 50%; | |
| } | |
| .brows-none::before { opacity: 0; } | |
| /* 3. MOUTH (::after) */ | |
| face::after { | |
| content: ''; | |
| position: absolute; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| bottom: 5%; | |
| width: 80%; | |
| transition: all 0.3s ease; | |
| background-repeat: no-repeat; | |
| } | |
| .smile-closed::after { | |
| height: 80%; | |
| background-image: | |
| radial-gradient(ellipse at 50% 0%, transparent 45%, var(--line-color) 46%, var(--line-color) 64%, transparent 65%); | |
| background-size: 64% 32%; | |
| background-position: 50% 100%; | |
| } | |
| .smile-open::after { | |
| height: 80%; | |
| background-image: | |
| radial-gradient(ellipse at 50% 0%, transparent 55%, var(--line-color) 56%, var(--line-color) 72%, transparent 73%), | |
| linear-gradient(0deg, transparent 79%, var(--line-color) 80%, var(--line-color) 100%); | |
| background-size: 64% 32%; | |
| background-position: 50% 100%; | |
| } | |
| .frown::after { | |
| height: 80%; | |
| background-image: | |
| radial-gradient(ellipse at 50% 100%, transparent 45%, var(--line-color) 46%, var(--line-color) 64%, transparent 65%); | |
| background-size: 64% 32%; | |
| background-position: 50% 90%; | |
| } | |
| .oh::after { | |
| width: 16%; | |
| height: 16%; | |
| bottom: 10%; | |
| border: var(--line-width) solid var(--line-color); | |
| border-radius: 50%; | |
| } | |
| .anger::after { | |
| height: 80%; | |
| background-image: | |
| radial-gradient(ellipse at 50% 100%, transparent 55%, var(--line-color) 56%, var(--line-color) 72%, transparent 73%), | |
| linear-gradient(0deg, var(--line-color) 0%, var(--line-color) 20%, transparent 21%); | |
| background-size: 64% 32%; | |
| background-position: 50% 90%; | |
| } | |
| .hrm::after { | |
| height: 80%; | |
| background-image: | |
| radial-gradient(ellipse at 50% 0%, transparent 45%, var(--line-color) 46%, var(--line-color) 84%, transparent 85%), | |
| radial-gradient(ellipse at 50% 100%, transparent 45%, var(--line-color) 46%, var(--line-color) 84%, transparent 85%), | |
| radial-gradient(ellipse at 50% 0%, transparent 45%, var(--line-color) 46%, var(--line-color) 84%, transparent 85%), | |
| radial-gradient(ellipse at 50% 100%, transparent 45%, var(--line-color) 46%, var(--line-color) 84%, transparent 85%), | |
| radial-gradient(ellipse at 50% 0%, transparent 45%, var(--line-color) 46%, var(--line-color) 84%, transparent 85%); | |
| background-position: 16% 80%, 32% 73%, 48% 80%, 64% 73%, 80% 80%; | |
| background-size: 16% 8%; | |
| } | |
| /* --- DEMO STYLING --- */ | |
| .container { text-align: center; } | |
| .controls { | |
| margin-top: 30px; | |
| display: flex; | |
| flex-wrap: wrap; | |
| justify-content: center; | |
| gap: 15px; | |
| background: white; | |
| padding: 20px; | |
| border-radius: 12px; | |
| box-shadow: 0 10px 25px rgba(0,0,0,0.1); | |
| } | |
| .control-item { display: flex; flex-direction: column; gap: 5px; align-items: flex-start; } | |
| label { font-size: 12px; font-weight: bold; color: #888; text-transform: uppercase; } | |
| select { padding: 8px 12px; border-radius: 8px; border: 1px solid #ddd; background: #fff; cursor: pointer; } | |
| .code { margin-top: 25px; font-family: 'Courier New', Courier, monospace; background: #2d2d2d; color: #a6e22e; padding: 15px; border-radius: 8px; font-size: 14px; } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="container"> | |
| <face id="targetFace" class="brows-up eyes-open frown"></face> | |
| <div class="code" id="codeOut"> | |
| <face class="brows-up eyes-open smile-closed"></face> | |
| </div> | |
| <div class="controls"> | |
| <div class="control-item"> | |
| <label>Eyebrows</label> | |
| <select id="b" onchange="up()"> | |
| <option value="brows-none">None</option> | |
| <option value="brows-up" selected>Up (/ \)</option> | |
| <option value="brows-down">Down (\ /)</option> | |
| </select> | |
| </div> | |
| <div class="control-item"> | |
| <label>Eyes</label> | |
| <select id="e" onchange="up()"> | |
| <option value="eyes-open" Open</option> | |
| <option value="eyes-closed-up">Closed (n n)</option> | |
| <option value="eyes-closed-down">Closed (u u)</option> | |
| <option value="eyes-wink" selected>Wink</option> | |
| </select> | |
| </div> | |
| <div class="control-item"> | |
| <label>Mouth</label> | |
| <select id="m" onchange="up()"> | |
| <option value="smile-closed" >Smile (U)</option> | |
| <option value="smile-open">Smile (D)</option> | |
| <option value="frown">Frown (n)</option> | |
| <option value="oh">Oh (o)</option> | |
| <option value="anger">Anger (D-up)</option> | |
| <option value="hrm" selected>Hrm (~)</option> | |
| </select> | |
| </div> | |
| </div> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function up() { | |
| const f = document.getElementById('targetFace'); | |
| const b = document.getElementById('b').value; | |
| const e = document.getElementById('e').value; | |
| const m = document.getElementById('m').value; | |
| const classes = `${b} ${e} ${m}`; | |
| f.className = classes; | |
| document.getElementById('codeOut').innerText = `<face class="${classes}"></face>`; | |
| } | |
| up(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {"name":"CSS face element","settings":{},"filenames":["index.html","index.css","index.js"]} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment