あなたがWebサイトを開設してゲームを配信したり、情報発信したりしようとするときに、何を使えば良いでしょうか?

正解は、テキストエディタです。テキストエディタと言われてもぴんとこないかもしれませんが、要はメモ帳です。テキスト、つまり文字を編集できるソフトがあれば、Webページは作成することができます。

実はWebページとは、文字の集合になっています。実際に、shigenoki.comのトップページの表示内容を決めるテキストは以下のようになっています。(実際のページは装飾用のCSSや動きのためのJavaScriptも含みますが、ここではまず「骨格」だけを示します。)

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>ShigeNoKi</title>
    <meta name="description" content="ShigeNoKi(しげのき・シゲノキ)は5人チームによるWeb開発ユニットです。">
    <meta name="author" content="ShigeNoKi">
    <link rel="canonical" href="https://shigenoki.com/">

    <!-- OGP / Twitter Card(SNSでシェアされた時の表示) -->
    <meta property="og:type" content="website">
    <meta property="og:title" content="ShigeNoKi">
    <meta property="og:url" content="https://shigenoki.com/">
    <meta name="twitter:card" content="summary_large_image">

    <!-- ファビコン -->
    <link rel="icon" href="/favicon.ico">
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">

    <!-- スタイルシート -->
    <link rel="stylesheet" href="/styles/base.css">
  </head>
  <body>
    <div id="cosmic-background"></div>

    <header>
      <div id="cosmic-tree-container"></div>
      <nav class="nav">
        <a href="/" class="brand">
          <img src="/favicon.svg" alt="" class="brand-logo" width="32" height="32">
          <span>ShigeNoKi</span>
        </a>
        <div class="nav-links">
          <a href="/" class="nav-link">トップ</a>
          <a href="/#apps" class="nav-link">アプリ一覧</a>
          <a href="/#members" class="nav-link">メンバー紹介</a>
          <a href="/about" class="nav-link">運営者情報</a>
        </div>
      </nav>
    </header>

    <main>
      <!-- アプリのプレビュー -->
      <section class="app-preview">
        <div class="preview-container">
          <div class="preview-track" id="previewTrack">
            <div class="preview-slide" data-index="0">
              <div class="preview-content">
                <img src="/apps/halpal/images/10.webp" alt="HΛLPΛLのプレビュー">
                <div class="preview-info">
                  <h3>HΛLPΛL</h3>
                  <p>ターン制カードゲーム。WebSocketでリアルタイム対戦。</p>
                </div>
              </div>
            </div>
          </div>
          <button class="preview-nav preview-prev" id="prevSlide" aria-label="前のプレビューを表示">←</button>
          <button class="preview-nav preview-next" id="nextSlide" aria-label="次のプレビューを表示">→</button>
          <div class="preview-indicators" id="previewIndicators">
            <button class="preview-indicator" data-index="0" aria-label="1番目のプレビューを表示"></button>
          </div>
        </div>
      </section>

      <!-- 見出し -->
      <section class="hero" aria-labelledby="main-heading">
        <div class="content-wrap">
          <h1 id="main-heading">ShigeNoKi</h1>
          <p>5人の小規模チームによるWebアプリ開発ユニットです。<br>
             ここではチーム紹介とプロダクト一覧を掲載しています。</p>
        </div>
      </section>

      <!-- お知らせ -->
      <section class="news">
        <div class="content-wrap">
          <h2>お知らせ</h2>
          <div class="news-list">
            <article class="news-item">
              <time datetime="2025-11-01">2025/11/01</time>
              <h3>HΛLPΛLを本公開しました</h3>
              <p>Webアプリ「HΛLPΛL-ハルパル-」を本公開しました!</p>
            </article>
            <article class="news-item">
              <time datetime="2025-10-01">2025/10/01</time>
              <h3>HΛLPΛLのベータ版を公開しました</h3>
              <p>Chaos-cardとしていたアプリを「HΛLPΛL-ハルパル-」として公開しました!</p>
            </article>
            <article class="news-item">
              <time datetime="2025-09-25">2025/09/25</time>
              <h3>ウェブサイトを公開しました</h3>
              <p>ShigeNoKiのウェブサイトを公開しました。</p>
            </article>
          </div>
        </div>
      </section>

      <!-- アプリ一覧 -->
      <section id="apps" aria-labelledby="apps-heading">
        <div class="content-wrap">
          <h2 id="apps-heading">Apps</h2>
          <ul class="app-grid" role="list">
            <li class="app-card">
              <div class="app-card__preview">
                <picture>
                  <source srcset="/apps/halpal/images/10.webp" type="image/webp">
                  <img src="/apps/halpal/images/10.webp" alt="HΛLPΛLのプレビュー" loading="lazy" decoding="async">
                </picture>
              </div>
              <div class="app-card__content">
                <h3><a href="https://halpal.shigenoki.com">HΛLPΛL</a></h3>
                <p>ターン制カードゲーム。WebSocketでリアルタイム対戦。</p>
                <div class="badges">
                  <span class="badge">game</span><span class="badge">websocket</span>
                </div>
                <div class="links">
                  <a href="/apps/halpal/index.html">説明ページ</a>
                  <a href="https://halpal.shigenoki.com" target="_blank" rel="noopener">アプリを開く ↗</a>
                </div>
              </div>
            </li>
          </ul>
        </div>
      </section>

      <!-- メンバー紹介 -->
      <section id="members" aria-labelledby="members-heading">
        <div class="content-wrap">
          <h2 id="members-heading">Members</h2>
          <div class="member-grid" role="list">
            <article class="member-card" role="listitem">
              <div class="member-card__avatar">
                <div class="avatar-placeholder" aria-hidden="true">S</div>
              </div>
              <div class="member-card__content">
                <h3>shintaro</h3>
                <div class="member-role">PM</div>
                <p>プロジェクトの統括とマネジメントを担当</p>
              </div>
            </article>
            <!-- 以下、shige / k / kenta / tikuwa も同じ形のカードが続きます -->
          </div>
        </div>
      </section>

      <!-- お問い合わせ -->
      <section id="contact" aria-labelledby="contact-heading">
        <div class="content-wrap">
          <h2 id="contact-heading">お問い合わせ</h2>
          <div class="contact-content">
            <p>ご質問やお問い合わせがございましたら、下記のフォームよりお気軽にご連絡ください。</p>
            <div class="contact-link">
              <a href="https://forms.gle/6uXvhMgtQeWsyS5n8" target="_blank" rel="noopener" class="contact-button">
                Googleフォームでお問い合わせ
              </a>
            </div>
          </div>
        </div>
      </section>
    </main>

    <footer>
      <div class="container">
        2026 ShigeNoKi<br>
        <div class="footer-contact">
          お問い合わせ:<a href="https://forms.gle/6uXvhMgtQeWsyS5n8" target="_blank" rel="noopener">Googleフォーム</a>
        </div>
        <div class="footer-legal">
          <a href="/about">運営者情報</a> |
          <a href="/legal/terms">利用規約</a> |
          <a href="/legal/privacy">プライバシーポリシー</a>
        </div>
      </div>
    </footer>
  </body>
