前回、投票ページのHTMLを作りました。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>投票ページ</title> </head> <body> <header><!-- 後ほどJavaScriptで共通ページを引っ張ってくる--> <h1>投票ページ</h1> </header> <main class="vote-main"> <table> <!-- テーブル--> <thead><!-- 項目を書く行--> <tr><!-- 以下のものを一行に収める--> <th>順位</th><!-- 内容(値)--> <th>候補者</th> <th>投票数</th> <th>投票ボタン</th> </tr> </thead> <tbody id="candidate-list"> <!-- ここに行が追加されていく--> </tbody> </table> </main> </body> </html>
これを整理するためにCSSを書いていきます。
で、CSSを進めていく上で必要なクラスやIDなどを付け足していきます。
その際はコメントアウトで付け足した部分をメモしていきます。
HTMLはトップページと投票ページを分けましたが、CSSは今のところは特に分ける意味もないので、トップページを書いたものを使います。
body { font-size: 1rem; font-family: sans-serif; margin: 0; padding: 0; } header { position: relative; background-color: #fff; padding: 1rem; display: flex; justify-content: space-between; align-items: center; } nav { position: absolute; /*ヘッダーを基準に書いていく*/ display: none; /*最初はメニューが見えないようにしておく*/ &.show{ display: block; /* show クラスがついたら表示*/ } top: 100%; /*ヘッダーの下に配置*/ right: 0; /* 右端はヘッダーに合わせる*/ ul { list-style: none;/* マーカーを消す*/ padding: 0; /* ul の内側の余白を消す*/ li { margin-bottom: 0.5rem; a { /* リンクの表示の扱い*/ display: block; /* li 全体をクリック可能に*/ padding: 0.5rem 1rem; /* 内側の余白 */ text-decoration: none; /* リンクの下線を消す*/ color: #333; /* ダークグレー*/ &:hover { /* ホバーしたときの扱い*/ background-color: #f0f0f0; /* ホバー時の色 */ } } } } }
まずmainのレイアウトや見た目を整えていきます。
main
トップページのmainとこんがらがってはいけないので、HTMLの方にクラスをつけて<main class="vote-main"><!-- 投票用のメイン-->にします。
これでCSSを書いていきます。
.vote-main { width: 100%; padding: 1rem; box-sizing: border-box;/*paddingなども含めて幅を計算する*/ }
次にtableですね。
table
テーブルに関してはCSSでもJavaScriptでもほぼ確実に制御することになるので、こっちにもクラスを付けておきます。
クラス名は<table class="vote-table"> <!-- テーブル-->でいいですね。
では書いていきます。
.vote-table { width: 100%; border-collapse: collapse; /*セルの境界線を重ねる*/ margin-bottom: 1rem; th, td { border: 1px solid #ccc; /*薄いグレーの境界線*/ padding: 0.5rem; text-align: left; } th { background-color: #f9f9f9; /*薄いグレーの背景色*/ } }
まあこんな感じです。
thは項目(見出し)のセルを表し、tdはデータ(値)のセルを表します。
現時点ではテーブルといっても一行だけで、データではなく項目だけを表示したいのでtdは要らないのですが、今後JavaScriptでデータを追加していくので、ここは記載したままにしておきます。
次の問題は項目ごとの横幅です。
すべてを均等にするのではなく、順位、候補者名、投票数、投票ボタン、という項目なので、それに適した長さにする必要があります。
まずはテーブルレイアウトをfixedにして固定します。
で、要素の一つ下(子)を制御するのでnth-childを使い、長さの割合を一つずつ決めていきます。
nthとはn-th、つまりn番目を意味します。
thの中の何番目をどれくらいの割合の長さにするかを決めるので、以下のように書きます。
th { background-color: #f9f9f9; /*薄いグレーの背景色*/ &:nth-child(1) { width: 10%; /*順位の幅*/ } &:nth-child(2) { width: 45%; /*候補者の幅*/ } &:nth-child(3) { width: 20%; /*投票数の幅*/ } &:nth-child(4) { width: 25%; /*投票ボタンの幅*/ } }
vote-tableのところでレイアウトをfixedにするのも忘れないように。
.vote-table { width: 100%; border-collapse: collapse; /*セルの境界線を重ねる*/ margin-bottom: 1rem; table-layout: fixed; /*項目の横幅を固定する*/
これで以下のようなレイアウトになります。

実際の順位やら候補者やらを表示する箇所はJavaScriptで制御することになります。
投票ボタンを押したら数字を投票数を1増やし、それを順位順に並べる、といった制御です。
で、今思いついたんですけど、候補者を増やすフォームも必要ですね。
入力フォームに候補者名を書いて、送信ボタンを押せば候補者の名前が反映されてテーブルの行が増える、というような。
ただこれ、投票とは役割が違って「候補者を追加する」ことが目的ですから、このページに作るのは違うように思います。
なので候補者追加のページはまた別に作成します。
次回はそれを作っていくことにします。