【第4回HTML, CSS, JS編】基礎から学ぶJamstack構成のサイト開発

プロフィール画像

志田泰晟

2024年10月29日

リンクをコピーXでシェアするfacebookでシェアする

はじめに

こんにちは!Jamstack研究会の志田です。

メンバーズではJamstackやヘッドレスCMSに取り組むエンジニアを増やすことを目的に「Jamstack研究会」が設立され、Jamstackの勉強会や研究を行っています。
本ブログシリーズでは、「Astro + microCMS + AWSを使用したJamstackなポータルサイトの開発手法」について皆様にお届けしています。

今回は、シリーズ第4回ということで、Bento UIを作成しながら、AstroでのHTML, CSS, JSの書き方について紹介していきます。
※前回の記事を読んでいない方は、「【第3回 コード整形 & VSCodeの拡張機能・設定編】基礎から学ぶJamstack構成のサイト開発Open in new tab」をご覧ください。

前提

  • 本開発ではVisual Studio Code(以下VSCode)を使用します。(他のエディターを使っていただいても問題ありません。)
  • 開発にはmacOSを使用しています。(Windowsで実行する際に別途Windows用の手順が必要な場合があります。)
  • シェルはzshを使用しています。

ポータルサイトのデザイン

Bento UIを作成しながら、AstroのHTML, CSS, JSの書き方について紹介していきます。Bento UIとは「弁当箱におかずを詰めるようにWebサイトにコンテンツを並べたデザイン」のことで、最近よく見かけるデザインです。
Bento UIの中でも、今回はAstroThemesのGuridoデザインを参考にデザインを作成していきます。
AstroThemes:https://astro.build/themes/details/guridoOpen in new tab

Astroの書き方

コンポーネントスクリプト

コンポーネントスクリプトと呼ばれる、’---’で囲まれたブロックがあります。ここには、コンポーネントのimportやpropsの受け取りなど、ビルド時に動く処理を記載することができます。またTypeScriptにも対応しており、型定義も行うことができます。

HTML

通常のHTMLを記述することができます。Reactのような、classをclassNameのように書き換える必要もありません。コンポーネントはReactのJSXのように扱うことができます。

CSS

<style>タグを設置しCSSを記述することができます。記述したCSSは自動的にスコープされ、他のコンポーネントに影響しません。スコープを無効にしたい場合は、<style is:global>属性を付与することで無効にできます。
また、npm install sassコマンドで別途Sassをインストールし、<style lang=”scss”>と記述することでSCSS記法を使用することもできます。(<style lang=”sass”>も可)

JavaScript

.astroファイル内に<script>タグを追加することで、クライアントサイドで動作するJavaScriptを記述することができます。すべてのインポートはバンドルされ、ローカルファイルやNodeモジュールをインポートできます。また、TypeScriptにも対応しています。


STEP1 reset.cssとcommon.cssを作成

src/stylesディレクトリ配下にファイルを作成し、CSSを記述していきます。


src/styles/reset.css


* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    border: 0;
}

src/styles/common.css

h1,
h2,
h3 {
    font-family: Comico;
}

p {
    padding: 1rem 0;
}

/* Text Color */
.text-white {
    color: #fff;
}

.text-red {
    color: #f12607;
}

.text-small {
    font-size: 1.875rem;
}

.text-medium {
    font-size: 2.25rem;
}

h3,
.text-large {
    font-size: 3rem;
}

h2,
.text-huge {
    font-size: 3.75rem;
}

/* Text Font */
.font-comico {
    font-family: Comico;
}