</html>

これは、右クリック→検証(あるいは開発者ツール)からも同じようなものが見られます。

ファイルを表示する

ここで少し脱線をします。といっても、これからの話をするために重要な、簡単な確認のようなものです。

Webページがあなたのパソコンに表示されるとき、公開元から何があなたのパソコンに送られているのでしょうか? 正解は、HTMLファイルです。これまでの話からすると当たり前ですね。「<ファイル名>.html」のようなものが公開元からGoogle Chromeなどのブラウザーに届いて表示されています。

つまりブラウザーは、ファイルを表示させるための装置といえるわけです。もちろん、適切なWebサイトを探す検索というのも大事な機能ですが、根っこの部分では、公開元のサーバーからHTMLファイルを受け取って表示しているわけです。

公開元サーバーからブラウザーへHTMLファイルが送られ、ブラウザーがWebページとして表示するまでの流れ

ちなみに、ブラウザーの検索窓に

~/

と打ち込むと、自分のパソコンの中のフォルダを見ることができます。実際にPDF等を開いてみると、正しく表示されるはずです。ブラウザーがファイルを表示させるためのものだというのが、体感できると思います。

HTML

上記に示したソースコードは、HTML(ハイパーテキスト・マークアップ・ランゲージ)と呼ばれるものです。Webページで表示される内容をテキストで示します。HTMLでは、何を表現するかを、タグというものを使用して表現します。

