【第2回】HTML/CSS/JS入門(1)

主にCSSとJavaScriptについての基本的な知識を学びます。

Homeブログ一覧【第2回】HTML/CSS/JS入門(1)

前回の復習

第1回の講習では、Webサイトがどのような仕組みで構成され表示されるのかを学びました。今回も、そのWebサイトを作るための基本的な技術であるHTML/CSS/JSについて学びます。

CSSを外部のファイルに書く

CSSはHTML内に書くこともできますが、外部のファイルに書くこともできます。実際に、前回作成したHTMLファイルを編集して、CSSを外部のファイルに書いてみましょう。

<!DOCTYPE html>
<html>
  <head>
    <title>Web研講義1</title>
    <style>
      h1 { 
        color: blue; 
      }
      span {
        color: red;
      }
      .hero {
        width: 700px;
      }
    </style>
  </head>
  <body>
    <img src="https://maximum.vc/images/hero.png" alt="Maximumのロゴ" class="hero">
    <h1>Web研究会</h1>
    <h2>活動内容</h2>
    <p>Web研究会は、Webに興味のある学生が集まって、Web技術の研究や開発を行う<span>プログラミングサークルMaximumの活動の一環</span>です。</p>
    <h2>Webの分野</h2>
    <ul>
      <li>フロントエンド</li>
      <li>バックエンド</li>
      <li>インフラ</li>
    </ul>
    <a href="https://maximum.vc">Maximumのサイトはこちら</a>
  </body>
</html>

まずは、index.htmlと同じディレクトリにstyle.cssというファイルを作成します。

.
├── index.html
└── style.css

作成したstyle.cssに、<style>タグ内に書いていたCSSをコピーします。

style.css
h1 { 
  color: blue; 
}
span {
  color: red;
}
.hero {
  width: 700px;
}

次に、index.html<style>タグ内のCSSを削除し、以下のように<link>タグを追加します。

index.html
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="./style.css">
    <title>Web研講義1</title>
  </head>
  <body>
    <img src="https://maximum.vc/images/hero.png" alt="Maximumのロゴ" class="hero">
    <h1>Web研究会</h1>
    <h2>活動内容</h2>
    <p>Web研究会は、Webに興味のある学生が集まって、Web技術の研究や開発を行う<span>プログラミングサークルMaximumの活動の一環</span>です。</p>
    <h2>Webの分野</h2>
    <ul>
      <li>フロントエンド</li>
      <li>バックエンド</li>
      <li>インフラ</li>
    </ul>
    <a href="https://maximum.vc">Maximumのサイトはこちら</a>
  </body>
</html>

ここでの<link>タグのhref(hypertext reference)属性にはCSSファイルのパスを指定し、rel(relationship)属性にはstylesheetを指定します。<link>タグは<head>タグ内に書くのが一般的です。

<link rel="stylesheet" href="style.css">

これで、CSSを外部のファイルに書くことができました。

Tip: <a>タグと<link>タグの違い

  • <a>タグはインライン要素として文章中にハイパーリンクを作るためのタグです。
  • <link>タグは直接Webページの見栄えに関係なく、外部ファイルを読み込むためのタグです。

CSSを書いてみよう

まずは、作業ディレクトリ(maximumフォルダ)の中のwebkenフォルダにlec-02というディレクトリを作成し、その中にindex.htmlstyle.cssを作成します。

maximum
└── webken
    └── lec-01
    |   └── ...
    └── lec-02
        └── index.html
        └── style.css

作成したindex.htmlに以下のHTMLを記述します。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="./style.css">
    <title>Web研講義2</title>
  </head>
  <body>
    <header class="header">
      <h2>サンプルサイト</h2>
    </header>
    <main class="main">
      <div class="hero">ヒーロー</div>
      <article class="article">
        <div class="contents">メイン</div>
        <div class="sidebar">サイドバー</div>
      </article>
    </main>
    <footer class="footer">
      <p>2024 Maximum Web研究会</p>
    </footer>
  </body>
</html>

レイアウトは様々ありますが、今回は例として下のようなレイアウトを作成します。 CSSレイアウトの例

style.cssを作成して、下の見た目になるようにCSSを書いてみましょう。 (正解は1つではありません。第1回で学んだことを生かしたり調べてみましょう) サンプルサイトのレイアウト

  • ヘッダー、フッターの色は#AFF4C6
  • ヒーローの色は#B3B3B3
  • メインの色は#FFC7C2
  • サイドバーの色は#BDE3FF

