본문 바로가기

CSS 기반 스크롤 애니메이션 반응형 웹페이지 디자인

반응형

순수 CSS 기반 스크롤  애니메이션 반응형 웹페이지  디자인 입니다.

소스를 적절히 수정하시면 멋진 웹페이지를 구성할수 있습니다.

:root {
--text-color: hsl(230 16% 28%);
/* header */
--header-bg: hsl(0 0% 100% / 75%);
/* section */
--section: hsl(0 0% 93%);
--section-even: hsl(210deg 15% 92%);
/* tiles */
--red: hsl(10 83% 52%);
--green: hsl(157 91% 43%);
--blue: hsl(210 100% 45%);
--purple: hsl(266 100% 67%);
--yellow: hsl(49 100% 73%);
--black: hsl(0 0% 0%);
--cubic: cubic-bezier(0.25, 0.1, 0, 2.05);
}
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
display: grid;
overflow-x: hidden;
font-family: "Righteous", sans-serif;
/* scope */
timeline-scope: 
--masthead-s, 
--tiles-s, 
--text-s, 
--two-columns-s,
--subscribe-s;
}
header {
--show: none;
--position: relative;
--b: 0;
--s: 10%;
--nav-bg: var(--yellow);
position: sticky;
top: 0;
z-index: 2;
inline-size: 100%;
transition: all 200ms linear;
/* animation */
animation: height-resize both linear;
animation-timeline: scroll();
animation-range: entry 0% exit 20%;
.menu {
position: fixed;
top: 0.25rem;
left: 0.25rem;
z-index: 2;
cursor: pointer;
& input[type="checkbox"] {
display: none;
}
.burger {
display: var(--show);
background-color: var(--header-bg);
& path {
fill: none;
stroke: currentcolor;
stroke-width: 3;
transition: stroke-dasharray 400ms, stroke-dashoffset 400ms;
&.top {
stroke-dasharray: 40 172;
}
&.middle {
stroke-dasharray: 40 111;
}
&.bottom {
stroke-dasharray: 40 172;
}
}
}
&:has(input[type="checkbox"]:checked) {
.burger {
& path {
&.top {
stroke-dashoffset: -132px;
}
&.middle {
stroke-dashoffset: -71px;
}
&.bottom {
stroke-dashoffset: -132px;
}
}
}
}
}
& nav {
position: var(--position);
inline-size: inherit;
display: flex;
align-items: center;
justify-content: center;
/* blur background */
background-color: var(--header-bg);
backdrop-filter: blur(6px);
& ul {
list-style-type: none;
display: flex;
padding: 0;
grid-column-gap: 3rem;
& li {
position: relative;
padding: 0.5rem 1rem;
text-transform: uppercase;
color: var(--text-color);
transition: transform 0.25s var(--cubic);
&::after {
position: absolute;
content: "";
left: 0;
bottom: var(--b);
z-index: -1;
inline-size: 100%;
block-size: var(--s);
background-color: var(--nav-bg);
transition: all 0.25s var(--cubic);
}
&:has(a:hover) {
--b: 10%;
--s: 70%;
}
}
}
}
}

@media (width <= 48rem) {
body {
&:has(input[id="burger"]:checked) {
scrollbar-gutter: stable;
overflow-y: hidden;
}
}
header {
--position: absolute;
--translateY: -100%;
--show: block;
--nav-bg: var(--green);
& nav {
top: 0;
translate: 0 var(--translateY);

inline-size: 100%;
block-size: 100dvh;
padding-inline: 1rem;
transition: all 200ms ease-in-out;
& ul {
block-size: 100%;
flex-direction: column;
justify-content: space-evenly;
}
}
& .menu {
&:has(input[type="checkbox"]:checked) {
& ~ nav {
--translateY: 0;
}
}
}
}
}
@keyframes height-resize {
to {
padding-block: 0;
}
}

