WEBサイト制作の勉強

WEBサイト制作の勉強の為の解説ブログです。

フェリカテクニカルアカデミー

3月14日の作業データ

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>レストランサイトの作成</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Stick&family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/hamburgers.css">
<link rel="stylesheet" href="css/jquery.bxslider.css">
<link rel="stylesheet" href="css/lightbox.css">
</head>
<body id="top">
<header>
<h1>Trattoria La Famiglia</h1>
<p class="tag-line">家族のように温かい、本場のイタリア料理</p>
<p class="logo"><img src="img/logo.svg" alt=""></p>
</header>

<p class="hamburger hamburger--stand" id="ham-btn">
  <span class="hamburger-box">
    <span class="hamburger-inner"></span>
  </span>
</p>

<nav id="g-nav">
<ul>
<li><a href="#top" data-en="TOP">トップ</a></li>
<li><a href="#news" data-en="NEWS">お知らせ</a></li>
<li><a href="#menu" data-en="MENU">メニュー</a></li>
<li><a href="#video" data-en="VIDEO">動画</a></li>
<li><a href="#shop" data-en="SHOP">店舗情報</a></li>
<li><a href="#reserve" data-en="RESERVE">ご予約</a></li>
</ul>
</nav>

<div class="main-visual">
<ul class="bxslider">
<li><img src="img/main-1.webp" alt=""></li>
<li><img src="img/main-2.webp" alt=""></li>
<li><img src="img/main-3.webp" alt=""></li>
</ul>
</div>

<div class="main-copy">
<h2>ようこそ、家族のように温かいイタリアへ!</h2>
<p class="lead">
Trattoria La Famigliaは、イタリアの家庭料理をアットホームな雰囲気で提供するレストランです。<br>
まるでイタリアの田舎に来たような、温かく親しみやすい空間で、おばあちゃんが作るような素朴で美味しい料理をお楽しみください。<br>
厳選された旬の食材を使い、伝統的なレシピで丁寧に作られた料理は、心も体も温まる美味しさです。</p>
</div>

<div class="gallery">
<p><img src="img/gallery-1.jpg" alt=""></p>
<p><img src="img/gallery-2.jpg" alt=""></p>
</div>

<main>
<section id="news">
<h3 data-en="NEWS">お知らせ</h3>
<dl id="news-list">

</dl>
</section>

<div class="parallax-1"></div>

<section id="menu">
<h3 data-en="MENU">メニュー</h3>
<div class="menu-wrapper">
<div class="menu-box">
<a href="img/menu-1.jpg" data-lightbox="photo">
<p class="menu-photo"><img src="img/menu-1.jpg" alt=""></p>
<p class="menu-txt">Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis, necessitatibus?</p>
</a>
</div><!-- /.menu-box -->
<div class="menu-box">
<a href="img/menu-2.jpg" data-lightbox="photo">
<p class="menu-photo"><img src="img/menu-2.jpg" alt=""></p>
<p class="menu-txt">Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis, necessitatibus?</p>
</a>
</div><!-- /.menu-box -->
<div class="menu-box">
<a href="img/menu-3.jpg" data-lightbox="photo">
<p class="menu-photo"><img src="img/menu-3.jpg" alt=""></p>
<p class="menu-txt">Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis, necessitatibus?</p>
</a>
</div><!-- /.menu-box -->
<div class="menu-box">
<a href="img/menu-4.jpg" data-lightbox="photo">
<p class="menu-photo"><img src="img/menu-4.jpg" alt=""></p>
<p class="menu-txt">Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis, necessitatibus?</p>
</a>
</div><!-- /.menu-box -->
<div class="menu-box">
<a href="img/menu-5.jpg" data-lightbox="photo">
<p class="menu-photo"><img src="img/menu-5.jpg" alt=""></p>
<p class="menu-txt">Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis, necessitatibus?</p>
</a>
</div><!-- /.menu-box -->
<div class="menu-box">
<a href="img/menu-6.jpg" data-lightbox="photo">
<p class="menu-photo"><img src="img/menu-6.jpg" alt=""></p>
<p class="menu-txt">Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis, necessitatibus?</p>
</a>
</div><!-- /.menu-box -->
</div><!-- /.menu-wrapper -->
</section>

