57
52

More than 1 year has passed since last update.

【Next.js + Tailwind】これを押さえればOK 最新のフロントエンド開発

Last updated at Posted at 2021-11-11

目次

1.この記事を書くきっかけ
2.自己紹介
3.この記事を見てほしい人
4.Reactについて
5.Next.js + Tailwind cssの導入方法
6.Tailwind css
7.スクロールアニメーション
8.Next.jsのImageについて
9.おわり
10.おまけ

1. この記事を書くきっかけ

fwywdという会社の1次試験でQiitaに記事を投稿するという試験があり、書くことになりました。

初めて記事を書くので、ご不明な点等があるかもしれませんが、できるだけ詳しく書いていくので、どうぞよろしくお願いいたします。

2. 自己紹介

私はhtml css を3カ月前に勉強し始めたばかりの学生です。

Tailwind css歴は2カ月程度ですが、こんな私でもfwywdの一次試験のサイト制作が合格したので、ぜひ参考にしていただければ幸いです。

3. この記事を見てほしい人

  • Reactを触ったことがある人(jsx記法、コンポーネント化)
  • cssを触ったことがある人(hover、レスポンシブ対応)
  • Tailwind cssを触ったことがない人
  • fwywdの一次試験に応募したい人

4. Reactについて

ReactはNext.jsのもとになるものですが、説明については割愛させていただきます。
こちらの動画で詳しく解説しています。

5. Next.js+Tailwind cssの導入方法

nodeについて

nodeは必須なので、入っていない方はこちらの記事を参考にしてください

すでにnode、npmかyarnが入っている方

vscode

vscodeが入っていない方は、インストールすることを強くお勧めします。

個人的におすすめな拡張機能

絶対に必要

  • Japanese Language Pack ( 日本語になる )
  • Tailwind CSS intelliSense ( 補完機能 )
  • Error Lens ( エラーの内容が表示される )
  • ESLint ( 構文エラーがわかる )

あると便利

  • Auto Rename Tag ( 開始タグ、終了タグの片方を自動補完 )
  • Git History ( git使うときに便利 )
  • indent-rainbow ( 空白に色がついて、まとまりがわかりやすい )
  • HTML CSS Support ( 補完機能 )
  • HTML Snippets ( 補完機能 )

6. Tailwind cssについて

生のcssの説明については割愛させて頂きます。

基本的な使い方

Tailwind css は、HTMLのタグにクラスを与えることで、スタイルが付加されます。

Bootstrapを触ったことがある人なら、すぐに慣れると思います。

cssのコード

h1{
font-size:30px;
color:#535353;
width:100%;
height:50%;
}

Tailwind cssのコード

<h1 className="text-[30px] text-[#535353] w-full h-[50%] ">Hello Tailwind</h1>

S__22822919.jpg

このように、必要なスタイルに応じたクラスを、つけ足していきます。

下のサイトはTailwind cssを使う上で必須なサイトで、サイトの上部の ”Search” に当てたいcssを入力するとTailwindのクラスに直してくれます。


background-color

結果
bg-red-50
bg-red-100


ファイルのtailwind.config の設定を mode:"jit"にしないと、[ ]を使った書き方はできません。

基本的なクラス

padding -> p
margin  -> m 
width   -> w
height  -> h

例
padding:10px;     -> p-[10px]
padding-left:10%; -> pl-[10%]
margin:10px;      -> m-[10px]
margin-left:10%;  -> ml-[10%]
width:100px       -> w-[100px]
width:100%        -> w-full か w-[100%]
height:2em        -> h-[2em]
height:100vh      -> h-[100vh]

font-size:100px;  -> text-[100px]
font-family:bold; -> font-bold

color:red;     -> text-red-500
color:#92400E; -> text-[#92400E]

background-color:red;    -> bg-red-500
background-color:#92400E -> bg-[#92400E]

border:2px solid black; -> border-2 border-black border-solid
border-radius:100px;    -> rounded-[100px]

text-align:center; -> text-center
text-align:left    -> text-left

float:left;  -> float-left
float:right; -> float-right

opacity:0.1; -> opacity-10
opacity:1;   -> opacity:100
opacity:0.54 -> opacity-[54%]

display:none;         -> hidden
display:block;        -> block
display:inline;       -> inline
display:inline-block; -> inline-block
display:flex;         -> flex
display:grid;         -> grid

position:relative; ->relative
position:absolute; -> absolute
position:fixed;    -> fixed
position:static;   -> static

基本的なcss はこのようなクラスを書くことで、同等のスタイルになります。