/* Flex */
.flex-col {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.flex-row {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    gap: 0.5rem;
}

@media (max-width: 1024px) {
    .col-span-full {
        grid-column-start: 1;
        grid-column-end: -1;
    }
}

STEP2 レイアウトの作成

Layout.astroとslot

ページテンプレートのような再利用可能なUI構造を作成するために使用されるAstroコンポーネントです。ヘッダーやナビゲーションバー、フッターなど、複数ページで簡単に共通レイアウトを持たせることができます。
 slotは親コンポーネントの<slot />が書かれた場所に子要素を丸ごと渡すことができます。コンポーネントに渡された子要素は、<slot />内でレンダリングされます。(Reactでいう、childrenに相当するもの)

Layout.astroファイルにCSSを記述します。

src/layouts/Layout.astro


<style>
    html {
        font-family:
            ui-sans-serif,
            system-ui,
            sans-serif,
            'Apple Color Emoji',
            'Segoe UI Emoji',
            Segoe UI Symbol,
            'Noto Color Emoji';
    }
    body {
        background-color: #f3f4f6;
        min-height: 100vh;
        display: flex;
        flex-direction: column;
        gap: 0.5rem;
        margin: 0 auto;
        padding: 2rem;
        max-width: 1280px;
        color: #0f1014;
    }
</style>

STEP3 コンポーネントの作成

ButtonLinkコンポーネントを作成します。propsを受け取ることにより、テキストやカラーを使用時に変更できるようにしています。

src/components/ButtonLink.astro


---
interface Props {
    text: string;
    link: string;
    textColor: string;
    bgColor: string;
}

const { text, link, textColor, bgColor } = Astro.props;
---

<a href={link} target="_blank" rel="noopener noreferrer"><div>{text}</div><div>→</div></a>

<style define:vars={{ textColor, bgColor }}>
    a {
        color: var(--textColor);
        background-color: var(--bgColor);
        transition-duration: 0.3s;
        font-weight: 600;
        font-size: 1.25rem;
        line-height: 1.75rem;
        padding: 0.5rem 2rem;
        border-radius: 0.75rem;
        height: 4rem;
        display: flex;
        justify-content: space-between;
        align-items: center;
        text-decoration: inherit;
    }
    a:hover{
        color: white;
        background-color: black;

    }
</style>

次にBentoコンポーネントを作成します。Bentoコンポーネントは<slot />を用いて、子要素を渡せるようにしています。

src/components/Bento.astro


---
interface Props {
    bgColor?: string;
    className?: string;
}

const {
    bgColor = '#E5E7EB',
    className
} = Astro.props;
---

<div class={className}>
    <slot />
</div>

<style define:vars={{ bgColor }}>
    div {
        background-color: var(--bgColor);
        padding: 2rem;
        border-radius: 1.5rem;
        min-width: 100%;
    }
</style>

最後にTwoColLayoutコンポーネントを作成します。こちらは、子要素として渡した要素を、グリッドレイアウトにするコンポーネントです。
ブラウザ画面サイズが1024px以上は2列、それ以下は1列になるレスポンシブ対応になっています。

src/layouts/TwoColLayout.astro


<div>
    <slot />
</div>

<style>
    div {
        display: grid;
        grid-template-columns: repeat(1, 1fr);
        gap: 0.5rem;
        min-width: 100%;
    }
    @media (min-width: 1024px) {
        div {
            grid-template-columns: repeat(2, 1fr);
        }
    }
</style>

STEP4コンポーネントの読み込み

作成したコンポーネントを組み合わせて、ページを作成していきます。
初めに、コンポーネントスクリプト内で、作成したコンポーネントをインポートします。

src/pages/index.astro


---
import Bento from '../components/Bento.astro';
import ButtonLink from '../components/ButtonLink.astro';
import Layout from '../layouts/Layout.astro';
import TwoCol from '../layouts/TwoColLayout.astro';
---

次に、mainタグの中身を下記に変更します。

<Layout title="Jamstack Portalsite">
    <main>
        <TwoCol>
            <div class="flex-col">
                <Bento bgColor="#279E54">
                    <div class="text-small font-comico text-white">Hello Members!</div>
                    <h2 class="text-large text-white">About Jamstack Study Group</h2>
                    <p class="text-white">
                        fuga近年注目されているJamstackと、広く普及し始めているヘッドレスCMSに取り組むエンジニアを増やすことが必要だと感じ、本ギルドが開設されました。
                        <br />
                        Jamstackな人材の育成や技術研究、社内外への普及活動に取り組んでいます。
                    </p>
                </Bento>
                <Bento bgColor="#7498FF">
                    <h3 class="text-white text-medium">Application Form</h3>
                    <p class="text-white">
                        Jamstackに関するハンズオンや勉強会、時にはブログ執筆をして広報活動を行なっています。<br />
                        研究員が自主的に活動内容を決めて行っているので裁量が大きいのもポイントです!<br />
                        「まずは話を聞いてみたい」「活動を見学したい」からOK!
                        <br />
                    </p>
                    <ButtonLink text="問い合わせはこちらから" link="" bgColor="#fff" textColor="#7498FF" />
                </Bento>
            </div>
            <Bento>
                <div class="info">
                    <h2 class="text-red">News</h2>
                    <div>
                        <div></div>
                    </div>
                </div>
            </Bento>
        </TwoCol>
    </main>
</Layout>

最後に、styleタグの中身を下記に変更します。


<style>
    main {
        display: flex;
        flex-direction: column;
        gap: 0.5rem;
    }
    .info {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100%;
    }

    .iflame {
        height: 30rem;
    }
</style>

propsでデータの受け渡し

propsは、コンポーネントスクリプトでAstro.propsから受け取ることができます。propsの型は、Props型を定義することで自動で判別されます。

STEP5ページの確認

以上でコーディング部分は終了です。npm run startコマンドでローカルサーバーを立ち上げページを開き、画像のようなページができていれば完成です。

次回予告

第4回は以上となります。
今回はAstroでのHTML, CSS, JavaScriptの書き方についてを行いました。コンポーネントベースで開発することで、再利用性や保守性を高められるので、効率よく開発を行うことができます。
HTML, CSS, JavaScriptも素の状態でシンプルに扱ったり、ReactやVueといったライブラリと連携したりと柔軟に対応できるため、導入も容易です。

次回の第5回目は「Amplifyで自動デプロイ」についてです。
第5回目の記事も是非ご覧ください。

この記事を書いた人

志田泰晟
志田泰晟
2023年にメンバーズに新卒入社。現在は企業のWebサイト制作を行っている。「つよつよエンジニア」を目指して日々奮闘中。
ページトップへ戻る