<section id="video">
<h3 data-en="VIDEO">動画</h3>
<div class="video-wrapper">
<iframe src="https://www.youtube.com/embed/toQ5bMf8mfw?si=qL3gYB4KltAxcIFF" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div><!-- /.video-wrapper -->
</section>

<section id="shop">
<h3 data-en="SHOP">店舗情報</h3>
<div class="shop-wrapper">
<div class="map-wrapper">
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3238.9452895590807!2d139.7117402746393!3d35.72756402742931!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x60188d68f6cfe057%3A0xddd17dcd7ecaf745!2z6LGK5bO25Yy656uL5Y2X5rGg6KKL5YWs5ZyS!5e0!3m2!1sja!2sjp!4v1710385754427!5m2!1sja!2sjp" style="border:0;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
</div><!-- /.map-wrapper -->

<div class="shop-info">
<dl>
<dt>171-11xx</dt>
<dd>東京都豊島区南池袋x-x-x</dd>
<dt>Tel</dt>
<dd class="tel"><a href="tel:03-1111-xxxx">03-1111-xxxx</a></dd>
<dt>Mail</dt>
<dd>example@gmail.com</dd>
</dl>

<dl>
<dt>Open</dt>
<dd>11:00 — 23:00</dd>
<dt>定休日</dt>
<dd>年末年始</dd>
<dt>駐車場</dt>
<dd>5台</dd>
</dl>
</div><!-- /.shop-info -->
</div><!-- /.shop-wrapper -->
</section>

<div class="parallax-2"></div>

<section id="reserve">
<h3 data-en="RESERVE">ご予約</h3>
</section>
</main>
<footer>

</footer>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="js/jquery.bxslider.js"></script>
<script src="js/lightbox.js"></script>
<script>
$(function(){
//ハンバーガーボタン
//#ham-btnをon.clickしたらthisに「is-active」をtoggleClassさせる
$('#ham-btn').on('click',function(){
$(this).toggleClass('is-active');
});


//メインビジュアル
$('.bxslider').bxSlider({
mode: 'fade',//画像の切り替わり方
auto: true,//trueがon
controls: false,//falseがoff
pager: false,
speed: 2000,//画像が切り替わる時間
pause: 2000,//画像が止まっている時間
});

//ajaxで外部データを呼び出す
$('#news-list').load('news.txt');



});
</script>
</body>
</html>
style.css
@charset "utf-8";

/* 変数の登録 */
:root{
--font_ja:"Stick", sans-serif;
--font_en:"Ubuntu", sans-serif;
--color_1:#297884;
--color_2:#e8ba3c;
--bg_1:#000;
}


*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul{
list-style: none;
}
a{
text-decoration: none;
}
img{
vertical-align: bottom;
max-width: 100%;
}
body{
color: #333;
}


header{
background-color: #d7ea91dc;
width: fit-content;/* 幅が中身の幅に合う */
position: absolute;
top: 80px;
left: 60px;
z-index: 10;
padding: 80px 40px 40px;

>h1{
font-family: var(--font_en);
margin-bottom: 20px;
font-size: 38px;
}
>.tag-line{
font-family: var(--font_ja);
font-size: 22px;
}
}


#g-nav{
display: none;
}

/* ロゴを回す */
.logo{
width: 160px;
position: absolute;
right: -70px;
top: -50px;
animation: logo-anime 7s infinite linear;
}

@keyframes logo-anime{
0%{rotate: 0;}
100%{rotate: 360deg;}
}



/* ハンバーガーボタン */
#ham-btn{
position: fixed;
top: 0;
right: 0;
z-index: calc(infinity);
background-color: #FFF;
}


/* メインビジュアル部分 */
.main-visual{
width: 100%;
height: 100vh;
margin-bottom: 140px;
}
.main-visual li{
width: 100%;
height: 100vh;
>img{
object-fit: cover;
width: 100%;
height: 100%;
}
}

