こんにちは。KOUKIです。
本記事は、Udemyの「50 Projects In 50 Days – HTML, CSS & JavaScript」で学習したことを載せています。
実装するもの
今回は、「いいね機能」をcssでスタイリングしたいと思います。
demoは「こちら」で確認できます。
ワークスペース
必要なファイルは、以下の通りです。
1 2 3 4 5 6 |
$ tree . ├── index.html ├── script.js └── style.css |
JavaScript版
HTML & JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" /> <link rel="stylesheet" href="style.css" /> <title>Double Click Heart</title> </head> <body> <h3>Double click on the image to <i class="fas fa-heart"></i> it</h3> <small>You liked it <span id="times">0</span> times</small> <div class="loveMe"></div> <script src="script.js"></script> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
// 要素の取得 const loveMe = document.querySelector('.loveMe') const times = document.querySelector('#times') // クリック時間の制御 let clickTime = 0 // いいね数をカウント let timesClicked = 0 // クリックイベントの登録 loveMe.addEventListener('click', (e) => { if(clickTime === 0) { clickTime = new Date().getTime() // UNIX TIMEでデータを取得できる } else { if((new Date().getTime() - clickTime) < 800) { createHeart(e) clickTime = 0 // 初期化 } else { clickTime = new Date().getTime() } } }) // ハートの作成 const createHeart = (e) => { // https://fontawesome.com/ const heart = document.createElement('i') heart.classList.add('fas') heart.classList.add('fa-heart') const {xInside, yInside} = culcPosition(e) // ハートの位置を指定 // スタイルの.loveMe .fa-heart {}にてposition: absolute;を // 指定しているため、位置を制御できる heart.style.top = `${yInside}px` heart.style.left = `${xInside}px` // 子要素として追加 loveMe.appendChild(heart) // いいね数を増加して挿入 times.innerHTML = ++timesClicked // クリックするとハート要素が無限に増えていくため、5秒後に削除 setTimeout(() => heart.remove(), 5000) } // 要素を出す位置を計算 function culcPosition(e) { // クリックした位置を取得 const x = e.clientX const y = e.clientY // ページからみて画像の位置を取得 const leftOffset = e.target.offsetLeft const topOffset = e.target.offsetTop // ハートを出す位置を制御 // 画像の位置とクリック位置から計算 const xInside = x - leftOffset const yInside = y - topOffset return {xInside, yInside} } |

スタイリング
これからCSSでスタイリングをしていきます。項目のbodyやh3はHTML要素です。
全体の設定
1 2 3 4 5 6 7 |
@import url("https://fonts.googleapis.com/css?family=Oswald"); * { /* ボックスの大きさを算出 paddingとborderをwidthとpaddingに含める */ box-sizing: border-box; } |
bodyの設定
1 2 3 4 5 6 7 8 |
body { font-family: "Oswald", sans-serif; /* テキストを真ん中寄せにする */ text-align: center; /* はみ出た要素を非表示 */ overflow: hidden; margin: 0; } |

h3の設定
1 2 3 4 |
h3 { margin-bottom: 0; text-align: center; } |

smallの設定
1 2 3 4 5 6 |
small { /* block要素にする */ display: block; margin-bottom: 20px; text-align: center; } |

fa-heartの設定
1 2 3 |
.fa-heart { color: red; } |

loveMeの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 |
.loveMe { height: 440px; width: 300px; background: url("https://images.unsplash.com/photo-1504215680853-026ed2a45def?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=334&q=80") no-repeat center center/cover; /* 要素を真ん中寄せにする */ margin: auto; cursor: pointer; max-width: 100%; /* 要素の基準位置 */ position: relative; box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); } |


fa-heartとアニメーションの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.loveMe .fa-heart { /* relativeからみた要素の絶対位置 */ position: absolute; /* アニメーション「grow」を設定 */ animation: grow 0.6s linear; /* アニメーション translateとscale */ transform: translate(-50%, -50%) scale(0); } @keyframes grow { /* to -> アニメーションの終わりである 100% を示します。 */ to { /* scaleを10に拡大 */ transform: translate(-50%, -50%) scale(10); } } |
これで、画像にダブルクリックしたときに、ハートを拡大して表示します。

おわりに
CSSのスタイリングは、一見難しそうに思えますが、要素のブロックとCSSプロパティの意味を一つ一つ理解していけば、攻略していけると思います。
子供の積み木遊びと似ていると思うので、教育にも良さそうですよね^^
それでは、また!
CSSまとめ
CSSソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
@import url("https://fonts.googleapis.com/css?family=Oswald"); * { /* ボックスの大きさを算出 paddingとborderをwidthとpaddingに含める */ box-sizing: border-box; } body { font-family: "Oswald", sans-serif; /* テキストを真ん中寄せにする */ text-align: center; /* はみ出た要素を非表示 */ overflow: hidden; margin: 0; } h3 { margin-bottom: 0; text-align: center; } small { /* block要素にする */ display: block; margin-bottom: 20px; text-align: center; } .fa-heart { color: red; } .loveMe { height: 440px; width: 300px; background: url("https://images.unsplash.com/photo-1504215680853-026ed2a45def?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=334&q=80") no-repeat center center/cover; /* 要素を真ん中寄せにする */ margin: auto; cursor: pointer; max-width: 100%; /* 要素の基準位置 */ position: relative; box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22); } .loveMe .fa-heart { /* relativeからみた要素の絶対位置 */ position: absolute; /* アニメーション「grow」を設定 */ animation: grow 0.6s linear; /* アニメーション translateとscale */ transform: translate(-50%, -50%) scale(0); } @keyframes grow { /* to -> アニメーションの終わりである 100% を示します。 */ to { /* scaleを10に拡大 */ transform: translate(-50%, -50%) scale(10); } } |
コメントを残す
コメントを投稿するにはログインしてください。