を指定してみましょう。(他の色でも大丈夫です)

レベル1

サンプルコード

前回の資料に載っているプロパティだけで書けます。

.header {
  background-color: #AFF4C6;
  width: 100%;
}

.hero {
  background-color: #B3B3B3;
}

.article {
  width: 100%;
}

.contents {
  background-color: #FFC7C2;
}

.sidebar {
  background-color: #BDE3FF;
}

.footer {
  background-color: #AFF4C6;
  width: 100%;
}

レベル2

サンプルコード
  • heightを使って高さを指定しました。
  • text-aligndisplayなどのプロパティを使いました。
.header {
  background-color: #AFF4C6;
  width: 100%;
}

.main {
  padding: 20px;
}

.hero {
  background-color: #B3B3B3;
  padding: 8px;
}

.article {
  display: flex;
  width: 100%;
}

.contents {
  width: 70%;
  height: 70vh;
  background-color: #FFC7C2;
  padding: 8px;
}

.sidebar {
  width: 30%;
  height: 70vh;
  background-color: #BDE3FF;
  padding: 8px;
}

.footer {
  background-color: #AFF4C6;
  text-align: center;
  width: 100%;
}

レベル3

サンプルコード
  • margin-leftmargin-bottomを使って余白を調整しました。
  • :rootを使って変数を定義しました。
  • *(ユニバーサルセレクター)を使ってページ全体(全ての要素)にスタイルを適用しました。
:root {
  --top-bottom-color: #AFF4C6;
}

* {
  margin: 0;
}

.header {
  background-color: var(--top-bottom-color);
  width: 100%;
}

.main {
  padding: 20px;
}

.hero {
  height: 200px;
  margin-bottom: 20px;
  background-color: #B3B3B3;
  padding: 8px;
}

.article {
  display: flex;
  width: 100%;
}

.contents {
  width: 70%;
  height: 70vh;
  background-color: #FFC7C2;
  padding: 8px;
}

.sidebar {
  width: 30%;
  height: 70vh;
  background-color: #BDE3FF;
  margin-left: 20px;
  padding: 8px;
}

.footer {
  background-color: var(--top-bottom-color);
  text-align: center;
  width: 100%;
}

プログラミング言語を学ぶ上での基本ルール

ちょっと余談ですが...

現在主流となっているプログラミング言語には、Java、JavaScript、C#、C++、PHPなどなどありますが、これらのプログラミング言語は「C言語」から派生しています。 つまり、起源が同じなので基本的な文法の構造は全て同じなので、1つ主流なプログラミング言語を習得すれば他のプログラミング言語も習得しやすくなります。

入門講習会でも学習したと思いますが、かる~く復習しておきましょう。

プログラムを処理をする順番

C言語やPython、JavaScriptなどの手続き型プログラミング言語は、基本的にプログラムを処理する順番は、1行ごとに上から下に処理されます。

console.log("こんにちは");
console.log("今日は4月29日です。");
console.log("天気は晴れです。");

詳しいことはわからなくても、プログラムが実行される順番は一目でわかりますね。

変数と代入

変数とは、データを格納するための箱のようなもので、変数には様々なデータを格納することができます。

let num = 10;

このように変数を宣言し、値を代入することができます。

命令文の終わりを伝える

JavaScriptやC++などのプログラムを書く際には、命令文の終わりに;をつけることが基本です。

// JS
let num = 5;
console.log(num);
// cpp
int num = 5;
cout << num << endl;

Pythonでは改行することで命令文の終わりを伝えることができます。

# Python
num = 5
print(num)

JavaScript

JavaScript(以降JS)とは、HTMLとCSSをとともにWebページを作るための言語で、ユーザーの操作に応じてサイト上の要素を動かしたり、変更したりすることができます。 HTMLやCSSは、Webページにテキストや画像を追加したり、色を付けたりするなどWebページ全体の装飾をするための言語であり、「マークアップ言語」と呼ばれます。 一方、JSは計算や条件分岐などの処理ができるプログラミング言語です。 例えば

  • ボタンを押したら画像を表示する
  • 検索機能やソート機能を実装する
  • 送信フォームの入力内容をチェックする

などの処理はHTML/CSSだけでは作ることができず、JSを組み合わせることで書くことができます。