/* メインコピー部分 */
.main-copy{
text-align: center;
font-family: var(--font_ja);
margin-bottom: 140px;
>h2{
font-size: 34px;
margin-bottom: 40px;
}
>.lead{
font-size: 22px;
max-width: 680px;
margin: 0 auto;
line-height: 2.2;
text-align: left;
}
}

/* ギャラリー部分 */
.gallery{
max-width: 600px;
margin: 0 auto 140px;
position: relative;/* positionの基準点 */
>p:nth-of-type(1){
box-shadow: 20px 20px 0 var(--color_1);
}
>p:nth-of-type(2){
width: 50%;
position: absolute;
right: -100px;
bottom: -100px;
box-shadow: 20px 20px 0 var(--color_2);/* 横、縦、影の距離、影の色 */
}
}


/* セクション部分 */
section{
padding: 100px 10px;

>h3{
text-align: center;
font-family: var(--font_ja);
color: var(--color_1);
font-size: 34px;
margin-bottom: 50px;
&::before{
display: block;
content: attr(data-en);
font-family: var(--font_en);
font-size: 28px;
color: var(--color_2);
}
}
}


/* お知らせ部分 */
#news-list{
max-width: 600px;
margin: 0 auto 140px;
display: flex;
flex-wrap: wrap;
font-size: 20px;
>dt{
width: 30%;
margin-bottom: 20px;
border-bottom: 2px solid var(--color_1);
padding: 5px 10px;
&:nth-of-type(n+4){
display: none;
}
}
>dd{
width: 70%;
margin-bottom: 20px;
border-bottom: 2px solid var(--color_1);
padding: 5px 10px;
&:nth-of-type(n+4){
display: none;
}
}
}


/* パララックス部分 */
.parallax-1{
width: 100%;
height: 70vh;
background: url(../img/parallax-1.webp) no-repeat center center/cover fixed;
}
.parallax-2{
width: 100%;
height: 70vh;
background: url(../img/parallax-2.webp) no-repeat center center/cover fixed;
}

/* メニュー部分 */
.menu-wrapper{
width: 90%;
margin: 0 auto 140px;
display: flex;
gap: 80px 40px;/* 上下、左右 */
flex-wrap: wrap;/* 折り返しの指定 */
}
.menu-box{
width: calc((100% - 80px) / 3 );/* 全部から必要な余白を引いて、3で割る */
border: 1px solid #5d5d5d;
padding: 16px;
>a{
color: #222;
&:hover img{
scale: 1.2;
transition: 0.2s;
}
>.menu-photo{
margin-bottom: 10px;
overflow: hidden;
}
>.menu-txt{
line-height: 1.6;
}
}
}


/* 動画部分 */
.video-wrapper{
width: 70%;
aspect-ratio: 16/9;
margin: 0 auto;
>iframe{
width: 100%;
height: 100%;
}
}


/* 店舗情報部分 */
.shop-wrapper{
max-width: 960px;
margin: 0 auto;
}
.map-wrapper{
width: 100%;
aspect-ratio: 2/0.8;
margin-bottom: 80px;
>iframe{
width: 100%;
height: 100%;
}
}

.shop-info{
display: flex;
>dl{
width: 50%;
display: flex;
flex-wrap: wrap;
>dt{
width: 25%;
margin-bottom: 20px;
}
>dd{ 
width: 75%;
margin-bottom: 20px;
}
}
}

/* 電話番号の設定 */
.tel>a{
pointer-events: none;
color: #333;
font-size: 24px;
}
news.txt
<dt>2024年3月17日</dt>
<dd>新メニューのご提供</dd>
<dt>2024年3月16日</dt>
<dd>お客様感謝祭開催!</dd>
<dt>2024年3月15日</dt>
<dd>春のワインフェア開催</dd>
<dt>2024年3月14日</dt>
<dd>ホワイトデー限定メニューのご提供</dd>
<dt>2024年3月10日</dt>
<dd>春の食材を使った特別コースのご提供</dd>
<dt>2024年3月09日</dt>
<dd>営業時間変更のお知らせ</dd>