これを見て、「案外、複雑じゃないかも!」と思えたら、すぐにTailwind cssをマスターできるはずです。

hover activeについて

次に、hoverやactiveについてです。

Tailwind cssではクラスの前に hover: とつけるだけで、hoverしたときのスタイルになります。
しかし、ひとつひとつにhover:をつける必要があるところがデメリットです。

試しにこちらのコードを読み込んでみてください。

<button className="py-[10px] px-[20px] border border-black duration-300 hover:text-white hover:bg-black hover:translate-y-[-10px] hover:rotate-[360deg] hover:scale-150">Hover me!</button>

通常
S__22822921.jpg

hoverした時
S__22822922.jpg

hoverしたときにボタンが動いたでしょうか?
ここに書いてある hover: で始まるクラスは、全てhoverしたときに発火します。

hover:p-10 hover:m-10 hover:text-black hover:hidden のように、ほとんどのクラスをhoverにあてることができます

activeについても同様で、先ほどのコードのhoverの部分をactiveに変えるだけで、クリックしている間だけ発火させることができます。

<button className="py-[10px] px-[20px] border border-black duration-300 active:text-white active:bg-black active:translate-y-[-10px] active:rotate-[360deg] active:scale-150">Click me!</button>

また、このクラスの中に duration-300とありますが、これはcssでいうtransition:0.3sと同じスタイルになるので、hoverやactiveを使うときには必ずつけましょう

レスポンシブについて

レスポンシブデザインは、cssでは

@media (min-width: 600px) {
    /* 画面の横幅が600px以上で適用 */
}
@media (min-width: 1000px) {
    /* 画面の横幅が1000px以上で適用 */
}

のように書きます。

Tailwind cssの場合では、hover: active:と似た書き方になります。

<button className="py-[10px] px-[20px] border border-black block sm:hidden md:block lg:hidden xl:block 2xl:hidden"> responsive BTN </button>

S__22822934.jpg

S__22822936.jpg

S__22822937.jpg

S__22822938.jpg

S__22822939.jpg

S__22822940.jpg

画面の横幅を変えることで、このボタンは出たり消えたりします。

このsm: のように書いたものはデフォルトで、以下のようになります。

BreackPoint min-width CSS
sm 640px @media (min-width: 640px) { ... }
md 768px @media (min-width: 768px) { ... }
lg 1024px @media (min-width: 1024px) { ... }
xl 1280px @media (min-width: 1280px) { ... }
2xl 1536px @media (min-width: 1536px) { ... }
<p className="text-[10px] sm:text-[100px]"> Big </p>

このコードの場合、sm(640px)になるまで text-[10px]の状態でいて、sm(640px)を超えた時に text-[100px]の状態になります。

7. スクロールアニメーション

スクロールアニメーションをつけると、それだけでとても高度なサイトに見せることができます。

生のJavaScriptでやると、

        const els = document.querySelectorAll(".new-Animation");
        const cb = function (entries, observer) {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    entry.target.classList.add("fadeIn");
                    //observer.unobserve(entry.target);
                } else {
                    entry.target.classList.remove("fadeIn");
                }
            });
        }
        const options = {
            root: null,
            rootMargin: "0px 0px",
            threshold: 0
        };
        const io = new IntersectionObserver(cb, options);
        els.forEach(el => io.observe(el));

このような書き方になると思います。ですが、Next.jsはReactなのでdom操作は推奨されていません。

そこで、react-intersection-observerというライブラリを使うと、簡単に実装することができます。

以下のサイトでわかりやすく説明しています。

スクロールアニメーションのコンポーネント化

また、スクロールアニメーションを導入する際におススメするのが、スクロールアニメーションの動作をコンポーネント化して、動作させたい要素ごとに呼び出す方法です。

その方法は、まず、react-intersection-observerをインストールします。

そして、プロジェクトの直下にcomponentsフォルダを作り、ここではFadeIn.jsxを作ります。

components
 FadeIn.jsx
pages
  api
  _app.js
  index.js

FadeIn.jsxに以下を書きます。

import { useInView } from 'react-intersection-observer';

export const FadeIn = ({ children }) => {
    const { ref, inView } = useInView({
        // オプション
        rootMargin: '-50px', // ref要素が現れてから50px過ぎたら
        triggerOnce: true, // 最初の一度だけ実行
    });

    return (
        <div
            ref={ref}
            className={`${inView ? "opacity-100" : "opacity-0 translate-y-[50%]"} duration-[1s]`}
        >
            {children}
        </div>
    )
}

そしたら、index.jsに以下を書くとスクロールアニメーションが実行できます。

