Model: gpt-4.1-mini
-- none --
b2203d90fe3d6fc3aaf227f37a3e535162f853eab1cc2d3cafc6b2b4ef3c6e12
@charset "UTF-8";
/*
pug index.pug -w
sass main.scss:main.css -w
*/
:root {
color-scheme: dark;
--cube-size: 5rem;
--camera-distance: 50rem;
--air-image: none;
--pickaxe-image: url("./assets/pickaxe.png");
--stone-image: url("./assets/stone.png");
--grass-image: url("./assets/grass_side_carried.png");
--grass-top-image: url("./assets/grass_carried.png");
--dirt-image: url("./assets/dirt.png");
--log-image: url("./assets/log_oak.png");
--wood-image: url("./assets/oak_planks.png");
--log-top-image: url("./assets/log_oak_top.png");
--leaves-image: url("./assets/azalea_leaves.png");
--glass-image: url("./assets/glass.png");
pointer-events: none;
}
body {
color: white;
background-color: lightSkyBlue;
block-size: 100vh;
block-size: 100dvb;
margin: 0;
box-sizing: border-box;
font-family: system-ui, sans-serif;
overflow: hidden;
display: grid;
place-content: center center;
}
label, button {
cursor: pointer;
}
h1, p {
margin: 0;
}
h1, strong {
font-weight: 600;
}
a {
color: inherit;
}
.info {
pointer-events: auto;
z-index: 1;
position: absolute;
inset-block-start: 0;
inset-inline: 0;
padding: 0.75rem;
margin-inline: auto;
inline-size: fit-content;
max-inline-size: min(60rem, 100vw - 10rem);
background-color: rgba(17, 17, 17, 0.4666666667);
--backdrop-filter: blur(.4rem);
-webkit-backdrop-filter: var(--backdrop-filter);
backdrop-filter: var(--backdrop-filter);
border-radius: 0.6rem;
border-start-start-radius: 0;
border-start-end-radius: 0;
text-align: center;
box-shadow: 0 0 1.5rem rgba(0, 0, 0, 0.4);
display: flex;
align-items: center;
gap: 1rem;
}
.info strong {
color: gold;
}
.info .text {
display: flex;
flex-direction: column;
gap: 0.3rem;
}
.info .close {
padding-inline: 0.3rem;
}
.info .close::before {
content: "⨉";
font-size: 1.5rem;
}
.info .close > input[type=checkbox] {
position: absolute;
opacity: 0;
pointer-events: none;
}
.info:has(.close > input[type=checkbox]:checked) {
display: none;
}
.info .not-supported {
border: 2px solid red;
background-color: rgba(255, 0, 0, 0.2666666667);
border-radius: 0.7rem;
padding: 0.6rem 0.4rem;
}
@supports selector(:has(a)) {
.info .not-supported {
display: none;
}
}
.controls {
pointer-events: auto;
z-index: 2;
position: absolute;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: 1.25rem;
border-radius: 0.8rem;
box-shadow: 0 0 1.5rem rgba(0, 0, 0, 0.4);
background-color: rgba(34, 34, 34, 0.5333333333);
--backdrop-filter: blur(.3rem);
-webkit-backdrop-filter: var(--backdrop-filter);
backdrop-filter: var(--backdrop-filter);
padding: 0.75rem;
padding-block-start: 0.5rem;
margin-block-end: 0.75rem;
inset-block-end: 0;
inset-inline: 0;
margin-inline: auto;
inline-size: fit-content;
max-inline-size: calc(100vw - 4rem);
}
.controls .block-chooser {
display: flex;
align-items: center;
gap: 0.5rem;
}
.controls .block-chooser > label {
display: block;
inline-size: 3rem;
block-size: 3rem;
border-radius: 0.3rem;
box-sizing: border-box;
background-size: 100% 100%;
background-repeat: no-repeat;
image-rendering: pixelated;
outline-offset: 1px;
}
.controls .block-chooser > label.air {
background-image: var(--air-image);
}
.controls .block-chooser > label.stone {
background-image: var(--stone-image);
}
.controls .block-chooser > label.grass {
background-image: var(--grass-image);
}
.controls .block-chooser > label.dirt {
background-image: var(--dirt-image);
}
.controls .block-chooser > label.log {
background-image: var(--log-image);
}
.controls .block-chooser > label.wood {
background-image: var(--wood-image);
}
.controls .block-chooser > label.leaves {
background-image: var(--leaves-image);
}
.controls .block-chooser > label.glass {
background-image: var(--glass-image);
}
.controls .block-chooser > label.air {
background-image: var(--pickaxe-image);
}
.controls .block-chooser > label:hover {
outline: 2px solid silver;
}
.controls .block-chooser > label:has(> input[type=radio]:checked) {
outline: 2px solid white;
}
.controls .block-chooser > label > input[type=radio] {
position: absolute;
opacity: 0;
pointer-events: none;
}
.controls:has(> .block-chooser > .air > input[type=radio]:checked) ~ main .cubes-container > .cube:not(.air) {
display: none;
}
.controls:has(> .block-chooser > .stone > input[type=radio]:checked) ~ main .cubes-container > .cube:not(.stone) {
display: none;
}
.controls:has(> .block-chooser > .grass > input[type=radio]:checked) ~ main .cubes-container > .cube:not(.grass) {
display: none;
}
.controls:has(> .block-chooser > .dirt > input[type=radio]:checked) ~ main .cubes-container > .cube:not(.dirt) {
display: none;
}
.controls:has(> .block-chooser > .log > input[type=radio]:checked) ~ main .cubes-container > .cube:not(.log) {
display: none;
}
.controls:has(> .block-chooser > .wood > input[type=radio]:checked) ~ main .cubes-container > .cube:not(.wood) {
display: none;
}
.controls:has(> .block-chooser > .leaves > input[type=radio]:checked) ~ main .cubes-container > .cube:not(.leaves) {
display: none;
}
.controls:has(> .block-chooser > .glass > input[type=radio]:checked) ~ main .cubes-container > .cube:not(.glass) {
display: none;
}
.controls .block-chooser, .controls .move-button-pair {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(auto, 1fr));
justify-items: center;
gap: 0.5rem;
}
.controls .block-chooser > *:not(.label), .controls .move-button-pair > *:not(.label) {
grid-row: 2;
}
.controls .block-chooser > .label, .controls .move-button-pair > .label {
grid-column: 1/span 2;
}
.controls .block-chooser > .label {
grid-column-end: span 8;
}
.controls .move-buttons {
display: flex;
align-items: center;
gap: 1.25rem;
}
.controls .move-buttons button {
display: grid;
place-content: center;
inline-size: 3rem;
block-size: 3rem;
border: none;
border-radius: 0.3rem;
background-color: rgba(0, 0, 0, 0.2);
font-size: 1.5rem;
}
.controls .move-buttons button:hover {
background-color: rgba(0, 0, 0, 0.3333333333);
}
.controls .move-buttons button:active {
background-color: rgba(0, 0, 0, 0.4666666667);
}
.controls:has(.up:active) ~ main .down {
animation-play-state: running;
}
.controls:has(.down:active) ~ main .up {
animation-play-state: running;
}
.controls:has(.clockwise:active) ~ main .clockwise {
animation-play-state: running;
}
.controls:has(.counterclockwise:active) ~ main .counterclockwise {
animation-play-state: running;
}
.controls:has(.forwards:active) ~ main .backwards {
animation-play-state: running;
}
.controls:has(.backwards:active) ~ main .forwards {
animation-play-state: running;
}
.controls:has(.look-up:active) ~ main .look-up {
animation-play-state: running;
}
.controls:has(.look-down:active) ~ main .look-down {
animation-play-state: running;
}
main {
perspective: var(--camera-distance);
perspective-origin: center center;
}
main, main * {
transform-style: preserve-3d;
}
.content {
rotate: x -50grad;
--animation-duration: 10000s;
--max-translation: 400000rem;
--max-rotation: 3000turn;
}
.content .initial-camera-position {
translate: 0 calc(var(--layers) * var(--cube-size) * 0.4) calc(var(--camera-distance) - var(--rows) * var(--cube-size) * 0.9);
}
.content, .content .look-up, .content .look-down {
transform-origin: 0 0 var(--camera-distance);
}
.content .look-up {
animation: var(--animation-duration) linear 1ms paused look-up;
}
@keyframes look-up {
from {
rotate: x 0turn;
}
to {
rotate: x calc(var(--max-rotation));
}
}
.content .look-down {
animation: var(--animation-duration) linear 1ms paused look-down;
}
@keyframes look-down {
from {
rotate: x 0turn;
}
to {
rotate: x calc(-1 * var(--max-rotation));
}
}
.content .down {
animation: var(--animation-duration) linear 1ms paused move-down;
}
@keyframes move-down {
from {
translate: 0 0;
}
to {
translate: 0 calc(var(--max-translation));
}
}
.content .up {
animation: var(--animation-duration) linear 1ms paused move-up;
}
@keyframes move-up {
from {
translate: 0 0;
}
to {
translate: 0 calc(-1 * var(--max-translation));
}
}
.content .forwards {
animation: var(--animation-duration) linear 1ms paused move-forwards;
}
@keyframes move-forwards {
from {
translate: 0 0 0;
}
to {
translate: 0 0 calc(-1 * var(--max-translation));
}
}
.content .backwards {
animation: var(--animation-duration) linear 1ms paused move-backwards;
}
@keyframes move-backwards {
from {
translate: 0 0 0;
}
to {
translate: 0 0 calc(var(--max-translation));
}
}
.content .clockwise {
animation: var(--animation-duration) linear 1ms paused rotate-clockwise;
}
@keyframes rotate-clockwise {
from {
rotate: y 0turn;
}
to {
rotate: y calc(-1 * var(--max-rotation));
}
}
.content .counterclockwise {
animation: var(--animation-duration) linear 1ms paused rotate-counterclockwise;
}
@keyframes rotate-counterclockwise {
from {
rotate: y 0turn;
}
to {
rotate: y calc(var(--max-rotation));
}
}
.content .blocks {
position: relative;
translate: calc(-0.5 * var(--columns) * var(--cube-size)) calc(-0.5 * var(--layers) * var(--cube-size)) calc(-0.5 * var(--rows) * var(--cube-size));
}
.content .blocks .cubes-container {
pointer-events: auto;
translate: calc(var(--column) * var(--cube-size)) calc(var(--layer) * var(--cube-size)) calc(var(--row) * var(--cube-size));
}
.content .blocks .cubes-container:has(> .cube.air > input[type=radio]:checked) {
display: none;
}
.content .blocks .cubes-container:has(> .cube.air > input[type=radio]:checked) {
--background-image: var(--air-image);
}
.content .blocks .cubes-container:has(> .cube.stone > input[type=radio]:checked) {
--background-image: var(--stone-image);
}
.content .blocks .cubes-container:has(> .cube.grass > input[type=radio]:checked) {
--background-image: var(--grass-image);
}
.content .blocks .cubes-container:has(> .cube.dirt > input[type=radio]:checked) {
--background-image: var(--dirt-image);
}
.content .blocks .cubes-container:has(> .cube.log > input[type=radio]:checked) {
--background-image: var(--log-image);
}
.content .blocks .cubes-container:has(> .cube.wood > input[type=radio]:checked) {
--background-image: var(--wood-image);
}
.content .blocks .cubes-container:has(> .cube.leaves > input[type=radio]:checked) {
--background-image: var(--leaves-image);
}
.content .blocks .cubes-container:has(> .cube.glass > input[type=radio]:checked) {
--background-image: var(--glass-image);
}
.content .blocks .cubes-container .cube {
position: absolute;
block-size: var(--cube-size);
inline-size: var(--cube-size);
}
.content .blocks .cubes-container .cube > input[type=radio] {
position: absolute;
opacity: 0;
pointer-events: none;
}
.content .blocks .cubes-container .cube > label {
position: absolute;
inset: 0;
background-image: var(--background-image);
image-rendering: pixelated;
background-size: 100% 100%;
transform-origin: center center calc(-1 * var(--cube-size) / 2);
translate: 0 0 calc(var(--cube-size) / 2);
box-sizing: border-box;
}
.content .blocks .cubes-container .cube > label.front {
rotate: y 0grad;
filter: brightness(92%);
}
.content .blocks .cubes-container .cube > label.back {
rotate: y 200grad;
filter: brightness(68%);
}
.content .blocks .cubes-container .cube > label.left {
rotate: y 100grad;
filter: brightness(76%);
}
.content .blocks .cubes-container .cube > label.right {
rotate: y -100grad;
filter: brightness(84%);
}
.content .blocks .cubes-container .cube > label.top {
rotate: x 100grad;
filter: brightness(100%);
}
.content .blocks .cubes-container .cube > label.bottom {
rotate: x -100grad;
filter: brightness(60%);
}
.content .blocks .cubes-container:has(> .cube.grass > input[type=radio]:checked) > .cube > label.top {
background-image: var(--grass-top-image);
}
.content .blocks .cubes-container:has(> .cube.grass > input[type=radio]:checked) > .cube > label.bottom {
background-image: var(--dirt-image);
}
.content .blocks .cubes-container:has(> .cube.log > input[type=radio]:checked) > .cube > label:is(.top, bottom) {
background-image: var(--log-top-image);
}
.cubes-container > .cube > label:hover,
.controls:has(.air > input[type=radio]:checked) ~ main .cubes-container:hover > .cube > label {
--outline-width: calc(var(--cube-size) / 24);
outline: var(--outline-width) solid white;
outline-offset: calc(-1 * var(--outline-width));
}
.controls:has(.air > input[type=radio]:checked) ~ main .cubes-container:hover > .cube > label {
filter: brightness(70%);
}
/*# sourceMappingURL=main.css.map */
explain all the tricks used by this CSS
This CSS implements a complex, interactive 3D block-building interface, inspired by voxel games like Minecraft. Let me break down and explain the various clever and advanced tricks it uses:
:root
defines many custom properties (CSS variables) like:--cube-size
: size of each block cube (5rem).--camera-distance
: used for 3D perspective depth.- Various
--{block}-image
holding URLs for Minecraft-style textures (stone, grass, dirt, etc).
- These variables allow easy styling updates and consistent reuse, and tune 3D settings.
color-scheme: dark
on:root
enables automatic form control styling for dark mode.
- The entire app disables pointer events by default on
:root
(no interaction). - Specific interactive elements like
.info
,.controls
, and.cubes-container
enable pointer-events for user interaction.
- Uses
display: grid; place-content: center;
inbody
to perfectly center the content. block-size: 100vh; block-size: 100dvb;
two size units ensuring it fills viewport height robustly (viewport height and dynamic viewport block units).
.info
and.controls
usebackdrop-filter
with:- A CSS variable declaration
--backdrop-filter: blur(...)
cached in a variable. - Applied with standard and vendor-prefixed versions.
- A CSS variable declaration
- Provides a blurred translucent background behind content overlays for nice UI.
- This advanced CSS pseudo-class lets styles be applied based on child state.
- Examples:
.info:has(.close > input[type=checkbox]:checked)
hides the info panel when checkbox inside.close
is checked (custom close button)..controls:has(> .block-chooser > .stone > input[type=radio]:checked) ~ main .cubes-container > .cube:not(.stone)
hides blocks that don't match the selected type.- Highlight currently selected block with outline by styling label with
:has(> input[type=radio]:checked)
. - Animations triggered when buttons inside
.controls
are active using:has(:active)
selector.
This use of :has()
eliminates the need for JavaScript for many state-driven UI behaviors.
- Defines several keyframe animations like
move-up
,rotate-clockwise
,look-up
, etc. - These animations have duration set to a very large value (
10000s
) and are initially paused. - When control buttons are pressed (
:has(.up:active)
), the related animation playback state is toggled torunning
. - This lets CSS animate camera or block group translations and rotations smoothly without JS.
main
has aperspective
to simulate 3D scene.- Children have
transform-style: preserve-3d
to keep 3D layering. .content
has rotated X by -50 grads (a metric angle unit similar to degrees).- Cubes and blocks positioned in 3D space using CSS variables and 3D translate transforms calculated from
--row
,--column
,--layer
multiplied with--cube-size
. - Each cube side (
front
,back
,left
,right
,top
,bottom
) rotated in 3D space to form a cube using rotate transforms. - Filters (
brightness()
) applied to different faces simulates directional lighting—top face brightest, bottom darkest.
- Blocks and block chooser items use hidden radio inputs wrapped inside labels.
- Clicking a label selects a block type or activates some interaction.
- CSS
:checked
states on inputs are used heavily with sibling general or descendant selectors to toggle UI state. - Example: selecting a block type filter hides all cubes except the selected type.
- Block faces use
background-image
pulled from CSS variables defined in:root
. image-rendering: pixelated;
ensures block textures remain crisp and low-res styled.- Different images are applied for different cubes and faces (grass top vs sides, log top vs sides etc).
11. Accessible Close Button with Emoji & Hidden Checkbox
- Close button
.close
uses a pseudo-element::before
to show the × emoji. - The real toggle is a hidden checkbox input.
- Clicking the label toggles the checkbox which triggers
.info:has()
to hide the panel. - This is a creative way to build a close button that works without JavaScript.
- Controls and info blocks have max-widths based on viewport widths (
min(60rem, 100vw - 10rem)
) for good responsiveness. - Controls layout uses
grid-template-columns: repeat(auto-fill, minmax(auto, 1fr))
to adapt buttons or blocks dynamically.
This CSS uses modern CSS features at an expert level to create a 3D interactive voxel-style UI while minimizing or eliminating JavaScript:
- CSS custom properties for configuration and theming.
:has()
pseudo-class for conditional styling and interaction states.- CSS animations triggered by
:active
state and controlled withanimation-play-state
. - 3D transforms and perspective for cube rendering.
- Pixelated background images producing Minecraft-like textures.
- Smart use of hidden radio inputs for UI state control.
- Backdrop blur, responsive design, and accessibility tricks with input/label controls.
The result is a responsive, interactive 3D block builder fully implemented in CSS.
Feel free to ask if you want a detailed explanation of any particular part!
3,813 input, 1,291 output