例えば、以下のようにタグを使用します。

<h1>タイトル</h1>

上記はh1タグという、見出しのときに使用するタグです。また、画像を表示したいとき、リンクを表示したいときは以下のようになります。

<!-- 画像 -->
<img src="<画像のパス>">

<!-- リンク -->
<a href="<飛ばしたいリンク>">この文字列をクリックするとリンクに飛びます</a>

パスについての詳しい説明は:「パスを通すって何!?」

それでは、冒頭に示したHTMLを使って、実際に手元で表示させてみましょう。Finder(Mac)で「index.html」を作成し、冒頭のHTMLを貼り付けます。そのindex.htmlを右クリックして「パスをコピー」を押し、Google Chromeなどのブラウザーの検索窓に貼り付けてください。

どうでしょう? あまりにも殺風景なものだと思います。HTMLは何を表示するかを示すものですが、どのように表示するかまでは示しません。どのように表示するかは、CSSというもので記述されます。

HTMLについての詳しい説明は:「HTMLの書き方」

CSS

CSSとは、HTMLで決められた表示内容に対して、それぞれの内容をどのように表示するかを示したものです。これがHTMLと合わさることで、見た目が伴ったWebページが作成されます。

実際に、このサイトのトップページのCSS(ヘッダーと全体の土台部分)は以下のようになっています。

:root {
  --w: 1080px;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  overflow-x: hidden;
  background: #050519;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  line-height: 1.6;
  color: #111;
}

/* ヘッダー(上部に固定される) */
header {
  position: sticky;
  top: 0;
  z-index: 100;
  border-bottom: 1px solid rgba(229, 231, 235, 0.3);
  overflow: hidden;
  background: rgba(20, 30, 60, 0.3);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 64px;
  padding: 0 32px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  color: #fff;
  text-decoration: none;
}
.brand:hover {
  opacity: 0.8;
}

