09Ô nhập liệu kính
Khi ô nhập chất liệu kính nhận được focus, quầng sáng viền sáng lên trong khi nhãn phía trên nổi lên chút ít bằng translateY rồi vào đúng vị trí.
Dùng choForm đăng nhập, ô đăng ký nhận bản tin
box-shadowtranslateY220ms

<main class="stage">
<div class="gi-field is-demo">
<input class="gi-field__input gi-focal" type="email" placeholder=" ">
<label class="gi-field__label">Email address</label>
</div>
</main>@use "../../../../site/static/demo-tokens" as *;
// ── 변수 3개 ──────────────────────────────────────────
$duration: $dur-quick;
$easing: $ease-out;
$color: $subject-blue;
@include stage($stage-ink);
.gi-field {
position: relative;
width: min(240px, 84vw);
}
.gi-field__input {
width: 100%;
box-sizing: border-box;
padding: $sp-5 $sp-4 $sp-2;
border-radius: $r-control;
background: rgba(255, 255, 255, .12);
border: 1px solid rgba(255, 255, 255, .3);
backdrop-filter: blur(14px) saturate(160%);
-webkit-backdrop-filter: blur(14px) saturate(160%);
box-shadow: $shadow-press;
color: $subject-cream;
font: 600 13px/1 -apple-system, "Segoe UI", sans-serif;
outline: none;
transition: border-color $duration $easing, box-shadow $duration $easing;
}
.gi-field__input::placeholder { color: transparent; }
// top·left 는 고정, 뜨는 움직임은 transform 만
.gi-field__label {
position: absolute;
left: $sp-4;
top: 50%;
transform: translateY(-50%) scale(1);
transform-origin: left center; // 규칙8: 좌측 패딩 붙은 라벨 뜸
color: rgba($subject-cream, .6);
font: 600 13px/1 -apple-system, "Segoe UI", sans-serif;
pointer-events: none;
transition: transform $duration $easing, color $duration $easing;
}
// 실사용: 진짜 포커스로 라벨이 뜨고 테두리 빛이 밝아진다
.gi-field:focus-within .gi-field__label { transform: translateY(-14px) scale(.82); color: $subject-cream; }
.gi-field:focus-within .gi-focal { border-color: rgba($color, .9); box-shadow: 0 0 0 3px rgba($color, .35), $shadow-raised; }
// 데모 루프: is-demo 는 같은 상태를 keyframes 로 반복 (헤드리스는 :focus-within 을 못 건다, .focus() 는 안 쓴다 — BD18)
@keyframes gi-label-loop {
0%, 20% { transform: translateY(-50%) scale(1); color: rgba($subject-cream, .6); }
50%, 70% { transform: translateY(-14px) scale(.82); color: $subject-cream; }
100% { transform: translateY(-50%) scale(1); color: rgba($subject-cream, .6); }
}
@keyframes gi-input-loop {
0%, 20% { border-color: rgba(255, 255, 255, .3); box-shadow: $shadow-press; }
50%, 70% { border-color: rgba($color, .9); box-shadow: 0 0 0 3px rgba($color, .35), $shadow-raised; }
100% { border-color: rgba(255, 255, 255, .3); box-shadow: $shadow-press; }
}
.gi-field.is-demo .gi-field__label { animation: gi-label-loop $dur-loop $easing infinite; }
.gi-field.is-demo .gi-focal { animation: gi-input-loop $dur-loop $easing infinite; }
@media (prefers-reduced-motion: reduce) {
.gi-field__label, .gi-focal { transition: none; }
.gi-field.is-demo .gi-field__label,
.gi-field.is-demo .gi-focal { animation: none !important; }
}html, body {
margin: 0;
overflow: hidden;
}
.stage {
box-sizing: border-box;
min-height: 100vh;
display: grid;
place-items: center;
margin: 0;
background: #17141a;
font-family: -apple-system, "Segoe UI", "Noto Sans KR", sans-serif;
padding: clamp(8px, 4vw, 24px);
}
.gi-field {
position: relative;
width: min(240px, 84vw);
}
.gi-field__input {
width: 100%;
box-sizing: border-box;
padding: 20px 16px 8px;
border-radius: 12px;
background: rgba(255, 255, 255, 0.12);
border: 1px solid rgba(255, 255, 255, 0.3);
backdrop-filter: blur(14px) saturate(160%);
-webkit-backdrop-filter: blur(14px) saturate(160%);
box-shadow: 0 6px 12px rgba(23, 20, 26, 0.32);
color: #fff7e6;
font: 600 13px/1 -apple-system, "Segoe UI", sans-serif;
outline: none;
transition: border-color 220ms ease-out, box-shadow 220ms ease-out;
}
.gi-field__input::placeholder {
color: transparent;
}
.gi-field__label {
position: absolute;
left: 16px;
top: 50%;
transform: translateY(-50%) scale(1);
transform-origin: left center;
color: rgba(255, 247, 230, 0.6);
font: 600 13px/1 -apple-system, "Segoe UI", sans-serif;
pointer-events: none;
transition: transform 220ms ease-out, color 220ms ease-out;
}
.gi-field:focus-within .gi-field__label {
transform: translateY(-14px) scale(0.82);
color: #fff7e6;
}
.gi-field:focus-within .gi-focal {
border-color: rgba(47, 109, 246, 0.9);
box-shadow: 0 0 0 3px rgba(47, 109, 246, 0.35), 0 14px 24px rgba(23, 20, 26, 0.32);
}
@keyframes gi-label-loop {
0%, 20% {
transform: translateY(-50%) scale(1);
color: rgba(255, 247, 230, 0.6);
}
50%, 70% {
transform: translateY(-14px) scale(0.82);
color: #fff7e6;
}
100% {
transform: translateY(-50%) scale(1);
color: rgba(255, 247, 230, 0.6);
}
}
@keyframes gi-input-loop {
0%, 20% {
border-color: rgba(255, 255, 255, 0.3);
box-shadow: 0 6px 12px rgba(23, 20, 26, 0.32);
}
50%, 70% {
border-color: rgba(47, 109, 246, 0.9);
box-shadow: 0 0 0 3px rgba(47, 109, 246, 0.35), 0 14px 24px rgba(23, 20, 26, 0.32);
}
100% {
border-color: rgba(255, 255, 255, 0.3);
box-shadow: 0 6px 12px rgba(23, 20, 26, 0.32);
}
}
.gi-field.is-demo .gi-field__label {
animation: gi-label-loop 2s ease-out infinite;
}
.gi-field.is-demo .gi-focal {
animation: gi-input-loop 2s ease-out infinite;
}
@media (prefers-reduced-motion: reduce) {
.gi-field__label, .gi-focal {
transition: none;
}
.gi-field.is-demo .gi-field__label,
.gi-field.is-demo .gi-focal {
animation: none !important;
}
}import { CSSProperties } from "react";
import styles from "./GlassInput.module.scss";
type Vars = CSSProperties & {
"--duration"?: string;
"--easing"?: string;
"--color"?: string;
};
export interface GlassInputProps {
duration?: string;
easing?: string;
color?: string;
}
export default function GlassInput({
duration = "220ms",
easing = "ease-out",
color = "#2f6df6",
}: GlassInputProps) {
const style: Vars = { "--duration": duration, "--easing": easing, "--color": color };
return (
<div className={styles.field} style={style}>
<input id="gi-email" className={styles.input} type="email" placeholder=" " />
<label className={styles.label} htmlFor="gi-email">Email address</label>
</div>
);
}09 Ô nhập liệu kính — Diện tích đo được 2.953% · khung hình chuyển động 15/23Nguyên tác GODRICH · SCSS và React nằm trong tệp zip · 9 css glassmorphism — dán một file là chạy
Bài viết chứa demo này
9 css glassmorphism — dán một file là chạyGlassmorphism là đặt một tấm kính mờ lên màn hình: nền phía sau hiện lên mờ mềm còn chữ phía trên vẫn rõ nét. Chín hiệu Xem tất cả demo trong bài này


