Skip to content

Commit 3b99bd8

Browse files
committed
Use intersection observer to animate images
1 parent 5907e35 commit 3b99bd8

File tree

4 files changed

+244
-0
lines changed

4 files changed

+244
-0
lines changed

intersection-observer/app.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const section = document.querySelector("#my-work");
2+
const observer = new IntersectionObserver((entries) => {
3+
if (entries[0].isIntersecting) {
4+
entries[0].target.classList.add("show");
5+
} else {
6+
entries[0].target.classList.remove("show");
7+
}
8+
}, {threshold: 0.5});
9+
10+
observer.observe(section);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Bento Grid CSS Explanation
2+
3+
## What is a Bento Grid?
4+
5+
A bento grid is a visually interesting layout where grid items have different sizes and positions, similar to compartments in a bento box. This is often achieved using CSS Grid's `grid-template-areas` property.
6+
7+
## How `grid-template-areas` Works
8+
9+
The `grid-template-areas` property lets you define named areas in your grid, making it easy to visually map out complex layouts.
10+
11+
### Example from styles.css
12+
13+
```css
14+
.grid-container {
15+
display: grid;
16+
grid-template-columns: repeat(4, 1fr);
17+
grid-template-rows: repeat(3, 120px);
18+
grid-gap: 1rem;
19+
grid-template-areas:
20+
"img-1 img-1 img-2 img-3"
21+
"img-4 img-5 img-2 img-3"
22+
"img-4 img-6 img-6 img-3";
23+
}
24+
```
25+
26+
- Each string represents a row in the grid.
27+
- Each word (e.g., `img-1`, `img-2`) is a named area.
28+
- Repeating a name makes that area span multiple cells.
29+
- The layout above creates a dynamic, bento-style arrangement for six images.
30+
31+
### Assigning Areas to Elements
32+
33+
Each image is assigned to a grid area using the `grid-area` property:
34+
35+
```css
36+
.grid-container img[style*="img-1"] {
37+
grid-area: img-1;
38+
}
39+
.grid-container img[style*="img-2"] {
40+
grid-area: img-2;
41+
}
42+
// ...etc.
43+
```
44+
45+
This approach makes it easy to:
46+
47+
- Visually design complex layouts
48+
- Rearrange items by changing the area names
49+
- Create responsive and unique grid designs
50+
51+
---
52+
53+
**Tip:** You can experiment with the area names and grid structure to create your own bento layouts!

intersection-observer/index.html

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Document</title>
7+
<link rel="stylesheet" href="styles.css" />
8+
</head>
9+
<body>
10+
<section class="hero">
11+
<div class="hero-stack">
12+
<img class="hero-img" src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=1200&q=80" alt="Hero Art">
13+
<h1 class="hero-title">Let's bring art to your life</h1>
14+
</div>
15+
</section>
16+
<section id="my-work">
17+
<h2>Some of my best pictures</h2>
18+
<div class="grid-container">
19+
<img
20+
style="grid-area: img-2"
21+
src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80"
22+
alt="pic2"
23+
/>
24+
<img
25+
style="grid-area: img-3"
26+
src="https://images.unsplash.com/photo-1465101046530-73398c7f28ca?auto=format&fit=crop&w=400&q=80"
27+
alt="pic3"
28+
/>
29+
<img
30+
style="grid-area: img-4"
31+
src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=400&q=80"
32+
alt="pic4"
33+
/>
34+
<img
35+
style="grid-area: img-5"
36+
src="https://images.unsplash.com/photo-1465101178521-c1a9136a3b99?auto=format&fit=crop&w=400&q=80"
37+
alt="pic5"
38+
/>
39+
<img
40+
style="grid-area: img-5"
41+
src="https://images.unsplash.com/photo-1502082553048-f009c37129b9?auto=format&fit=crop&w=400&q=80"
42+
alt="pic5"
43+
/>
44+
<img
45+
style="grid-area: img-6"
46+
src="https://images.unsplash.com/photo-1519125323398-675f0ddb6308?auto=format&fit=crop&w=400&q=80"
47+
alt="pic6"
48+
/>
49+
<img
50+
style="grid-area: img-1"
51+
src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=400&q=80"
52+
alt="pic1"
53+
/>
54+
</div>
55+
<a href="#" class="cta-button">See more</a>
56+
</section>
57+
</body>
58+
<script src="app.js"></script>
59+
</html>