基本文法を学ぼう

Web研ではJSを初めて学習する人もいるため、基本文法について簡単に紹介します。 入力が大変な部分もあるので、適宜コピー&ペーストしてください。

Web学習におけるコピペ

再度アナウンスしますが、Webでは文法よりも真似して慣れること・動作を理解することが大切です。 そのため、コードを模写する勉強はタイピングの練習としてはとても有効ですが、Webの勉強には不向きだと思います。 コピペをすることをためらう必要はなく、したものを少しいじったりして動作を理解すると良いと思います。

コンソールに出力する

JSをコンソールに出力してみましょう。 まずは、index.htmlに以下のコードを追加します。

<!DOCTYPE html>
<html>
  <head>
    <script src="./script.js"></script>
  </head>
</html>

script.jsindex.htmlと同じディレクトリに作成し、以下のコードを入力してください。

console.log('Hello World!');

index.htmlを開き、F12キーからコンソールログを開くとコンソールに Hello World! と表示されるはずです。 C++ではcout << "Hello World!" << endl;と書くのがおなじみですが、JSではconsole.log()を使います。

お馴染みの四則演算もできます

console.log(1 + 1); // 2
console.log(1 - 1); // 0
console.log(2 * 2); // 4
console.log(4 / 2); // 2
console.log(5 % 2); // 1

C言語ではint型同士の除算は小数点以下が切り捨てられますが、JSでは整数も小数として表されるため、除算では小数点以下も計算されます。

console.log(5 / 2); // 2.5

ちなみに0で割った時はInfinityと表示されます。

console.log(1 / 0); // Infinity

変数

変数宣言の方法はvar(variable)とletの2つありますが、基本的にはletを使います。

let a = 1;
let b = 2;
console.log(a + b); // 3
var a = 3;
var b = 4;
console.log(a + b); // 7

お気づきの方もいるかもしれませんが、JSには型宣言がありません。これは、JSが動的型付け言語だからです。Pythonなどと同じですね。 動的型付け言語とは、変数の型を宣言する必要がない言語のことです。 その代わり実行時に型を推論するので、実行が遅くなります。 コンパイル型言語が速いのは静的型付け言語だからです。

定数

変数と同じようにconst(constant)で定数を宣言できます。

const a = 1;
const b = 2;
console.log(a + b); // 3

a = 2; // エラー

定数なので、再代入はできません。aに2を代入しようとするとエラーになります。 基本は定数を使い、再代入が必要な場合に限って変数を使うようにしましょう。

条件分岐

比較演算

演算子意味
==等しい(キャストあり)
===厳密に等しい(キャストなし)
!=等しくない(キャストあり)
!==厳密に等しくない(キャストなし)
>より大きい
>=以上
<より小さい
<=以下
&&かつ
||または
!否定
console.log(1 == 1); // true
console.log(1 == '1'); // true
console.log(1 === '1'); // false
console.log(1 != 2); // true
console.log(1 !== '1'); // true
console.log(1 > 0); // true
console.log(1 >= 1); // true
console.log(1 < 2); // true
console.log(1 <= 1); // true
console.log(true && true); // true
console.log(true && false); // false
console.log(true || false); // true
console.log(false || false); // false
console.log(1 > 0 && 2 > 1); // true
console.log(1 < 0 || 2 > 1); // true
console.log(!false); // true

if文

const a = 1;
const b = 2;
if (a < b) {
  console.log('a < b');
} else if (a > b) {
  console.log('a > b');
} else {
  console.log('a = b');
}

switch文

const text = "Mon";

switch (text) {
  case "Sun":
    console.log("日曜日");
    break;
  case "Mon":
    console.log("月曜日");
    break;
  case "Tue":
    console.log("火曜日");
    break;
  case "Wed":
    console.log("水曜日");
    break;
  case "Thu":
    console.log("木曜日");
    break;
  case "Fri":
    console.log("金曜日");
    break;
  case "Sat":
    console.log("土曜日");
    break;
  default:
    console.log("曜日ではありません");
    break;
}

繰り返し

for (let i = 0; i < 10; i++) {
  console.log(i);
}

関数

従来の関数

function add(a, b) {
  return a + b;
}
console.log(add(1, 2)); // 3

アロー関数

const add = (a, b) => {
  return a + b;
}
console.log(add(1, 2)); // 3