配色のルール

配色には色々なルールがありますが、まずはこの3つを覚えましょう

1、コントラスに気を付ける

2、色数を抑える

3、トーンを合わせる


HSBを使った配色

photoshopではRGB以外にもHSBやLabといった数値でも色の調整が出来ます。特にHSBは配色時によく使うので是非覚えておきましょう。
HSBは色相(Hue)、彩度(Saturation)、明度(Brightness)の3つの値を調整していきます。

トーン(色調)を合わせる方法

トーン(色調)とは彩度と明度の2つの値を合わせた物です。なので上記の「トーンを合わせる」場合は彩度(Saturation)、明度(Lightness)の2つの値は動かさずに色相(Hue)を動かして色を決めていきます。




webnaut.jp



www.slideshare.net


hue360.herokuapp.com


配色を考えるのは非常に難しい作業ですが、今はキーワードでカラーパレットを生成してくれるAIなどが豊富にあるので、これらを使って作業を効率よく進めましょう



キーワードから配色を提案するColor Magic(日本語可)

colormagic.app

キーワードから配色を提案するHuemint(英語のみ)

aicolors.co



プロジェクトにあった配色を自動で提案してくれるツールHuemint

色の組み合わせを確認できるサンプルイメージが豊富。
huemint.com


クリックするだけのお手軽AIカラーツール Colormind

colormind.io

background-attachment

background-attachmentをfixedにすると簡単にパララックス(視差効果)を使ったスクロールが実装出来ます。
ただ、iOSはどういった理由か、この「background-attachment:fixed;」を頑なに対応させない為(ベンダープレフィックスを付けてもダメ)、iOSでは別の対応が必要になります。
今回はiOSではパララックス(視差効果)を使わずにシンプルに背景画像がスクロールしていく形で対応させます。


See the Pen
background-attachment:fixedでパララックス
by yachin29 (@yachin29)
on CodePen.

各ブラウザの対応


backgroundのショートハンド

background関連の指定は多いのでbackground-attachmentも含めてショートハンドでまとめてしまいましょう。

background: #FFF url() no-repeat center center/cover fixed;/* 背景色、背景画像、背景の位置、背景のサイズ、背景のスクロールの有無 */

iOSの対応

iOSSafariでは「background-attachment」は未対応のため、そのままでは表示が崩れてしまうので対応が必要です。ここでは「background-attachment:fixed」の値を「background-attachment:scroll」に変更するという非常にシンプルな方法で対応します。さらに高さを50vhほどに抑えておきます。

@media (max-width: 959px) {

.bg-1{
height: 50vh;
background: url() no-repeat center center/cover scroll;
}

}

今後のiOS

今後、iOSで「background-attachment」が対応されるのかは、解らないですが、AppleのDeveloper Forumsで「background-attachment」については以下のコメントで締められています。

Apple decided fixed background is not the vibe. That's all. Apple is god remember it


developer.apple.com

CODEPENを使って自身のコードを掲載させる



https://codepen.io/



CODEPENとは?
「CODEPEN」とは、HTML・CSS・JSなどのソースコードを保存・公開・共有できるWEBサービスです。他の人が作ったソースをその場で編集できたり、プレビューで確認出来、動作確認などにも使えて非常に便利です。ソースをブログやWEBサイトに埋め込むことも簡単にできます。
有料・無料アカウントがあり、無料アカウントは一部の機能が使えません。
ソースコードを保存・公開・共有できるサービスの為、画像は自身のサーバー等にアップロードする必要があります。(有料プランの場合、画像をアップロード出来るスペースが与えられます)
なので、WebGLCSSアニメーションなど、比較的リッチな動きを見せるものの掲載が多いです。
webのポートフォリオなどに使ってみるのも良いと思います。


cssプラグインを使ってハンバーガーボタンを作る

プラグインを使う事でハンバーガーメニューを簡単に作る事が出来ます。