import { FadeIn } from '../components/FadeIn';

export default function Home() {
  return (
    <div>
      <FadeIn>
        <h1 className="my-[300px] text-[100px]">fadein</h1>      
      </FadeIn>
      <FadeIn>
        <h1 className="my-[300px] text-[100px]">fadein</h1>      
      </FadeIn>
      <FadeIn>
        <h1 className="my-[300px] text-[100px]">fadein</h1>      
      </FadeIn>
    </div>
  )
}

このように<FadeIn></FadeIn>で囲った要素が、スクロールで画面に入った時にふわっと出現ます。

右から出現

import { useInView } from 'react-intersection-observer';

export const SlideInRight = ({ children }) => {
    const { ref, inView } = useInView({
        // オプション
        rootMargin: '-100px', // ref要素が現れてから50px過ぎたら
        triggerOnce: true, // 最初の一度だけ実行
    });

    return (
        <div
            ref={ref}
            className={`${inView ? "opacity-100" : "opacity-0 translate-x-[50%]"} duration-[1s]`}
        >
            {children}
        </div>
    )
}

左から出現

import { useInView } from 'react-intersection-observer';

export const SlideInLeft = ({ children }) => {
    const { ref, inView } = useInView({
        // オプション
        rootMargin: '-100px', // ref要素が現れてから50px過ぎたら
        triggerOnce: true, // 最初の一度だけ実行
    });

    return (
        <div
            ref={ref}
            className={`${inView ? "opacity-100" : "opacity-0 translate-x-[-50%]"} duration-[1s]`}
        >
            {children}
        </div>
    )
}

これをセクションや、ブロックごとに、このコンポーネントを使い分けることで、よりアップグレードしたサイトになります。

8. next.jsのImageについて

Next.jsはそのまま使うだけでも、SEO効果がかなり高いです。
さらに、SEO効果を高めるためにimgタグではなく、Imageを使うことが推奨されています。

こちらのサイトで詳しく説明しています。

昔のNext.jsでは

<img src="/img.png" alt="img"/>

と、いう書き方でしたが

import img from "../public/img.png"
.
.
.
<Image src={img} alt="img"/>

今は、このような書き方が推奨されています。

元の画像のサイズを変えない場合の書き方です。

<Image src={img} placeholder="blur" alt="img" />

また、このようなオプションをつけることをおススメします。
placeholder="blur"をつけることで、画像完全に読み込まれるまで、ぼやけて表示してくれるので、表示速度が上昇します。
(src={img}のような書き方以外は、placeholderは使えません)

画像のサイズを変える場合で、アスペクト比を保ちたい場合には以下のように書きます。

<Image src="/img.png" width={100} height={500} objectFit="contain"  alt="img"/>

widthとheightは、両方かかないとエラーになるので注意して下さい。
また、objectFit="contain"を追加すると、画像のアスペクト比が保たれます。

9. おわり

お疲れ様でした。Next.js + Tailwind css はこの先のフロントエンドで主流になると思うので、ぜひこの機会に習得してみてください。

ここまで読んでいただき誠にありがとうございました。

10. おまけ

固定されたヘッダーを、下スクロールしたときに消えて、上スクロールしたときに表示する方法

このgithubのサイトをスクロールしていくと、inistall の仕方が書いてあります。
コードはこちらです。

import { useState } from 'react';
import { useScrollPosition } from "@n8tb1t/use-scroll-position";

export default function Home() {

const [showHeader, setShowHeader] = useState(true);
  useScrollPosition(({ prevPos, currPos }) => {
    const visible = currPos.y > prevPos.y;
    setShowHeader(visible);
  }, []);

return(
  <div>
      <header className={`fixed top-0 z-10 bg-red-300 bg-opacity-75 w-full duration-300
        ${showHeader ? "" : "translate-y-[-100%]"}`}>
        HEADER
      </header>

      <div className="my-[1000px]">text</div>
  </div>
  )
}

header のクラス内に${showHeader ? "" : "translate-y-[-100%]"}とあります。

これは、showHeaderという変数に今現在上にスクロールしているか、下にスクロールかを判別しています。

また、この書き方は三項演算子といい、ここではshowHeaderがtrueの時に左、falseの時に右の""の中が実行されます。

ここでは、下にスクロールしているときはtrueが格納されるので${showHeader ? "" : "translate-y-[-100%]"}ここでいう ""がクラスにあてられます。

上にスクロールしているときはfalseが格納されるので"translate-y-[-100%]"、つまり上に100%動くのでヘッダーが上に隠れます。

57
52
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
57
52