従来の関数とアロー関数は同じことができますが、アロー関数の方が短く書けたり、簡潔だったりします。 厳密には違いがありますが、今のうちは気にしなくて大丈夫です。

早期リターン

const add = (a, b) => {
  if (a < 0 || b < 0) {
    return;
  }
  return a + b;
}
console.log(add(1, 2)); // 3
console.log(add(-1, 2)); // undefined

関数の中でreturnを使うと、その時点で関数の処理が終了し、その後ろの処理は実行されません。 これを早期リターンと言います。

本当は

const add = (a, b) => {
  if (a < 0 || b < 0) {
    return;
  } else {
    return a + b;
  }
}

と書かなきゃいけないところを、elseを省略して書けるので、短く書けます。 これが綺麗なコードを書く時の基本になりますので、覚えておきましょう。

※この技術はどの言語でも使えます。競プロでもよく使います。 特にオブジェクト指向言語(JavaやC#など)では必須な表現として紹介されることが多いです。

配列

const array = [1, 2, 3, 4, 5];
console.log(array[0]); // 1
console.log(array[1]); // 2
console.log(array[2]); // 3

console.log(array) // [1, 2, 3, 4, 5]

配列操作

JSで繰り返し処理を行う場合、for文を使うことはほとんどありません。 その代わりに、配列操作を行います。 代表的な高階関数8個とその他メソッドを覚えておきましょう。(ほかにもありますが、とりあえずこれだけ覚えておけば大丈夫です)

全部覚える必要はありません、早見表を置いておくので、必要なときに見てください。

関数名・メソッド名説明出力例
map各要素を加工して新しい配列を作成する2倍する [1, 2, 3, 4, 5] -> [2, 4, 6, 8, 10]
forEach各要素に対して関数を実行する一つずつ表示する [1, 2, 3, 4, 5] -> 1, 2, 3, 4, 5
filter条件に当てはまる要素だけを新しい配列にして作成する偶数だけ取り出す [1, 2, 3, 4, 5] -> [2, 4]
find条件に当てはまる要素を最初の一つだけ取り出す偶数を一つだけ取り出す [1, 2, 3, 4, 5] -> 2
reduce各要素をどんどん加工して一つの値にする合計を求める [1, 2, 3, 4, 5] -> 15
some一つでも条件に当てはまる要素があるか偶数があるか [1, 2, 3, 4, 5] -> true
everyすべての要素が条件に当てはまるか偶数だけか [1, 2, 3, 4, 5] -> false
sort配列を並び替える降順に並び替える [1, 2, 3, 4, 5] -> [5, 4, 3, 2, 1]
includes配列に指定した要素が含まれているか3が含まれているか [1, 2, 3, 4, 5] -> true
indexOf配列に指定した要素が何番目にあるか3は何番目か [1, 2, 3, 4, 5] -> 2
join配列を指定した文字で結合する,で結合する [1, 2, 3, 4, 5] -> 1,2,3,4,5
split文字列を指定した文字で分割する,で分割する 1,2,3,4,5 -> [1, 2, 3, 4, 5]
slice配列の一部を取り出す2番目から4番目まで取り出す [1, 2, 3, 4, 5] -> [2, 3, 4]
length配列の要素数を取得する[1, 2, 3, 4, 5] -> 5

map

mapはその配列の要素一つ一つを加工して、新しい配列を作成します。

const array = [1, 2, 3, 4, 5];
// すべての要素を2倍する
const doubledArray = array.map((value) => {
  return value * 2;
});

console.log(doubledArray); // [2, 4, 6, 8, 10]

for文でいちいちindexを指定して要素を取り出すのは面倒なので、mapを使います。 mapは配列の要素を一つずつ取り出して、関数を実行します。 その結果を配列にして返します。

forEach

forEachはその配列の要素一つ一つに対して、関数を実行します。

const array = [1, 2, 3, 4, 5];
const log = (value) => {
  console.log("value: " + value);
}

array.forEach(log); // value: 1, value: 2, value: 3, value: 4, value: 5

mapと違って、forEachは新しい配列を作成しません。 その代わり各要素に対して関数を実行します。 今回はlogという関数を作成して、それをforEachに渡しています。

filter

filterはその配列の要素一つ一つに対して、関数を実行し、その結果がtrueの要素だけを取り出して、新しい配列を作成します。

const array = [1, 2, 3, 4, 5];
const isEven = (value) => {
  return value % 2 === 0;
}
const isOdd = (value) => {
  return value % 2 === 1;
}

const evenArray = array.filter(isEven);
const oddArray = array.filter(isOdd);
console.log(evenArray); // [2, 4]
console.log(oddArray); // [1, 3, 5]

reduce

reduceはその配列の要素一つ一つに対して、関数を実行し、その結果を次の要素に渡していきます。 最終的には一つの値を返します。

const array = [1, 2, 3, 4, 5];
const sum = (a, b) => {
  return a + b;
}

const result = array.reduce(sum);
console.log(result); // 15

find

findはその配列の要素一つ一つに対して、関数を実行し、その結果がtrueになった最初の要素を返します。

const array = [1, 2, 3, 4, 5];
const isEven = (value) => {
  return value % 2 === 0;
}

const result = array.find(isEven);
console.log(result); // 2

filterと違って、findは最初に見つかった要素だけを返します。なので今回はindex0から線形探索をして初めて見つかった値2を返します。

some

someはその配列の要素一つ一つに対して、関数を実行し、その結果がtrueになった要素が一つでもあればtrueを返します。

const array = [1, 2, 3, 4, 5];
const isEven = (value) => {
  return value % 2 === 0;
}

const result = array.some(isEven);
console.log(result); // true

every

everyはその配列の要素一つ一つに対して、関数を実行し、その結果がtrueになった要素がすべてtrueならばtrueを返します。

const array = [1, 2, 3, 4, 5];
const isEven = (value) => {
  return value % 2 === 0;
}

const result = array.every(isEven);
console.log(result); // false

sort

sortはその配列の要素一つ一つに対して、関数を実行し、その結果を元にソートします。

const array = [1, 2, 3, 4, 5];
const compare = (a, b) => {
  if (a < b) {
    return 1;
  } else if (a > b) {
    return -1;
  } else {
    return 0;
  }
}

array.sort(compare);
console.log(array); // [5, 4, 3, 2, 1]

配列arrayconstなのに再代入できるの?と思うかもしれませんが、 constは再代入できないだけで、配列の内部状態を変更することはできます。 簡単に言えば、=による変更ができないということです。

compare関数はabを比較して、aが大きければ1bが大きければ-1、同じなら0を返します。 sortは負なら要素を入れ替え、0ならそのまま、正なら要素を入れ替えないという3値論理を使ってソートを行います。

includes

includesはその配列の要素一つ一つに対して、引数に指定した値と同じかどうかを調べ、一つでも同じ値があればtrueを返します。

const array = [1, 2, 3, 4, 5];

const result = array.includes(3);
console.log(result); // true
const result2 = array.includes(6);
console.log(result2); // false

indexOf

indexOfはその配列の要素一つ一つに対して、引数に指定した値と同じかどうかを調べ、一つでも同じ値があればその要素のindexを返します。

const array = [1, 2, 3, 4, 5];

const result = array.indexOf(3);
console.log(result); // 2
const result2 = array.indexOf(6);
console.log(result2); // -1

join

joinはその配列の要素一つ一つを文字列に変換し、引数に指定した文字列で結合します。

const array = [1, 2, 3, 4, 5];

const result = array.join('-');
console.log(result); // 1-2-3-4-5

split

splitは引数に指定した文字列で配列を分割します。

const text = '1-2-3-4-5';

const result = text.split('-');
console.log(result); // ['1', '2', '3', '4', '5']

slice

sliceは引数に指定したindexから、引数に指定したindexまでの要素を取り出します。 sliceは左閉右開の半開区間で指定します。 例えば、slice(1, 3)とすると、indexが[1, 3)の要素を取り出します。

const array = [1, 2, 3, 4, 5];

const result = array.slice(1, 3); // indexが1以上3未満の要素を取り出す
console.log(result); // [2, 3]

length

lengthはその配列の要素の数を返します。

const array = [1, 2, 3, 4, 5];

const result = array.length;
console.log(result); // 5

まとめ

今回の講義では、CSSの練習とJavaScriptの基本文法について学習しました。 JavaScriptの文法は慣れるまでは難しいかもしれませんが、無理に覚えようとせずに使っていくうちに読める/書けるようになると思います。 次回は、JavaScriptを使ってWebページを動的に操作する方法について学習します。