WEBLEB
Inicio
Editora de código
Iniciar sesión
Pro
Español
English
Français
Español
Português
Deutsch
Italiano
हिंदी
Reloj de neón
2220
Andev.web
Abrir en el editor
Publica tu código
Recomendado
30 November 2025
Formulario de inicio de sesión HTML: nombre de usuario/correo electrónico y contraseña
11 September 2025
Plantilla de sitio web HTML de Starbucks
1 June 2024
Animación de botones sin CSS
HTML
Copy
Andev Web
CSS
Copy
html { font-size: 0.75vmin; } body { background-image: linear-gradient(to bottom, #131313, #000); perspective: 45rem; transform-style: preserve-3d; } .wrapper { -webkit-animation: camera-rotate 40s ease-in-out forwards infinite; animation: camera-rotate 40s ease-in-out forwards infinite; width: 100%; height: 100%; transform-style: preserve-3d; } main { --s: 100%; --l: 50%; display: flex; color: hsl(0deg, var(--s), var(--l)); gap: 1rem; width: 100%; height: 100%; position: relative; align-items: center; justify-content: center; animation-composition: add; -webkit-animation: camera-pan 30s linear forwards infinite; animation: camera-pan 30s linear forwards infinite; translate: 0rem 1rem 10rem; transform-style: preserve-3d; } main .digits { transform-style: preserve-3d; } main .digits .group { display: flex; gap: 2rem; } main .digits .group .digit { position: relative; height: 16rem; aspect-ratio: 1/2; filter: drop-shadow(0px 0px 4px currentColor) drop-shadow(0px 0px 10px currentColor); } main .digits .group .digit span { --act: 0; --signX: 1; --signY: 1; position: absolute; background-color: white; transition: all 0.3s cubic-bezier(0.17, 0.67, 0.5, 1.15); opacity: calc(0.03 + 0.97 * var(--act)); animation-composition: add; transform: scale(var(--signX), var(--signY)); } main .digits .group .digit span.end { -webkit-clip-path: polygon(15% 0%, 7.5% 20%, 25% 100%, 75% 100%, 92.5% 20%, 85% 0%); clip-path: polygon(15% 0%, 7.5% 20%, 25% 100%, 75% 100%, 92.5% 20%, 85% 0%); width: 100%; height: 10%; } main .digits .group .digit span.end.top { top: 0; } main .digits .group .digit span.end.bottom { top: initial; bottom: 0; --signY: -1; } main .digits .group .digit span.side { -webkit-clip-path: polygon(0% 15%, 20% 7.5%, 100% 22.5%, 100% 85%, 20% 95%, 0% 90%); clip-path: polygon(0% 15%, 20% 7.5%, 100% 22.5%, 100% 85%, 20% 95%, 0% 90%); height: 50%; width: 20%; } main .digits .group .digit span.side.left { top: 0; left: 0; } main .digits .group .digit span.side.left.bottom { top: initial; bottom: 0; --signY: -1; } main .digits .group .digit span.side.right { top: 0; left: initial; right: 0; --signX: -1; } main .digits .group .digit span.side.right.bottom { top: initial; --signY: -1; bottom: 0; } main .digits .group .digit span.middle { -webkit-clip-path: polygon(22.5% 0%, 6.5% 50%, 22.5% 100%, 77.5% 100%, 93.5% 50%, 77.5% 0%); clip-path: polygon(22.5% 0%, 6.5% 50%, 22.5% 100%, 77.5% 100%, 93.5% 50%, 77.5% 0%); top: 45%; height: 10%; width: 100%; } main .digits .group .digit[data-digit="0"] :not(.middle) { --act: 1; } main .digits .group .digit[data-digit="1"] .right { --act: 1; } main .digits .group .digit[data-digit="2"] :not(.top.left, .bottom.right) { --act: 1; } main .digits .group .digit[data-digit="3"] :not(.left) { --act: 1; } main .digits .group .digit[data-digit="4"] :not(.end, .bottom.left) { --act: 1; } main .digits .group .digit[data-digit="5"] :not(.top.right, .bottom.left) { --act: 1; } main .digits .group .digit[data-digit="6"] :not(.top.right) { --act: 1; } main .digits .group .digit[data-digit="7"] .top, main .digits .group .digit[data-digit="7"] .right { --act: 1; } main .digits .group .digit[data-digit="8"] > * { --act: 1; } main .digits .group .digit[data-digit="9"] :not(.bottom.left) { --act: 1; } main .colon-group { transform-style: preserve-3d; } main .colon-group .colon span { display: flex; height: 16rem; flex-direction: column; justify-content: space-evenly; width: 4rem; align-items: center; filter: drop-shadow(0px 0px 4px currentColor) drop-shadow(0px 0px 10px currentColor); } main .colon-group .colon span::before, main .colon-group .colon span::after { content: ""; display: block; width: 2rem; aspect-ratio: 1/1; background-color: white; border-radius: 2rem; } main .shadow { top: 0; position: absolute; transform-origin: bottom center; transform: translateY(1rem) translateZ(2rem) rotateX(-90.1deg); } main .shadow .digit span { opacity: var(--act); } main .shadow.shadow1 { opacity: 0.5; filter: drop-shadow(0px 0px 4px currentColor) drop-shadow(0px 0px 10px currentColor) blur(4rem); } main .shadow.shadow1 > span, main .shadow.shadow1 .digit { -webkit-mask-image: linear-gradient(to bottom, white, rgba(0, 0, 0, 0.5)); mask-image: linear-gradient(to bottom, white, rgba(0, 0, 0, 0.5)); } main .shadow.shadow2 { opacity: 0.4; filter: drop-shadow(0px 0px 4px currentColor) drop-shadow(0px 0px 10px currentColor) blur(4px); } main .shadow.shadow2 > span, main .shadow.shadow2 .digit { opacity: var(--act); -webkit-mask-image: linear-gradient(to top, black, rgba(0, 0, 0, 0.1) 60%, rgba(0, 0, 0, 0)); mask-image: linear-gradient(to top, black, rgba(0, 0, 0, 0.1) 60%, rgba(0, 0, 0, 0)); } @-webkit-keyframes camera-rotate { 0% { transform: rotateY(-10deg); } 50% { transform: rotateY(10deg); } 100% { transform: rotateY(-10deg); } } @keyframes camera-rotate { 0% { transform: rotateY(-10deg); } 50% { transform: rotateY(10deg); } 100% { transform: rotateY(-10deg); } } @-webkit-keyframes camera-pan { 0% { transform: translate(0rem, 0rem); } 20% { transform: translate(1rem, 2rem); } 40% { transform: translate(-2rem, 2.5rem); } 50% { transform: translate(-1.5rem, 1.5rem); } 70% { transform: translate(-0.5rem, -0.5rem); } 90% { transform: translate(1.5rem, -1rem); } 100% { transform: translate(0rem, 0rem); } } @keyframes camera-pan { 0% { transform: translate(0rem, 0rem); } 20% { transform: translate(1rem, 2rem); } 40% { transform: translate(-2rem, 2.5rem); } 50% { transform: translate(-1.5rem, 1.5rem); } 70% { transform: translate(-0.5rem, -0.5rem); } 90% { transform: translate(1.5rem, -1rem); } 100% { transform: translate(0rem, 0rem); } } @-webkit-keyframes hue-rotate { 0% { color: hsl(0deg, var(--s), var(--l)); } 8.33% { color: hsl(30deg, var(--s), var(--l)); } 16.67% { color: hsl(60deg, var(--s), var(--l)); } 25% { color: hsl(90deg, var(--s), var(--l)); } 33.33% { color: hsl(120deg, var(--s), var(--l)); } 41.67% { color: hsl(150deg, var(--s), var(--l)); } 50% { color: hsl(180deg, var(--s), var(--l)); } 58.33% { color: hsl(210deg, var(--s), var(--l)); } 66.67% { color: hsl(240deg, var(--s), var(--l)); } 75% { color: hsl(270deg, var(--s), var(--l)); } 83.33% { color: hsl(300deg, var(--s), var(--l)); } 91.67% { color: hsl(330deg, var(--s), var(--l)); } 100% { color: hsl(360deg, var(--s), var(--l)); } } @keyframes hue-rotate { 0% { color: hsl(0deg, var(--s), var(--l)); } 8.33% { color: hsl(30deg, var(--s), var(--l)); } 16.67% { color: hsl(60deg, var(--s), var(--l)); } 25% { color: hsl(90deg, var(--s), var(--l)); } 33.33% { color: hsl(120deg, var(--s), var(--l)); } 41.67% { color: hsl(150deg, var(--s), var(--l)); } 50% { color: hsl(180deg, var(--s), var(--l)); } 58.33% { color: hsl(210deg, var(--s), var(--l)); } 66.67% { color: hsl(240deg, var(--s), var(--l)); } 75% { color: hsl(270deg, var(--s), var(--l)); } 83.33% { color: hsl(300deg, var(--s), var(--l)); } 91.67% { color: hsl(330deg, var(--s), var(--l)); } 100% { color: hsl(360deg, var(--s), var(--l)); } } .safari .digit span { transition: none !important; } .safari .digit span::before { content: ""; position: absolute; display: block; width: 400%; height: 400%; top: 0; left: 0; transform: translate(-50%, -50%); }
JS
Copy
const bars = [ ['end', 'top'], ['side', 'top', 'left'], ['side', 'top', 'right'], ['middle'], ['side', 'bottom', 'left'], ['side', 'bottom', 'right'], ['end', 'bottom'] ]; const $main = document.querySelector('main'); const addDigits = number => { const initGroup = (number, padding = 2) => { const $group = document.createElement('div'); $group.classList.add('group'); const digits = [...`${number}`.padStart(padding, 0)].map(digit => { const $digit = document.createElement('figure'); $digit.classList.add('digit'); $digit.setAttribute('data-digit', digit); bars.forEach(classes => { const $span = document.createElement('span'); $span.classList.add(...classes); $digit.append($span); }); return $digit; }); $group.append(...digits); return { element: $group, set number(val) { number = val; [...`${number}`.padStart(padding, 0).substring(`${number}`.length - 2)].forEach((digit, i) => { digits[i].setAttribute('data-digit', digit); }); }, get number() { return number; } } } const $digits = document.createElement('div'); $digits.classList.add('digits'); const group = initGroup(number); const groupShadow1 = initGroup(number); const groupShadow2 = initGroup(number); groupShadow1.element.classList.add('shadow'); groupShadow1.element.classList.add('shadow1'); groupShadow2.element.classList.add('shadow'); groupShadow2.element.classList.add('shadow2'); $digits.append(group.element); $digits.append(groupShadow1.element); $digits.append(groupShadow2.element); $main.append($digits); return { set number(val) { number = val; group.number = val; groupShadow1.number = val; groupShadow2.number = val; }, get number() { return number; } } } const addColon = () => { const $colonGroup = document.createElement('div'); $colonGroup.classList.add('colon-group'); const $colon = document.createElement('figure'); $colon.append(document.createElement('span')); const $colonShadow1 = document.createElement('figure'); $colonShadow1.append(document.createElement('span')); const $colonShadow2 = document.createElement('figure'); $colonShadow2.append(document.createElement('span')); $colon.classList.add('colon'); $colonShadow1.classList.add('colon', 'shadow', 'shadow1'); $colonShadow2.classList.add('colon', 'shadow', 'shadow2'); $colonGroup.append($colon); $colonGroup.append($colonShadow1); $colonGroup.append($colonShadow2); $main.append($colonGroup); } const init = () => { let now = new Date(); let hours = now.getHours(); let minutes = now.getMinutes(); let seconds = now.getSeconds(); const numberHour = addDigits(hours); addColon(); const numberMinute = addDigits(minutes); addColon(); const numberSecond = addDigits(seconds); const update = () => { now = new Date(); let newSeconds = now.getSeconds(); if (seconds !== newSeconds) { hours = now.getHours(); minutes = now.getMinutes(); seconds = newSeconds; numberHour.number = hours; numberMinute.number = minutes; numberSecond.number = seconds; } requestAnimationFrame(update); } update(); } if (/^(?:(?!chrome|android)[\s\S])*(?:safari|iPad|iPhone|iPod)/i.test(navigator.userAgent)) { document.body.classList.add('safari'); } init();