.brand-logo {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: linear-gradient(135deg, #2563eb, #4338ca);
}

.nav-links {
  display: flex;
  gap: 24px;
}

.nav-link {
  color: rgba(255, 255, 255, 0.8);
  text-decoration: none;
  font-size: 0.9rem;
}
.nav-link:hover {
  color: #fff;
}

/* 画面が狭いとき(スマホ)はメニューの間隔を詰める */
@media (max-width: 640px) {
  .nav-links {
    gap: 16px;
  }
}

main {
  width: 100%;
  margin: 0;
  padding: 0;
  background: #fff;
  position: relative;
  z-index: 1;
}

footer {
  width: 100%;
  color: #6b7280;
  font-size: 14px;
  background: #fff;
  position: relative;
  z-index: 1;
}
footer .container {
  max-width: var(--w);
  margin: 0 auto;
  padding: 24px 32px 40px;
}

/* 背景の星空アニメーションを描く場所 */
#cosmic-background {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -100;
  background: linear-gradient(to bottom, #141e3c, #050519);
}

HTMLのように実際に試したい方もいるでしょうが、これをindex.cssという別のファイルに保存しただけでは、HTML側にどこのCSSを読み込むかという指定(パス)がないので、見た目は変わりません。

パスについての詳しい説明は:「パスを通すって何!?」

今回は勉強なので、雑にCSSが適用されたHTMLを見られるように、index.htmlに直接CSSの内容を書いてしまいましょう。先ほど作ったindex.htmlの <head> の中に、次のように <style> タグを追加します。<style> の中身には、上の「CSS」の節で示した内容をそのまま貼り付けてください。

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>ShigeNoKi</title>

  <!-- 本来は別ファイル(/styles/base.css)にする CSS を、勉強用に直接ここへ書く -->
  <style>
    /* ↑「CSS」の節で示した内容をここに貼り付ける */
  </style>
</head>

<body> はそのまま、冒頭のHTMLのものを使います。

どうでしょう? イケてる感じになりました?

眺めていると、実際のshigenoki.comとは少し違うことに気づくと思います。もちろん、画像のせいもあります。今は画像の表示を指定しても、表示する画像が皆さんのPCに入っていませんからね。

それ以外でも、画面上部のアニメーションがない等の違いがありますよね。これは、CSSがHTMLを装飾する役割は担いますが、動きがあるものまでは担当しないからです。動きを必要とするものは、JavaScriptというものが担当します。

JavaScript

JavaScriptとは、HTMLで決められた表示内容に対して、どのような動作をするかを示したものです。例えば、ボタンを押すとポップアップが消えるなどはJavaScriptの担当範囲です。shigenoki.comのトップページの画面上部のアニメーションもJavaScriptが担当しています。

JavaScriptがあるおかげで、Webページは止まっているものを見るだけでなく、物が動いたり、ボタンを触ったりすることができるわけです。

JavaScriptもHTMLファイルの中に直接書くことができるので、index.htmlの中に書いてしまいましょう。さすがに、JavaScriptの全てをここで公開してしまうのはセキュリティ上危ないので、アニメーションに関わる部分だけにします。(どのように内部が動いているのかを明かしてしまうことになるので、ご了承ください。)

</body> の直前に、次の <script> を追加してみましょう。背景の星空アニメーションを描く部分です。

<script type="module">
// 描画先のキャンバスを用意する
const container = document.getElementById("cosmic-background");
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
container.appendChild(canvas);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

function random(min, max) {
  return Math.random() * (max - min) + min;
}

// 星をたくさん作る(x, y, z の位置と、明るさ・大きさ・またたきの位相を持つ)
const stars = [];
for (let i = 0; i < 150; i++) {
  stars.push({
    x: random(-1200, 1200),
    y: random(-800, 800),
    z: random(200, 1500),
    brightness: random(0.2, 1),
    size: random(1, 4),
    twinkle: random(0, Math.PI * 2),
  });
}

// 毎フレーム描き直すことで「動き」になる
function draw() {
  // 背景を夜空のグラデーションで塗りつぶす
  const grad = ctx.createLinearGradient(0, 0, 0, canvas.height);
  grad.addColorStop(0, "rgb(20, 30, 60)");
  grad.addColorStop(1, "rgb(5, 5, 25)");
  ctx.fillStyle = grad;
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  for (const star of stars) {
    star.twinkle += 0.01;
    const flicker = Math.sin(star.twinkle) * 0.4 + 0.6;   // またたき
    const sx = canvas.width / 2 + (star.x / star.z) * 400;
    const sy = canvas.height / 2 + (star.y / star.z) * 400;
    const alpha = star.brightness * flicker * (1 - star.z / 1500);

    // 星を1つ描く(z が小さい=手前ほど大きく見える)
    ctx.fillStyle = `rgba(255, 255, 255, ${alpha})`;
    ctx.beginPath();
    ctx.arc(sx, sy, Math.max(0.5, (star.size / star.z) * 1200), 0, Math.PI * 2);
    ctx.fill();

    // 少しずつ手前に近づけ、近づき切ったら奥へ戻す(無限に流れて見える)
    star.z -= 0.8;
    if (star.z <= 0) star.z = random(1200, 1500);
  }

  requestAnimationFrame(draw);
}

draw();
</script>

どうでしょうか? これで、shigenoki.comのトップページと同じになったはずです。

このようにして、Webサイトは表示されています。実際には、HTML、CSS、JavaScriptは別々のファイルに分けられて、画像や音声ファイル等と一緒に公開元のサーバーから送られ、ブラウザーによって表示されています。

これが、Webページの表示までの仕組みとなります。お疲れ様でした。