:is(h1, h2) {
margin: 0;
font-size: calc(2rem + 0.25vw);
}
a {
text-decoration: none;
color: currentColor;
/* animation */
animation: avtive-link both linear;
anchor-name: var(--an);
animation-timeline: var(--at);
&:not(:hover) {
opacity: calc(0.5 + var(--active, 0));
}
}
section {
min-block-size: 100vh;
background-color: var(--section);
/* for animation */
view-timeline-name: var(--name);
&:nth-child(even) {
--section: var(--section-even);
}
}
.flying-squares {
position: absolute;
z-index: 1;
.square {
position: inherit;
width: 15vw;
height: 15vw;
rotate: 0.4turn;
background-color: var(--square-color);
top: var(--y);
left: var(--x);
opacity: 0.3;
rotate: var(--rx) var(--ry) var(--rz) 0.55turn;
animation: flying 2s infinite alternate both;
&:nth-of-type(1) {
--y: 17vh;
--x: 8vw;
--rx: 0.5;
--ry: 2.1;
--rz: 1.6;
--square-color: var(--red);
animation-delay: 1s;
}
&:nth-of-type(2) {
--y: 8vh;
--x: 76vw;
--rx: 1.7;
--ry: 2.3;
--rz: 2.1;
--square-color: var(--purple);
}
&:nth-of-type(3) {
--y: 60vh;
--x: 40vw;
--rx: 1.75;
--ry: 3.5;
--rz: 2.7;
--square-color: var(--green);
animation-delay: 0.5s;
}
}
}
@keyframes flying {
to {
translate: 0 -5vh;
}
}
.masthead {
max-inline-size: 100vw;
block-size: 100vh;
overflow: hidden;
display: grid;
place-content: center;
padding-inline: 1rem;
& h1 {
position: fixed;
top: 50%;
left: 50%;
translate: -50% -50%;
text-transform: uppercase;
/* animation */
animation: scale-up both linear, fade-away both linear;
animation-timeline: var(--name);
animation-range: entry-crossing 70% exit 90%, exit 10% exit 70%;
}
}
@keyframes scale-up {
100% {
top: 0;
scale: 5;
}
}
@keyframes fade-away {
100% {
opacity: 0;
}
}
.tile-section {
position: sticky;
top: 0;
max-inline-size: 100vw;
block-size: 200vh;
overflow: hidden;
& .tile-container {
position: absolute;
top: 50%;
left: 50%;
translate: -50% -50%;
scale: 3;
inline-size: 100%;
block-size: 100vh;
display: grid;
grid-template: repeat(4, 1fr) / repeat(5, 1fr);
rotate: 0.12turn;
& .tile {
inline-size: 100%;
block-size: 100%;
background-color: var(--tile);
/* animation */
animation: tile both linear;
/* animation-timeline: scroll(root); */
animation-timeline: var(--name);
animation-range: entry 100% exit 0%;
&:nth-of-type(5n + 2),
&:nth-of-type(5n + 4) {
--tile: var(--green);
--vertical: 100%;
--horizontal: 100%;
&:nth-of-type(odd) {
--tile: var(--red);
--vertical: 100%;
--horizontal: -100%;
}
}
&:nth-of-type(5n + 1),
&:nth-of-type(5n + 3),
&:nth-of-type(5n + 5) {
--tile: var(--blue);
--vertical: -100%;
--horizontal: 100%;
&:not(:nth-of-type(odd)) {
--tile: var(--yellow);
--vertical: -100%;
--horizontal: -100%;
}
}
}
}
}
@keyframes tile {
0% {
translate: 0 0;
}
50% {
translate: 0 var(--vertical);
}
100% {
translate: var(--horizontal) var(--vertical);
}
}
.text {
max-inline-size: 80ch;
margin-inline: auto;
padding: 3rem 1rem;
counter-reset: chapter 0;
& > *:not(h2) {
text-wrap: pretty;
counter-increment: chapter 1;
/* animation */
animation: show-text both linear;
animation-timeline: view(y 80vh auto);
&::before {
content: counter(chapter, upper-roman) ". "; /* lower-alpha */
}
}
}
@keyframes show-text {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.read {
position: fixed;
top: 68px;
left: 0;
z-index: 3;
inline-size: 0;
max-inline-size: 100%;
text-align: right;
white-space: nowrap;
padding-block: 0.125rem;
padding-inline-end: 0.5rem;
background-image: linear-gradient(
0.25turn,
var(--red),
var(--yellow),
var(--green),
var(--blue),
var(--purple)
);
opacity: 0;
transition: opacity 200ms linear;
/* animation */
animation: read-text both linear;
animation-timeline: var(--name);
animation-range: entry 100% exit 100%;
& div {
filter: invert(100%);
}
}
@keyframes read-text {
1% {
opacity: 1;
}
99% {
inline-size: 100%;
opacity: 1;
}
100% {
opacity: 0;
}
}
.two-columns {
--columns: 1;
--translateX: 0;
max-inline-size: 80ch;
margin-inline: auto;
block-size: 100%;
padding: 3rem 1rem;
.content {
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
place-content: center;
gap: 2rem;
.cards {
margin-block-start: 2rem;
display: flex;
flex-direction: column;
justify-content: space-between;
.card {
box-shadow: inset 0 0 0.125rem var(--text-color);
/* animation */
animation: show both linear;
animation-timeline: var(--name);
animation-range: entry-crossing var(--range-start);
&:nth-of-type(1) {
--range-start: 10%;
}
&:nth-of-type(2) {
--range-start: 40%;
}
&:nth-of-type(3) {
--range-start: 70%;
}
&:not(:last-of-type) {
margin-block-end: 2rem;
}
& * {
margin: 0;
padding-inline: 1rem;
}
.title {
padding-block-start: 1rem;
}
.subtitle {
padding-block-start: 0.25rem;
padding-block-end: 1rem;
opacity: 0.5;
}
& p {
padding-block-end: 1rem;
}
}
}
}
.preview {
position: relative;
margin-block: 2rem;
block-size: calc(100% - 1rem);
.img {
left: var(--translateX);
block-size: inherit;
min-block-size: 24rem;
object-fit: cover;
background: var(--red);
}
}
}
@media (width >= 48rem) {
.two-columns {
--columns: 2;
--translateX: 150%;
.preview {
.img {
position: absolute;
top: 0;
aspect-ratio: 0.5;
/* animation */
animation: fade-right both linear;
animation-timeline: scroll(root);
animation-range: entry 5% exit 90%;
}
}
}
}
@keyframes fade-right {
to {
left: 0;
}
}
@keyframes show {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.subscribe {
max-inline-size: 80ch;
margin-inline: auto;
block-size: 100vh;
padding: 3rem 1rem;
display: grid;
place-content: center;
text-align: center;
& form {
position: relative;
margin-block-start: 2rem;
/* animation */
animation: slide-up both linear;
animation-timeline: var(--name);
animation-range: entry-crossing 40%;
& input {
inline-size: 100%;
border: 0;
min-block-size: 3rem;
margin-block-end: 1rem;
padding-inline: 0.5rem;
font-size: calc(1rem + 0.25vw);
box-shadow: 0 0 0.125rem var(--text-color);
&:focus {
outline: thin solid var(--purple);
}
}
& button {
padding: 0.75rem 1rem;
text-transform: uppercase;
cursor: pointer;
background-color: var(--purple);
border: 0;
&:focus {
outline: thin solid var(--purple);
}
& span {
font-weight: 700;
filter: invert(100%);
}
}
}
}
@keyframes slide-up {
from {
scale: 0;
}
to {
scale: 1;
}
}
.scroll {
position: fixed;
top: 50%;
left: 0.35rem;
translate: 0 -50%;
writing-mode: vertical-lr;
rotate: 0.5turn;
display: flex;
align-items: center;
gap: 0.5rem;
opacity: 0.5;
& .divider {
inline-size: 2rem;
block-size: 2px;
background-color: currentColor;
opacity: 0.5;
}
& span {
text-transform: lowercase;
font-weight: bold;
}
}
@keyframes avtive-link {
50% {
--active: 1;
}
}
footer {
display: grid;
place-content: center;
padding-block: 1rem;
& a {
--active: 1;
padding: 0.5rem 1rem;
background-color: var(--black);
& span {
filter: invert(75%);
}
}
}
<header>
 <label class="menu" for="burger">
 <input id="burger" type="checkbox"/>
 <svg class="burger" viewBox="0 0 100 100" width="64">
 <path class="line top" d="m 30,33 h 40 c 13.100415,0 14.380204,31.80258 6.899646,33.421777 -24.612039,5.327373 9.016154,-52.337577 -12.75751,-30.563913 l -28.284272,28.284272"></path>
 <path class="line middle" d="m 70,50 c 0,0 -32.213436,0 -40,0 -7.786564,0 -6.428571,-4.640244 -6.428571,-8.571429 0,-5.895471 6.073743,-11.783399 12.286435,-5.570707 6.212692,6.212692 28.284272,28.284272 28.284272,28.284272"></path>
 <path class="line bottom" d="m 69.575405,67.073826 h -40 c -13.100415,0 -14.380204,-31.80258 -6.899646,-33.421777 24.612039,-5.327373 -9.016154,52.337577 12.75751,30.563913 l 28.284272,-28.284272"></path>
 </svg>
 </label>
 <nav>
 <ul>
 <li><a href="#masthead" title="masthead" style="--an:--masthead;--at:--masthead-s;">masthead</a></li>
 <li><a href="#tiles" title="tiles" style="--an:--tiles;--at:--tiles-s;">tiles</a></li>
 <li><a href="#text" title="text" style="--an:--text;--at:--text-s;">text</a></li>
 <li><a href="#two-columns" title="two-columns" style="--an:--two-columns;--at:--two-columns-s;">two-columns</a></li>
 <li><a href="#subscribe" title="subscribe" style="--an:--subscribe;--at:--subscribe-s;">subscribe</a></li>
 </ul>
 </nav>
</header>
<main>
 <section id="masthead" style="--name:--masthead-s;">
 <div class="flying-squares">
 <div class="square"></div>
 <div class="square"></div>
 <div class="square"></div>
 </div>
 <div class="masthead">
 <h1>masthead</h1>
 <p>Press on the heart if you are also a CSS Developer</p>
 </div>
 </section>
 <section id="tiles" style="--name:--tiles-s;">
 <div class="tile-section">
 <div class="tile-container">
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 <div class="tile"></div>
 </div>
 </div>
 </section>
 <section id="text" style="--name:--text-s;">
 <div class="read">
 <div>Reading progress</div>
 </div>
 <div class="text">
 <h2>Smooth appearance of text when scrolling</h2>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 </div>
 </section>
 <section id="two-columns" style="--name:--two-columns-s;">
 <div class="two-columns">
 <h2>Picture arrived on the right</h2>
 <div class="content">
 <div class="cards">
 <div class="card">
 <h3 class="title">Card title</h3>
 <div class="subtitle">Subtitle</div>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 </div>
 <div class="card">
 <h3 class="title">Card title</h3>
 <div class="subtitle">Subtitle</div>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 </div>
 <div class="card">
 <h3 class="title">Card title</h3>
 <div class="subtitle">Subtitle</div>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 </div>
 </div>
 <div class="preview">
 <div class="img"></div>
 </div>
 </div>
 </div>
 </section>
 <section id="subscribe" style="--name:--subscribe-s;">
 <div class="subscribe">
 <h2>Subscribe now</h2>
 <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Culpa, tenetur deserunt! Obcaecati eius aut, facere porro amet atque laborum eos, numquam asperiores minus accusantium et tempore repellat voluptatum natus corrupti?</p>
 <form action="" method="POST">
 <input type="email" placeholder="Enter your email"/>
 <button class="btn" type="submit"><span>Subscribe</span></button>
 </form>
 </div>
 </section>
 <div class="scroll"><span>scroll</span>
 <div class="divider"></div><span>down</span>
 </div>
</main>
반응형

댓글


Copyright ⓒ SmartWeb All rights reserved.