jonsuh.com



アイコンの切り替えはjQueryでclass「is-active」をトグルさせるだけで良いので自身で記述してしまいましょう。


<p class="hamburger " id="ham-btn">
  <span class="hamburger-box">
    <span class="hamburger-inner"></span>
  </span>
</p>

サイト制作のワークフロー

webサイト制作におけるワークフローの一例

ヒアリング

クライアントとのヒアリングの時点で、方向性やサイトの目的、そしてサイトに盛り込むコンテンツなどを明確にします。また、その事をクライアントとしっかりと共有する事が大事です。その為にはしっかりとクライアントのいう事に耳を向け、クライアントの要望を言語化する必要があります。

サイト設計

ヒアリングであがったコンテンツの洗いだしを行い、これらをグルーピングしフローチャートサイトマップディレクションマップ)と呼ばれるページの遷移の画面に視覚化し、まとめます。

ペルソナの設定

「ペルソナ(persona)」とは、サービス・商品の典型的なユーザー像のことで、マーケティングにおいて活用される概念です。
実際にその人物が実在しているかのように、年齢、性別、居住地、職業、役職、年収、趣味、特技、価値観、家族構成、生い立ち、休日の過ごし方、ライフスタイル……などリアリティのある詳細な情報を設定していきます。


ferret-plus.com


ラフデザイン・ワイヤーフレームの作成

各ページの画面に盛り込む内容を検討し、まずは手書きのラフで良いので、全体のレイアウトなどを考え、次にIllustrator等のソフトを使って「ワイヤーフレーム」と呼ばれる線画に起こします。

ラフデザイン

カンプ制作

カンプとは「comprehensive layout」が省略されたもので、「comprehensive」には「包括的な」「総合的な」といった意味があります。カンプの段階でカラースキム(配色計画)・寸法をしっかりと考えながら図面に起こし、デザインやレイアウトも含めた全体像を作ることで完成品のイメージを把握出来るものを作成します。いわばwebサイトの設計図です。


https://blogs.adobe.com/japan/web-design-photoshop-cc-basics-artboard/blogs.adobe.com


スライス(アセット 書き出し)・コーディング

webサイトの設計図であるカンプを元に細かくパーツ別に分けて、コーディングをしてサイトを組み立てます。


動的プログラムの導入

プログラムを導入する意図を明確にし、ユーザビリティーの高いサイトを作るよう心がけましょう。

検証

仮サーバーにアップして、リンクやユーザービリティなどを検証します。



baigie.me


developer.apple.com

GoogleのBardを使ってサイトの要件定義を作成する

BardはGoogleが開発した大規模言語生成 AIです。大規模言語モデル(Large Language Models、LLM)とは、非常に巨大なデータセットディープラーニング技術を用いて構築された言語モデルです。

どういった事が出来るか本人に聞いてみました。

私の名前はBardです。Google AIによって開発された大規模な言語モデルです。テキストとコードの膨大なデータセットでトレーニングされており、テキストの生成、言語の翻訳、さまざまな種類のクリエイティブ コンテンツの作成、有益な方法で質問に答えることができます。

私はまだ開発中ですが、さまざまな種類のタスクを実行することを学びました。

あなたの指示に従い、思慮深くあなたの要求を完了するために最善を尽くします。
質問がオープンエンド、挑戦的、または奇妙であっても、包括的かつ有益な方法で回答するために私の知識を使用します。
詩、コード、台本、音楽作品、電子メール、手紙など、さまざまなクリエイティブなテキスト形式を生成します。すべての要件を満たすために最善を尽くします。
私はまだ学び、成長しており、今後も新しいことを学び続けます。

要件定義を作成

要件定義などを作成する上でLLMを効率よく使う事は今後必ず必要になってきます。

xtech.nikkei.com


Bardを使って決める事

  • お店の名前
  • お店のコンセプト
  • タグライン
  • リード文(100〜200文字程度)
  • よくある質問とその答え(3つ)
  • お知らせ(5日分)