1:Netlifyにデプロイする準備
index.htmlに以下の記述にする
タイトルとサイトの説明とアイコンの設定をしているよ
MinifyでJavaScriptやCSSのスペースを除去する作業をして貼り付け
画像を圧縮してサイズを小さくする
手動でもいいが、自動化する場合は別の記事で記載します
MinifyでJavaScriptやCSSのスペースを除去する作業をして貼り付け
画像を圧縮してサイズを小さくする
手動でもいいが、自動化する場合は別の記事で記載します
class MobileMenu {
// コストラクタ関数を用意する
constructor() {
// オブジェクトリテラルで初期化
this.DOM = {};
this.DOM.btn = document.querySelector('.mobile-menu__btn');
this.DOM.cover = document.querySelector('.mobile-menu__cover');
// this.DOM.containerでないとエラーになるよ
this.DOM.container = document.querySelector('#global-container');
this.eventType = this._getEventType();
this.__addEvent();
}
// プライベートメソッドにする(修正や保守のしやすさのため)
_getEventType() {
// スマホとデスクトップ対応するためにクリックかタッチかで処理をわける
return window.ontouchstart ? "touchstart" : "click";
}
_toggle() {
// global-containerにクリックするたびにmenu-openを付加、解除
this.DOM.container.classList.toggle("menu-open");
}
__addEvent() {
// ボタンが押されたら発火
this.DOM.btn.addEventListener(this.eventType, this._toggle.bind(this));
// カバーかクリックしたときに発火
this.DOM.cover.addEventListener(this.eventType, this._toggle.bind(this));
}
}
モバイルメニューが正常に働くことを確認する
.world {
@extend .content-width;
@extend .mb-lg;
// 親要素でローカルスタッキングコンテキストを作るために必要
&__inner {
@extend .flex;
justify-content: space-between;
// 周りに壁を作る
padding: 15px;
background-color: $cBgGray;
// 下の2つはローカルスタッキングコンテキストを作る設定
position: relative;
z-index: 0;
}
&__title {
// 横線の位置決め
position: relative;
// 横線を疑似要素で出力する
@include p-base(
$display: none,
$width: 70px,
$height: 1px,
$top: 50%,
// 線の長さ
$left: -75px
) {
// 棒線が伸びるアニメーション
background-color: $cBlack;
transform: translateY(-50%) scaleX(0);
// 右側を中心に伸びるアニメーション
transition: transform 0.3s ease 1.6s;
transform-origin: right;
}
}
&__sub {
@extend .mb-sm;
}
&__img {
height: 300px;
@extend .mb-sm;
// アニメーションが終わったときに表示したいので
transition: box-shadow 1ms linear 0.8s;
& > img {
position: relative;
// ボックスシャドウを背面につけるための設定
z-index: -1;
// 画像には基本object-fitをつける
object-fit: cover;
// 画像の上部分を中心にしたいので
object-position: top;
// 外側の親要素タテヨコ100%で画像が表示される
width: 100%;
height: 100%;
}
&.inview {
// 内側にボックスシャドウを付ける設定
box-shadow: inset 0 0 30px $cBlack;
}
}
&__texts {
@extend .pb-sm;
// 横線のアニメーションの設定
&.inview {
& .world__title::before {
//右から左に線が伸びるように
transform: translateY(-50%);
}
}
}
}
//ロゴ
.logo {
font-size: 42px;
display: flex;
&__img {
width: 0.7em;
}
&__Garden {
color: $cWineRed;
}
}
// スマホ画面のときサイド要素を非表示にする
.side {
display: none;
// 固定する
position: fixed;
// 画面の上から70%から表示する
top: 70%;
// ここは検証で試してみるとよい
transform: translateY(-50%);
transition: all 0.3s ease-in;
& .tween-animate-title {
color: $cBlack;
text-decoration: none !important;
margin: 0 40px;
// ロゴと文字の中心のズレを修正
vertical-align: middle;
letter-spacing: 2px;
}
// サイドバー左側の設定
&.left {
left: -50px;
&.inview {
left: 50px;
}
& .side__inner {
// 左端を軸とするための設定
transform-origin: top left;
// 文字を-90度回転させる
transform: rotate(-90deg);
}
}
// サイドバー右側の設定
&.right {
right: -50px;
&.inview {
right: 50px;
}
& .side__inner {
// 右端を軸とするための設定
transform-origin: top right;
// 文字を90度回転させる
transform: rotate(90deg);
}
}
}
.icon {
position: relative;
@include p-base($left: -20px, $top: 50%, $width: 1em, $height: 1em) {
transform: translateY(-50%);
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
//ロゴの設定
&.twitter {
&::before {
background-image: url(../images/twitter.svg);
}
}
&.fb {
&::before {
background-image: url(../images/facebook.svg);
}
}
}
// サイドバーのローカルスタッキングコンテキストを作るための設定
#main-content {
position: relative;
z-index: 0;
}
// サイドバーより背面にしたい
main {
position: relative;
z-index: -1;
}
// Stylesheet: 600px以上のタブレットやモニタで適用
.flex {
// 横に2列したいときの設定
flex-direction: row;
// これを設定しないとflex-basisが変わらない
flex-wrap: wrap;
}
.flowers {
&__item {
flex-basis: 50%;
margin-bottom: 60px;
}
}
.popular {
&__container {
// 余白を真ん中にしたい
justify-content: space-between;
}
&__item {
flex-basis: 47%;
}
}
.world {
&__inner {
padding: 50px;
}
&__texts,
&__img {
flex-basis: 47%;
}
&__texts {
display: flex;
// 文字を下揃えにするときに便利な設定
align-items: flex-end;
}
}
.footer {
& .logo {
// 左寄りにする右寄りはflex-end
justify-content: flex-start;
}
&__li {
// 検証を使いながら位置調整
margin-left: 0;
margin-right: 30px;
}
}
// Stylesheet: 960px以上のモニタで適用
.font-sm {
font-size: 16px;
}
.font-md {
font-size: 19px;
}
.font-lr {
font-size: 23px;
}
.font-lg {
font-size: 36px;
}
.mb-lg {
margin-bottom: 150px !important;
}
.pb-lg {
padding-bottom: 150px !important;
}
.popular {
&__item {
flex-basis: 25%;
}
&__img {
height: 335px;
}
}
.world {
&__img {
height: 400px;
}
&__description {
margin-bottom: 40px;
}
&__title {
// アニメーションを表示するための設定
&::before {
// 960px以上のときアニメーションするように設定
display: block;
}
}
}
.footer {
&__li {
justify-content: flex-start;
}
}
// 960以上ではヘッダー表示
.header {
&__nav {
display: block;
}
}
// ハンバーガーメニューを非表示にする(モバイル用でないため)
.mobile-menu {
&__btn {
display: none;
}
}
// スワイパースライドに影をつける
.swiper-slide {
box-shadow: 0 8px 40px -10px rgba(0, 0, 0, 0.8);
}
// Stylesheet: 1280px以上のモニタで適用
.world {
&__inner {
padding: 50px 150px;
}
}
.popular {
&__item {
flex-basis: 23%;
}
}
// サイドバー要素を表示する
.side {
display: block;
}
$cWhite: white;
$cBlack: black;
$cSubTitle: #535353;
$cBgGray: #eaebe6;
$cWineRed: #904669;
$contentMaxWidth: 1070px;
$navHeight: 100px;
以前作成したページローダーを流用する
loader.scssに読み込ませるため以下のように記述
このようになっていればOK
フェードインアニメーションで作った_appear.scssをmodulesに配置してstyle.scssで読み込む
使い方index.htmlの親要素にappearをつけて子要素にitemをつけるとフェードインアニメーションを付加できる。
モバイルメニューのところで作成したstyle.scssを流用する
_mobile-menu.scssにリネームしてmodulesに貼り付けする
style.scssで読み込むのも忘れずに
$cMenuClose: Black;
$cMenuOpen: Black;
.mobile-menu {
position: fixed;
right: 0;
// 上から60px
top: 60px;
width: 300px;
& .logo {
padding: 0 40px;
font-size: 38px;
}
// BEM(Block Element Modifier)
&__btn {
background-color: unset;
border: none;
outline: none !important;
cursor: pointer;
& > span {
background-color: $cMenuClose;
width: 35px;
height: 2px;
display: block;
margin-bottom: 9px;
transition: transform 0.7s;
&:last-child {
margin-bottom: 0;
}
}
}
// 黒い膜をつける
&__cover {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
opacity: 0;
visibility: hidden;
transition: opacity 1s;
cursor: pointer;
z-index: 200;
}
&__main {
padding: 0;
// 3Dアニメーションをしたいとき親の要素につける
perspective: 2000px;
transform-style: preserve-3d;
}
&__item {
// ・をけす
list-style: none;
display: block;
transform: translate3d(0, 0, -1000px);
padding: 0 40px;
transition: transform 0.3s, opacity 0.2s;
opacity: 0;
}
&__link {
// 左右いっぱいに広がるようにする
display: block;
margin-top: 30px;
color: $cBlack;
// 下線を削除
text-decoration: none !important;
}
}
.menu-open {
// クリックしたときに左下にずれるアニメーションの設定
& #container {
transform: translate(-300px, 60px);
box-shadow: 0 8px 40px -10px rgba(0, 0, 0, 0.8);
}
// クリックされたときの記述を書く
& .mobile-menu {
&__cover {
opacity: 1;
visibility: visible;
}
&__item {
transform: none;
opacity: 1;
// 要素を少しずつ遅延して表示
@for $i from 1 through 5 {
&:nth-child(#{$i}) {
transition-delay: $i * 0.07s;
}
}
}
&__btn {
& > span {
background-color: $cMenuOpen;
&:nth-child(1) {
transition-delay: 70ms;
transform: translateY(11px) rotate(135deg);
}
&:nth-child(2) {
transition-delay: 0s;
transform: translateX(-18px) scaleX(0);
}
&:nth-child(3) {
transition-delay: 140ms;
transform: translateY(-11px) rotate(-135deg);
}
}
}
}
}
<main>
<section class="world">
<div class="world__inner">
<div class="world__img cover-slide">
<img class="img-zoom" src="images/Birthday.jpg" alt=""/>
</div>
<div class="world__texts appear left">
<div class="world__texts-inner">
<div class="world__title main-title item">
<span class="purple">Floroj </span>
<span>de la mondo</span>
</div>
<div class="world__sub sub-title item">世界のお花をあなたに</div>
<div class="world__description item">
<p>世界150ヶ国の花を<br />あなたにお届けします。</p>
<p>あなたの望む花がきっと見つかります。</p>
</div>
<div class="world__btn item">
<button class="btn filled">もっと詳しく</button>
</div>
</div>
</div>
</div>
</section>
document.addEventListener('DOMContentLoaded', function () { // newでインスタンス化 const hero = new HeroSlider('.swiper-container'); hero.start(); // コールバック関数を設ける const cb = function (el, inview) { if (inview) { const ta = new TweenTextAnimation(el); ta.animate(); } }; // 第1引数にエレメント第二引数にコールバック関数 const so = new ScrollObserver(".tween-animate-title", cb); // 第1引数にDOM第二引数にコールバック関数 const _inviewAnimation = function(el, inview) { if (inview) { // もし画面内に入ってきたらinviewを付加 el.classList.add('inview'); }else { // 画面外になったらinviewを削除 el.classList.remove('inview'); } } const so2 = new ScrollObserver(".cover-slide", _inviewAnimation); });
<div id="main-content"> <section class="houses"> <div> <h2 class="main-title tween-animate-title">Pick up</h2> <p class="sub-title tween-animate-title">ピックアップ特集</p> </div> <div class="houses__inner"> <div class="houses__item"> <div class="cover-slide hover-darken"> <div class="bg-img-zoom img-bg50" style="background-image: url(images/Alstroemeria.jpg)"> </div> </div> <p class="houses__title">旬の花</p> <p class="sub-title tween-animate-title">4月の旬の花はアルストロメリア</p> </div> <div class="houses__item"> <div class="cover-slide hover-darken"> <div class="bg-img-zoom img-bg50" style="background-image: url(images/Birthday.jpg)"> </div> </div> <p class="houses__title">誕生日プレゼント特集</p> </div> <div class="houses__item"> <div class="cover-slide hover-darken"> <div class="bg-img-zoom img-bg50" style="background-image: url(images/Rose-banquet.jpg)"> </div> </div> <p class="houses__title">バラ特集</p> </div> <div class="houses__item"> <div class="cover-slide hover-darken"> <div class="bg-img-zoom img-bg50" style="background-image: url(images/peach.jpg)"> </div> </div> <p class="houses__title">春の花特集</p> </div> <button class="btn slide-bg">さらに詳しく</button> </section> </div> </div> </div> <!-- <div class="cover-slide hover-darken"> <img class="img-zoom" src="images/nemophila.jpg" alt="" /> </div> <button class="btn float">Button</button> <button class="btn filled">Button</button> <button class="btn letter-spacing">Button</button> <button class="btn shadow">Button</button> <button class="btn solid">Button</button> <button class="btn slide-bg">Button</button> <button class="btn cover-3d">Button</button> --> <!-- <a class="btn-cubic"><span class="hovering">Now, Hovering</span><span class="default">Button</span></a> --> <script src="scripts/vendors/swiper.min.js"></script> <script src="scripts/vendors/TweenMax.min.js"></script> <script src="scripts/vendors/scroll-polyfill.js"></script> <script src="scripts/libs/scroll.js"></script> <script src="scripts/libs/text-animation.js"></script> <script src="scripts/libs/hero-slider.js"></script> <!-- <script src="scripts/libs/mobile-menu.js"></script> --> <script src="scripts/main.js"></script> </body> </html>
貼り付けたmain.js内の以下を切り取り
scripts/main.jsにこのように貼り付け
HTMLに設定を追加する
<metaname="viewport"content="width=device-width, initial-scale=1.0"/>
style.scssに以下のような設定をする
// スマホ画面の設定
@import "breakpoints/base";
// スマホ横向きのときの設定
@media (min-width: 480px) {
@import "breakpoints/480up";
}
// タブレットのときの設定
@media (min-width: 600px) {
@import "breakpoints/600up";
}
@media (min-width: 960px) {
@import "breakpoints/960up";
}
@media (min-width: 1280px) {
@import "breakpoints/1280up";
}
// Retinaディスプレイで適用
@media (min-resolution: 192dpi)
,(-webkit-min-device-pixel-ratio: 2) {
@import "breakpoints/2x";
}
// 印刷時のみ適用される設定
@media print {
@import "breakpoints/print";
}
モバイルファーストが基本
ある程度よく使うもの(フォントのサイズやマージンやパディング)を共通化する。
スマホ用とパソコン用で設定を変えると良い
https://swiperjs.com/get-started
HTMLに記述を追加することと下をコピー&ペースト
<!-- Slider main container -->
<div class="swiper">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
...
</div>
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- If we need scrollbar -->
<div class="swiper-scrollbar"></div>
</div>
CSSにこれも追加すること
.swiper {
width: 600px;
height: 300px;
}
@import "mixin"; $cWhite: white; @import 'hero-slider';
document.addEventListener('DOMContentLoaded', function () { // newでインスタンス化 const hero = new HeroSlider('.swiper-container'); hero.start(); });
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <link rel="stylesheet" href="loader.css"> <script src="./pace.js"></script> </head> <body> <div id="global-container"> <a href="https://github.hubspot.com/pace/docs/welcome/" target="_blank">PaceJs</a> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <div><img src="images/flowers1.jpg" alt="" /></div> <style> img { max-width: 100%; } </style> </div> </body> </html>