intersection-observer/styles.css

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
.hero {
2+
width: 100%;
3+
height: 100vh;
4+
display: flex;
5+
flex-direction: column;
6+
align-items: center;
7+
justify-content: center;
8+
padding: 2rem 0 1rem 0;
9+
background: #f7f7f7;
10+
}
11+
12+
.hero-stack {
13+
display: grid;
14+
place-items: center;
15+
position: relative;
16+
width: 100%;
17+
height: 60vh;
18+
min-height: 320px;
19+
overflow: hidden;
20+
}
21+
22+
.hero-img {
23+
grid-area: 1 / 1;
24+
width: 100%;
25+
height: 100%;
26+
object-fit: cover;
27+
filter: brightness(0.7);
28+
border-radius: 16px;
29+
margin-bottom: 1.5rem;
30+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
31+
}
32+
33+
.hero-title {
34+
grid-area: 1 / 1;
35+
color: #fff;
36+
font-size: 2.5rem;
37+
font-weight: 700;
38+
text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
39+
z-index: 1;
40+
text-align: center;
41+
}
42+
43+
#my-work {
44+
padding: 3rem 0;
45+
background: #fff;
46+
text-align: center;
47+
}
48+
49+
#my-work h2 {
50+
font-size: 2rem;
51+
margin-bottom: 2rem;
52+
}
53+
54+
.grid-container {
55+
display: grid;
56+
grid-template-columns: repeat(4, 1fr);
57+
grid-template-rows: repeat(3, 120px);
58+
grid-gap: 1rem;
59+
grid-template-areas:
60+
"img-1 img-1 img-2 img-3"
61+
"img-4 img-5 img-2 img-3"
62+
"img-4 img-6 img-6 img-3";
63+
margin-bottom: 2rem;
64+
}
65+
66+
.grid-container img[style*="img-1"] {
67+
grid-area: img-1;
68+
height: 100%;
69+
}
70+
.grid-container img[style*="img-2"] {
71+
grid-area: img-2;
72+
height: 100%;
73+
}
74+
.grid-container img[style*="img-3"] {
75+
grid-area: img-3;
76+
height: 100%;
77+
}
78+
.grid-container img[style*="img-4"] {
79+
grid-area: img-4;
80+
height: 100%;
81+
}
82+
.grid-container img[style*="img-5"] {
83+
grid-area: img-5;
84+
height: 100%;
85+
}
86+
.grid-container img[style*="img-6"] {
87+
grid-area: img-6;
88+
height: 100%;
89+
}
90+
91+
.grid-container img {
92+
width: 100%;
93+
object-fit: cover;
94+
border-radius: 12px;
95+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
96+
display: block;
97+
}
98+
99+
.cta-button {
100+
display: inline-block;
101+
padding: 0.75rem 2rem;
102+
background: #007bff;
103+
color: #fff;
104+
border-radius: 25px;
105+
text-decoration: none;
106+
font-weight: bold;
107+
transition: background 0.2s;
108+
}
109+
.cta-button:hover {
110+
background: #0056b3;
111+
}
112+
113+
#my-work img {
114+
translate: -100vw; /* Move image fully to the left */
115+
opacity: 0; /* Hide image */
116+
transition: translate 2000ms cubic-bezier(0.4,0,0.2,1), opacity 800ms cubic-bezier(0.4,0,0.2,1);
117+
}
118+
119+
#my-work.show img {
120+
translate: 0;
121+
opacity: 1;
122+
}

0 commit comments

Comments
 (0)