- 投稿日:2019-11-29T21:41:41+09:00
【ポケモン】ゼロからはじめるダメージ計算ツールづくり【第1回:プロトタイプ編】
まえがき
ダイマックスちょーかっこよかった!
ポケモンシリーズの第8世代「ソード・シールド」が発売されました。
全作品プレイしている僕は当然のごとく今作も買いました。
メガシンカもZわざもないなんて…とバカにしていましたが、ダイマックスちょーかっこよかったです。
殿堂入りするまでノンストップでテンションあがりました。さて、殿堂入りまでがチュートリアルといわれるポケモンシリーズですが、
僕もレート対戦がんばりたいと思っています。
そんななかで発生するのがこんな状況だと思います。
この相手にこのわざ撃って倒せるのか??
倒せないなら交代or別のわざ撃ったほうがいいなぁ~
具体的なダメージが分かれば戦略がたてられるのに…
こんなとき、使いたくなるのが「ダメージ計算ツール」ですよね。
でも、僕みたいな初心者からすると、いちいちステータス打ち込んでわざ打ち込んで…って
ダメージ計算するの、対戦中にやるには億劫だし慣れてないツールだと時間も足りないんですよね。実際の対戦画面みたいに、わざのボタン押したらダメージ計算してくれるツールがあったらいいのにな~
と思いました。…
よし!つくろう!目標
- レート対戦(今作はランクバトル)初心者でも使いやすいダメージ計算ツールをゼロからつくること
- このツールで計算した結果が視覚的にわかりやすいこと
- エンジニアとしての知識・技術を身につけること
- SEとして名乗るのに具体的に見せることができる成果物をつくること
- このツールを使ってランクバトルに勝つこと
ほしい仕様
- 攻撃側、防御側のポケモンのステータスが計算できること
- 実際のバトルの状況に沿ってダメージ計算ができること
- 自分の使うポケモン・パーティー、流行っているポケモンの型が登録でき、なるべく少ない手順でそれが呼び出せること
- わざボタンを押すとダメージ計算の結果が表示されること
- ダメージ計算の結果が相手ポケモンのHPバーで表示されること(乱数による幅を含む)
使う技術、環境
HTML,JavaScript,CSS
Python(いったんやめた)いままでプログラミングでつくったことがあるものは、PythonでExcelファイルを操作して業務効率化を図るコンソールアプリだけだったので、GUIのあるものをつくるのはこれがほぼはじめてです。
Python大好きエンジニアなので、はじめはPythonでつくろうと思っていたのですが、
- PythonのGUIライブラリよくわかんない(tkinterとか)
- 最近ポートフォリオサイトをgithub.ioでつくったのでHTMLに慣れてた
- ダメージ計算だけだったらとりあえずJavaScriptでもつくれそう
の理由でいったんHTML,JavaScriptをベースにプロトタイプをつくることにしました。
PythonをベースにHTML,CSSでGUIアプリをつくることができるEelというライブラリも試してみましたが、途中で3に気づき、複雑になってしまうことを避けたかったので、今回はHTML,JavaScriptを勉強しながらつくってみることにしました。今回の進捗
数値を直接入力して使うタイプのダメージ計算ツールを避けるためにつくるのですが、まずはステータス計算、ダメージ計算の仕組みなども理解しながらつくる必要があると思ったので、よくあるシンプルなダメージ計算ツールを作成することにしました。
ここまでの成果物
HTMLソース
JavaScriptソース/* 味方側 */ function hcalc(){ let hbs =Number(document.getElementById("hbs").value); let hiv =Number(document.getElementById("hiv").value); let hev =Number(document.getElementById("hev").value); let hresult = Math.floor((hbs+hiv/2+hev/8+60)) document.getElementById("hresult").innerHTML = hresult; } function acalc(){ let abs =Number(document.getElementById("abs").value); let aiv =Number(document.getElementById("aiv").value); let aev =Number(document.getElementById("aev").value); let anc =Number(document.getElementById("anc").value); aresult = Math.floor((abs+aiv/2+aev/8+5)*anc) document.getElementById("aresult").innerHTML = aresult; document.getElementById("adisp").innerHTML = aresult; } function bcalc(){ let bbs =Number(document.getElementById("bbs").value); let biv =Number(document.getElementById("biv").value); let bev =Number(document.getElementById("bev").value); let bnc =Number(document.getElementById("bnc").value); let bresult = Math.floor((bbs+biv/2+bev/8+5)*bnc) document.getElementById("bresult").innerHTML = bresult; } function ccalc(){ let cbs =Number(document.getElementById("cbs").value); let civ =Number(document.getElementById("civ").value); let cev =Number(document.getElementById("cev").value); let cnc =Number(document.getElementById("cnc").value); cresult = Math.floor((cbs+civ/2+cev/8+5)*cnc) document.getElementById("cresult").innerHTML = cresult; document.getElementById("cdisp").innerHTML = cresult; } function dcalc(){ let dbs =Number(document.getElementById("dbs").value); let div =Number(document.getElementById("div").value); let dev =Number(document.getElementById("dev").value); let dnc =Number(document.getElementById("dnc").value); let dresult = Math.floor((dbs+div/2+dev/8+5)*dnc) document.getElementById("dresult").innerHTML = dresult; } function scalc(){ let sbs =Number(document.getElementById("sbs").value); let siv =Number(document.getElementById("siv").value); let sev =Number(document.getElementById("sev").value); let snc =Number(document.getElementById("snc").value); let sresult = Math.floor((sbs+siv/2+sev/8+5)*snc) document.getElementById("sresult").innerHTML = sresult; } /* 相手側 */ function ehcalc(){ let ehbs =Number(document.getElementById("ehbs").value); let ehiv =Number(document.getElementById("ehiv").value); let ehev =Number(document.getElementById("ehev").value); ehresult = Math.floor((ehbs+ehiv/2+ehev/8+60)) document.getElementById("ehresult").innerHTML = ehresult; document.getElementById("ehdisp").innerHTML = ehresult; } function eacalc(){ let eabs =Number(document.getElementById("eabs").value); let eaiv =Number(document.getElementById("eaiv").value); let eaev =Number(document.getElementById("eaev").value); let eanc =Number(document.getElementById("eanc").value); let earesult = Math.floor((eabs+eaiv/2+eaev/8+5)*eanc) document.getElementById("earesult").innerHTML = earesult; } function ebcalc(){ let ebbs =Number(document.getElementById("ebbs").value); let ebiv =Number(document.getElementById("ebiv").value); let ebev =Number(document.getElementById("ebev").value); let ebnc =Number(document.getElementById("ebnc").value); ebresult = Math.floor((ebbs+ebiv/2+ebev/8+5)*ebnc) document.getElementById("ebresult").innerHTML = ebresult; document.getElementById("ebdisp").innerHTML = ebresult; } function eccalc(){ let ecbs =Number(document.getElementById("ecbs").value); let eciv =Number(document.getElementById("eciv").value); let ecev =Number(document.getElementById("ecev").value); let ecnc =Number(document.getElementById("ecnc").value); let ecresult = Math.floor((ecbs+eciv/2+ecev/8+5)*ecnc) document.getElementById("ecresult").innerHTML = ecresult; } function edcalc(){ let edbs =Number(document.getElementById("edbs").value); let ediv =Number(document.getElementById("ediv").value); let edev =Number(document.getElementById("edev").value); let ednc =Number(document.getElementById("ednc").value); edresult = Math.floor((edbs+ediv/2+edev/8+5)*ednc) document.getElementById("edresult").innerHTML = edresult; document.getElementById("eddisp").innerHTML = edresult; } function escalc(){ let esbs =Number(document.getElementById("esbs").value); let esiv =Number(document.getElementById("esiv").value); let esev =Number(document.getElementById("esev").value); let esnc =Number(document.getElementById("esnc").value); let esresult = Math.floor((esbs+esiv/2+esev/8+5)*esnc) document.getElementById("esresult").innerHTML = esresult; } function damagecalc(){ let aorc =Number(document.getElementById("aorc").value); let power =Number(document.getElementById("power").value); let match =Number(document.getElementById("match").value); let comp =Number(document.getElementById("comp").value); //let ehdresult =Number(document.getElementById("ehdisp").value); if (aorc == 0){ //let adresult =Number(document.getElementById("adisp").value); //let ebdresult =Number(document.getElementById("ebdisp").value); temp = Math.floor(22*power*aresult/ebresult) temp = Math.floor(temp/50+2) mintemp = Math.floor(temp*0.85) temp = Math.floor(temp*comp) mintemp = Math.floor(mintemp*comp) temp = Math.ceil(temp*match-0.5) mintemp = Math.ceil(mintemp*match-0.5) } else{ //let cdresult =Number(document.getElementById("cdisp").value); //let eddresult =Number(document.getElementById("eddisp").value); temp = Math.floor(22*power*cresult/edresult) temp = Math.floor(temp/50+2) mintemp = Math.floor(temp*0.85) temp = Math.floor(temp*comp) mintemp = Math.floor(mintemp*comp) temp = Math.ceil(temp*match-0.5) mintemp = Math.ceil(mintemp*match-0.5) } document.getElementById("mintemp").innerHTML = mintemp; document.getElementById("temp").innerHTML = temp; document.getElementById("mincurrentHP").innerHTML = ehresult-temp; document.getElementById("maxcurrentHP").innerHTML = ehresult-mintemp; document.getElementById("minrate").innerHTML = (ehresult-temp)/ehresult*100; document.getElementById("maxrate").innerHTML = (ehresult-mintemp)/ehresult*100; }基本的な計算ツールとしての要件を満たすものはつくれたかなと思います。
具体的には、ほしい仕様の
1 は完璧に満たしている
2 はダメージ計算はできているが、どうぐや積み技によるランク上昇、天候などまだまだ足りない要素がある
3以降 はこれから
です。反省点として
JavaScriptのコードが不必要に長いです。汚いです。
機能実装最優先でゴリ押しで書きましたが、
1. Javascript側の関数を1つにしてHTML側でonclick=の引数を指定することでステータスの計算に適用
2. JavaScript側で親関数を作って各ステータスを計算する子関数を作り、HTML側はいまのまま
のどちらかできれいなコードになる気がします。このへんはまだオブジェクト指向な考え方が身についてないのですぐスマートな書き方にならないと思っています。
勉強します。あと、随時コメントを書くクセをつけていかないとなと思っています。
いまは1人でつくっていますが、複数人で開発するときにコメントがないのは大問題ですよね。課題
- ほしい仕様2の道具などの対応
- ほしい仕様3について、いきなりいろんなポケモンに対応するのは難しいので、いくつかのポケモンのプリセットボタンでダメージ計算のデモができるようにする
- ダメージ計算の結果をHPバーで表示する
- 機能はできてきたがデザインがダメ
見えている課題についてはこんなところです。
次回予告
次回はプリセットボタン、HPバーの実装について書きたいと思います。
また、今回は技術的なこと、苦労した点などについて書けていませんので、次回からはそのあたりも書いていきます。
(この記事についても追記したい)さいごに
いっしょにつくりたい!という方絶賛募集中です!
デザイン強いよ!、WEBアプリ強いよ!、勉強したいよ!という方、コメントなどにてお待ちしております!
- 投稿日:2019-11-29T21:19:42+09:00
HamlをRuby on Railsアプリケーションに導入する方法
Hamlとは
Hamlとは、HTMLを簡潔かつ簡単に記述できるマークアップ言語。
Railsで使用する場合の手順
1. Hamlを導入
Gemfileの一番下にコードを記述すると、すべての環境でhamlが使用できる。
記述後は、bundle installを忘れずに 。Gemfilegem 'haml-rails'2. erbファイルをHamlに変換
rails newにより、erbファイルがすでに作成されているので
拡張子がerbのファイルをhamlに変換する。一括変換する方法
ターミナルから以下のコマンドを実行。
$ rails haml:erb2hamlここで、
Would you like to delete the original .erb files? (This is not recommended unless you are under version control.) (y/n)と聞かれたら、状況に応じてy/nを選択する。
元のerbファイルを削除して構わなければ yを選択しよう。
- 投稿日:2019-11-29T21:00:59+09:00
初心者によるプログラミング学習ログ 172日目
100日チャレンジの172日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
172日目は
おはようございます
— ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) November 28, 2019
171日目
webサイトコーディングの課題
短い縦線の区切り線追加とか#100DaysOfCode #駆け出しエンジニアと繋がりたい #早起きチャレンジツイートは171日目ですが、172日目です。
- 投稿日:2019-11-29T19:07:23+09:00
デザインが上がってきてからコーディング前にする脳内整理したい
はじめに
記事を書く目的は「自分のやり方の整理整頓」です。
というのも、自分はこう考えてやってるけど合ってるんだっけ、もっといいやり方あるかもな、、と最近思う今日この頃。「業務の中でマークアップもするよ!」といった方、
「これからマークアップをやっていこうと思っているよ」といった方へ
一つの考え方として参考になるようなものになればと思います。デザインが上がってきたときにやること
デザインカンプを貰った時にまず考えること・やることを記述します。
ちなみに、デザインがあがってきた時に「さあ!コーディングだ!」と突然手をつけたら色々ぐっちゃぐちゃになって爆死します。(経験談)PCのデザイン、スマホのデザインを見比べる
※デザインカンプにPCとスマホ両方のデザインがあることを前提に記述します。
PCのデザインとスマホのデザインを見比べて、どこがどう違うのかをじっくり見ます。
ここでは以下を意識しています。
- 余白のルール
- コンテンツ間の余白
- コンポーネント同士の余白等
- テキストサイズのルール
- 見出しのテキストサイズ
- 本文のテキストサイズ
- 注釈のテキストサイズ等
- コンテンツの位置関係
- レスポンシブ前提の場合、要素の位置をスタイルの調整のみで変更できるかどうかを確認する
- 増える|消える要素はあるか
ルールが見えてこなかったり、不明な点がある場合は、素直に「教えてください」や、「こう実装しようと思ってるんですけど意図合ってますか?」とデザイナーさんにお伺いしています。
また、実装が難しそうな場合は、
「このやり方ならできます」や、「このやり方はどうでしょうか」と3案くらい持ってメリット・デメリットと合わせて説明し、
自分が思う「これがベスト」を提案してます。文書構造が破綻しそうにないかをチェック
マークアップをする上で文書構造は、見出しと文章の関係性を明確にする上でとても大事です。
また、スクリーンリーダーで読み上げた際に、見出しがないことで文章が成り立たなかったり、意図していない見出しの中に画像やテキストの内容が紐づいてしまう等もあります。それを防ぐために以下の観点でデザインを見て、文書構造を考えます。
見出しはどこかを考える
まず見出しは何かを明確にしていきましょう。
私はデザインカンプに直接「h1」や「h2」と泥臭くペンで書いてます。見出しに紐づくものは何か
上記で見出しを明確にしたら、次にその見出しの中になんのコンテンツが入るかを確認します。以下の画像では、タイトルに紐づくのは画像とテキストであるようにしなければなりません。
以前私がやってしまったNGパターンを紹介します。上記の「タイトル」を見出し要素(
h1
,h2
等)としてコーディングする場合
単純に再現するだけならば、、、<!-- NGパターン --> <div class="container"> <h1 class="pageTitle">ページタイトル</h1> <div class="l-grid"> <div class="l-grid_item"> <div class="img"> <img src="https://placehold.jp/150x150.png" alt=""> </div> </div> <div class="l-gird_item"> <h2 class="title">タイトル</h2> <p class="text">テキストテキストテキストテキストテキスト</p> </div> </div> <div class="l-grid"> <div class="l-gird_item"> <h2 class="title">タイトル</h2> <p class="text">テキストテキストテキストテキストテキスト</p> </div> <div class="l-grid_item"> <div class="img"> <img src="https://placehold.jp/150x150.png" alt=""> </div> </div> </div> </div>と以前の私はやってしまってました。(大反省)
一見見た目は再現できているように見えますが
、上記では1つ目の画像が別の見出しのものに紐づいてしまうので、文書構造上はNGです。
なので、実際には<!-- 多分OKパターン --> <div class="container"> <h1 class="pageTitle">ページタイトル</h1> <div class="l-grid l-grid-flexReverse"> <div class="l-gird_item"> <h2 class="title">タイトル</h2> <p class="text">テキストテキストテキストテキストテキスト</p> </div> <div class="l-grid_item"> <div class="img"> <img src="https://placehold.jp/150x150.png" alt=""> </div> </div> </div> <div class="l-grid"> <div class="l-gird_item"> <h2 class="title">タイトル</h2> <p class="text">テキストテキストテキストテキストテキスト</p> </div> <div class="l-grid_item"> <div class="img"> <img src="https://placehold.jp/150x150.png" alt=""> </div> </div> </div> </div>上記がマークアップ上正しい記述となります。
これだと、画像がタイトルに紐づく形になるので問題ないです。
画像とテキストを逆順にするのであれば、逆順にする用のclass属性を付けてあげましょう。まとめ
今回はデザインが上がってきた時、コーディングを行う前に脳内整理として大きく上記2点をやるといいのではないかなと思ってます。
この後に、コーディング規則とか、どんな設計にするとか色々工程はあるのですが、それは後日公開しようかなと思っています。
もしそのほかにも「自分はこれをやってるよ!」「これを意識しているよ!」等ありましたら、教えていただけると幸いです。
よい、コーディングライフを!
- 投稿日:2019-11-29T18:25:51+09:00
独学で居酒屋のホームページを作ってみた
結果
約半年間の勉強を経て、以下のようなホームページを制作しました。(ホームページ制作に費やした時間は3か月ほどです。)空いてる時間を見つけては少しずつ制作していったのでかなり時間がかかってしまいました。(笑)
サイトは、モバイルフレンドリー、SEO対策、ユーザーエージェント判定、jQueryによるアニメーションなどを考慮しました。
サイト制作には、HTML5、CSS3、Bootstrap4のみを学習した状態で取り掛かり、必要な技術や知識はその都度学びながら作業を進めていきました。使用した言語やフレームワーク
・HTML5
・CSS3
・Bootstrap4
・jQueryホームページを作ろうと思ったきっかけ
半年ほど前にwebプログラミングの勉強を始め、徐々に勉強をしていく中で完全オリジナルのホームページを作りたいと思うようになったのがきっかけです。最初は、クラウドソーシングを用いて誰かのためにホームページを作ろうと考えていました。しかし、初心者である私は一つも案件を受注することができませんでした。そこでポートフォリオ作成のためにも現在自分がアルバイトをしている居酒屋のホームページを勝手に作ってみることにしました。(笑)
出来上がったホームページをオーナーに見せてみるとぜひ欲しいということで公開に至りました。サイト公開までの制作手順
- サイトのデザイン、レイアウト、構造を大まかに決める
- HTML、CSSを記述し、大まかなサイトを作り上げる
- Bootstrap4を用いて余白やレイアウトを調節する
- レスポンシブ対応にするためにスマホ版のサイトを作成する(1~3を繰り返す)
- XAMPPを使用し動作確認
- 文書、写真の用意
- seo対策
- jQueryの実装
- レンタルサーバーを借りる(ロリポップ)
- ユーザーエージェント判定、CSSハックに対応する
- ホームページ公開
1. サイトのデザイン、レイアウト、構造を大まかに決める
正直自分はデザインやレイアウトを決めるのに一番頭を抱えました。デザインの勉強などもしたことがなかったので他の居酒屋ホームページを見まくりました。(笑)たくさんのホームページの中からいいなと思ったデザインを参考にしてサイトを制作しました。
2. HTML、CSSを記述し、大まかなサイトを作り上げる
HTML、CSSを記述し、大まかにサイトを作りました。文書や写真は仮のものを使用し、1で考案したデザインを形にしていきました。
3. Bootstrap4を用いて余白やレイアウトを調節する
CSSのフレームワークとしてBootstrap4を導入しました。制作したホームページの大半はBootstrap4を用いています。フレームワークによりかなりCSSの記述が楽になるのでCSSのフレームワークを学ぶことをお勧めします。自分の思い通りにCSSが反映されない時は、Chromeのディベロッパーツールを用いることで原因を突き止めていました。
4. レスポンシブ対応にするためにスマホ版のサイトを作成する(1~3を繰り返す)
サイトをレスポンシブ対応にする方法はいくつもありますが、自分はPC用サイトとスマホ版サイトを分けて作ることにしました。そのほうが、より自分の思い通りにレイアウトを調節できると感じたからです。手順としては、PC版と同じように1~3を行っていく形です。
5. XAMPPを使用し動作確認
ここまでのプログラミング反映の確認はChromeで行っていました(ディベロッパーツールを使うことでスマホ版のサイトも確認していた)。しかし、スマホ版のサイトを実機で確認がしてみたかったためサーバーが必要になりました。レンタルサーバーは費用がかかるため、無料でサーバー構築ができるXAMPPというソフトを使用しました。少し費用はかかりますが、圧倒的に楽で簡単なのは、レンタルサーバーを借りることです。
6. 文書、写真の用意
自分は、料理の魅力やオーナーの気持ちを伝えれるように文書を作成しました。写真は一部オーナーから頂き、足りない写真は自分のスマートフォンで営業時間外に撮影し編集しました。画像編集には、無料のソフトであるGIMPを使用しました。
7. seo対策
主なseo対策として、サイトに使用するワードについて気を付けました。(スモールワードとビッグワードをうまく使い分けることが大事。)また、HTMLファイル内にメタディスクリプションを記述したり、ファビコンの設定なども行いました。
8. jQueryの実装
サイトに動きを与えるためにjQueryを実装しました。サイトに動きを与えることでよりサイトが使いやすく見やすいものになっていきます。jQueryは、「スクロール幅によってトップに戻るボタンを出現させる」「ドロワーナビを表示させる」「ヘッダーとフッターのHTMLを別ファイルで管理する」といった箇所で実装しました。
9. レンタルサーバーを借りる(ロリポップ)
サイトが完成形に近づいてきたのでレンタルサーバーを借りました。レンタルサーバーはロリポップを使用しました。実践的にホームページをWeb上にアップロードしてみることでホームページの運用を体験しました。個人的にホームページをアップロードする瞬間が一番楽しかったです。(笑)
10. ユーザーエージェント判定、CSSハックに対応する
PC版のサイトとスマホ版のサイトをアクセスした端末によってうまく振り分けれるようにユーザーエージェント判定をjQueryで制御しました。
いざ、サイトを公開しようと思いアップロードしたところブラウザごとにレイアウトが乱れてしまうことが起きていたのでCSSハックにも対応させました。11. ホームページ公開
自分の思うようなホームページが完成したので公開に至りました。今後は、「Google Search Console」や「Google Analytics」を用いてseo対策がうまく適応されているかどうかを確認しつつ、ホームページを運用していくつもりです。
感想
ホームページを作成してみて一番重要なのは、使用する写真とSEO対策であると感じました。より画質の良く、映える写真を利用することで見栄えのいいホームページになります。またそれを検索上位に表示させるSEO対策も必須です。
レイアウトが思い通りにいかないことが多く、試行錯誤を繰り返すことはとても大変でしたが、その分達成感はものすごくありました。現在HTMLやCSSなどを勉強していてアウトプットする方法を探している方は、オリジナルのホームページやブログを作成し、公開してみるといいと思います。今後の展望
ホームページの作成当初は、出来上がったサイトを元にクラウドソーシングや近所のお店への直営業から案件を受注することを目標をしていましたが、ホームページが出来上がっていくにつれてより自分の技術を向上させたいと思うようになっていきました。
今後は、今回作成したホームページの運用とともにJavaScriptやそのフレームワークを中心に勉強していきたいと考えています。
ホームページのSEO対策についての改善案や、おすすめするJavaScriptのフレームワークなどありましたら教えてもらえると嬉しいです。
- 投稿日:2019-11-29T16:27:28+09:00
cakephpのテンプレートにjavascript呼び出しのみのボタンを設置
test.ctp<?php echo $this->Html->link('clickme', 'javascript:hoge();void(0)', ['class' => 'fuga']); ?> // class無しの場合 <?php echo $this->Html->link('clickme', 'javascript:hoge();void(0)'); ?> <script> function hoge() { alert('HOGE'); } </script>
- 投稿日:2019-11-29T12:50:37+09:00
HtmlFormでDeleteやPutを表現する
HTMLの標準では、FormはGETとPOSTしかサポートしていない。
擬似的にフォームでDeleteとPUTを表現したい場合は、パラメーターにmethod情報を含める。Railsのフレームワークは内部の処理で隠されたDeleteフォームを生成することでDeleteFormを表現している。
template.html<form method="POST"> <input type="hidden" value="delete" name="_method"> </form>
- 投稿日:2019-11-29T11:56:05+09:00
アクセシビリティ(a11y)対応の 「HTMLを書くとき」の自分メモ
a11yの必要性
- 過去記事
- https://qiita.com/SatoshiMukainakano/items/6a23f4ca90579eeff277
- https://qiita.com/SatoshiMukainakano/items/f38b71d99698576696c9
- ワールドワイドで見たら、より厳しいとこ多数
- 自分だって、いつケガしたり、障害もったり、するかわからない
- ケガや障害じゃなくても、公共の場の利用でもヒントになる
HTML書くとき
※書き終わったあとのコードを振り返るときにも。
(1) コンテンツのランドマーク
- どのセクションにも属していない
header
タグ orrole="banner"
- どのセクションにも属していない
footer
タグ orrole="contentinfo"
- 文法上正しい位置にある
main
タグ orrole="main"
メモ
- 原則として、ページを通して1箇所
- これら3つは互いに、どれかの子孫要素にも、どれかの祖先要素にもなっていない
- 「ここを探索できれば一発」的に、「共通ヘッダ」「共通フッタ」「コンテンツ主旨」 を示す
(2) 部品のランドマーク
nav
タグ orrole="navigation"
- 検索のためのフォーム (
role="search"
)- データ送信・操作のためのフォーム (
role="form"
)メモ
- コンテキスト、コンテンツ の並びによって、複数あっていいケースあり
(3) 見出し・セクション
h1-6
(h1
,h2
,h3
,h4
,h5
,h6
) タグaside
タグ orrole="complementary"
article
タグsection
タグメモ
- 「見出しをジャンプ」していくことで、そのページが伝えたいアウトラインを素早く巡行できる状態を目指す
- 本文しかないならともかく、それ以外のものもある中でいちいち全部をめぐってられない
- h1-6タグ でマークアップされた要素をジャンプしていく「見出しジャンプ」「見出しナビゲーション」 機能を活用
- 見出し【以外】を全部なくしたら、「コンテンツのアウトライン」がうまく描けている状態
注意
- HTML LS文法上で厳密に言えば、だいぶ語弊が残る
- あくまで、現時点の実装を踏まえた「早見」として
- 2019年11月時点では アウトラインアルゴリズム を踏襲した ブラウザ・支援技術 は見当たらない、とされる
(4) 他とつなげる
- 他のページへの遷移
a
タグ
- aタグ 以外のタグで「リンク」を装うのは原則的に非推奨
- やむない場合にのみ、
role="link"
を活用target="_blank"
にはrel="noopener"
を併設されたい- なるべくラベルだけでリンク先の 主旨・概要 を示したい
- フォーム
- ラベル付け必須
- エラーをしっかり明記
- 埋め込みコンテンツ
- 代替テキストなり、代替コンテンツなり、補助情報なり
- 外部リソース
link
タグ、meta
タグ、 OGP関連、アクセス解析系- スクリプト
(5) その他
HTML LS や WAI-ARIA を有効に活用
- リスト
- テキストレベル
- 動的に内容を変更したことを示す
参考にしたもの(一部)
- https://waic.jp/docs/WCAG20/Overview.html
- https://html.spec.whatwg.org/multipage/
- https://momdo.github.io/html/
- https://developer.mozilla.org/ja/docs/Web/Accessibility
- http://honttoni.blog74.fc2.com/blog-entry-61.html
- https://shibe97.tumblr.com/post/121266132377/html5のアウトラインを極めるための6つのルール
- https://developer.mozilla.org/ja/docs/Web/Guide/HTML/Using_HTML_sections_and_outlines
- http://www.html5-memo.com/html5/html5_03/
- ツール: https://gsnedders.html5.org/outliner/
- https://reliphone.jp/disabilities-possibilities/
- http://ommyzfactory.cocolog-nifty.com/blog/2019/10/post-a30587.html
[EOF]
- 投稿日:2019-11-29T11:54:31+09:00
横スクロール
- ポイント
- overflow-x
- white-space:nowrap; ← これないとカラム落ちみたいになるから、横幅をオーバーできない
<!DOCTYPE html> <html> <head> <title>Horizontal Scroll</title> <style> .parent{ overflow-x:scroll; overflow-y:hidden; width:50px; white-space:nowrap; } .child{ display: inline-block; } .item { /* 横スクロール用 */ display: inline-block; width: 90%; /* 見た目調整 */ height: 400px; margin: 16px; font-size: 48px; background: rgba(255, 0, 0, 0.4); } </style> </head> <body> <div class="parent"> <div class="child"> aaa </div> <div class="child"> aaa </div> <div class="child"> aaa </div> </div> </body> </html>
- 投稿日:2019-11-29T08:37:51+09:00
【React入門】コンポーネントの条件付きRender (Conditional Rendering)
はじめに
Reactの公式ドキュメントの条件付きレンダー(Conditional Rendering)にトライ。
条件付きレンダー-React
https://ja.reactjs.org/docs/conditional-rendering.html開発環境
- Ubuntu18.04
- yarn 1.17.3
- create-react-app 3.1.2
create-react-appで準備
$ create-react-app try-conditional-rendering $ cd try-conditional-renderingで、
./public/index.html
と./src/App.js
を編集。./public/index.html<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Web site created using create-react-app" /> <title>Try Conditional Rendering</title> </head> <body> <div id="root"></div> </body> </html>./src/App.jsimport React from 'react'; import './App.css'; const App = () => { } export default App;早速条件付きレンダーをやってみる。
まずは丸パクリにならないよう公式ドキュメントのマネをして
GreetInTheMorning
とGreetInTheAfternoon
、そしてGreetInTheEvening
というコンポーネントを作る。./src/App.jsconst GreetInTheMorning = () => { return <h1>おはようございます。</h1> } const GreetInTheAfternoon = () => { return <h1>こんにちは。</h1> } const GreetInTheEvening = () => { return <h1>こんばんは。</h1> }現在時刻によって上3つのコンポーネントのいずれかを表示したいとする。
本来ならちゃんとDate
オブジェクトを使って...ってやるんだけど、今回は公式に沿ってGreeting
コンポーネントを作ってApp
コンポーネントからGreeting
コンポーネントにnowHour
という引数を渡してズルをする。./src/App.jsconst Greeting = (props) => { // 5時 ~ 12時までは"おはようございます。"を表示する if(5 <= props.nowHour && props.nowHour < 12) { return <GreetInTheMorning /> } // 12時 ~ 18時までは"こんにちは。"を表示する else if(12 <= props.nowHour && props.nowHour < 18) { return <GreetInTheAfternoon /> } // 18時 ~ 5時までは"こんばんは。"を表示する else if((18 <= props.nowHour && props.nowHour < 24) || (0 <= props.nowHour && props.nowHour < 5) ) { return <GreetInTheEvening /> } else { return <h1>Error.</h1> } }
./src/App.js
の完成形が下のコード。./public/App.jsimport React from 'react'; import './App.css'; const GreetInTheMorning = () => { return <h1>おはようございます。</h1> } const GreetInTheAfternoon = () => { return <h1>こんにちは。</h1> } const GreetInTheEvening = () => { return <h1>こんばんは。</h1> } const Greeting = (props) => { // 5時 ~ 12時までは"おはようございます。"を表示する if(5 <= props.nowHour && props.nowHour < 12) { return <GreetInTheMorning /> } // 12時 ~ 18時までは"こんにちは。"を表示する else if(12 <= props.nowHour && props.nowHour < 18) { return <GreetInTheAfternoon /> } // 18時 ~ 5時までは"こんばんは。"を表示する else if((18 <= props.nowHour && props.nowHour < 24) || (0 <= props.nowHour && props.nowHour < 5) ) { return <GreetInTheEvening /> } else { return <h1>Error.</h1> } } // nowHour={}の中の数字を変えれば画面に表示される挨拶が変わる。 const App = () => { return <Greeting nowHour={13} />; } export default App;おわりに
続きはまた書きます。
- 投稿日:2019-11-29T01:07:55+09:00
HTMLについて学んだことまとめ
HTML - MDN - Mozillaで学んだことをまとめます。
目次
- HTMLとは
- HTMLの基本
今回の学習のゴール
- HTMLとは何か、何ができるかを知る
- 実際の使い方について知る
1. HTMLとは
- HyperText Markup Languageの略称
- webページのレイアウトに従ってwebページのコンテンツを記述し定義するもの
- マークアップを使用してwebページのコンテンツを記述する
- マークアップ : 文書構造(テキスト)や視覚表現(装飾)などの情報を、コンピュータが正しく認識できるように、タイトルや見出しなどの各構成要素に「タグ」と呼ばれる識別のための目印を使い、意味付けを行っていくこと
ex. <head>, <title>, <body>, <header>, <footer>2. HTMLの基本
ブロック要素とインライン要素
- ブロック要素
- 段落・リスト・ナビゲーションメニュー・フッターなどのウェブページ上で視認できるブロックを形成する要素
- インライン要素の中にネスト(入れ子)されることはできないが、他のブロックレベル要素にネストされることはある
<p>first</p><p>second</p><p>third</p>ブラウザfirst second third
- インライン要素
- ブロックレベル要素の中に包含され、段落全体やコンテンツのグループではなく、ドキュメントの内容の小さな部分だけを囲む要素
- ドキュメント内に新たな行を表示させず、テキスト段落の中で表示される
<em>first</em><em>second</em><em>third</em> <!-- 強調要素 -->ブラウザfirstsecondthirdHTML文書の構造
<!DOCTYPE html> <!-- DOCTYPE宣言 --> <html> <!-- ページ全体を囲むタグ --> <head> <!-- HTMLページに必要だが表示しない要素 --> <meta charset="utf-8"> <!-- 文字コード --> <title>first page</title> <!-- ページのタイトル ブラウザのタブに表示される --> <link rel="stylesheet" href="my-css-file.css"> <!-- HTMLにCSSを追加 --> </head> <body> <!-- webページで表示したいコンテンツを記載する --> </body> <script src="my-js-file.js"></script> <!-- HTMLにJavaScriptを追加 --> </html>
- 補足
- DOCTYPE宣言とは
- この文書がHTMLであること宣言し、HTMLのバージョンを明記するもの
<!DOCTYPE html>
は、HTML5を宣言するもの<link>
要素は<head>
タグの中に置く主なレイアウト要素
タグ 説明 <main>
Webサイト内の各ページで繰り返し使われるヘッダーやナビゲーション、検索フォームやフッター情報などを除いた、その文書内で主な内容となる部分 <article>
文書内の独立した記事セクション <section>
見出しを伴う文書内の章や節 <aside>
補足や脚注、用語の説明など、本筋とは別に触れておきたい内容 <header>
文書やセクションのヘッダー <nav>
文書内の主要なナビゲーション <footer>
文書やセクションのフッター 著者情報や関連記事へのリンクを記述することが多い 主要な要素
<h1>見出し</h1> <p>パラグラフはpタグを使う</p> <p> <img src="test.jpg"> <!-- 画像の埋め込み --> <a href="https://www.example.com">リンクの名前</a> <!-- リンクの埋め込み --> </p><!-- 順序なしリスト --> <ul> <li>リストの項目が入る</li> <li>リストの項目が入る</li> <li>リストの項目が入る</li> <li>リストの項目が入る</li> </ul> <!--順序つきリスト --> <ol> <li>リストの項目が入る</li> <li>リストの項目が入る</li> <li>リストの項目が入る</li> <li>リストの項目が入る</li> </ol><!-- テーブル --> <table> <tr> <!-- table row --> <th>デーブルヘッダー1</th> <!-- table header 表の見出し --> <th>デーブルヘッダー2</th> <th>デーブルヘッダー3</th> <th>デーブルヘッダー4</th> </tr> <tr> <td>デーブルデータ1</td> <!-- table data --> <td>デーブルデータ2</td> <td>デーブルデータ3</td> <td>デーブルデータ4</td> </tr> </table>HTMLフォーム
<form action="/my-handling-form-page" method="post"> <div> <label for="name">Name:</label> <input type="text" id="name" name="user_name"> </div> <div> <label for="mail">E-mail:</label> <input type="email" id="mail" name="user_mail"> </div> <div> <label for="msg">Message:</label> <textarea id="msg" name="user_message"></textarea> </div> <div class="button"> <button type="submit">送信</button> </div> </form>
- 補足
<form>
タグはフォームを表す
- action属性にはフォームで収集したデータを送信すべき場所(URL)を定義する
- method属性にはデータを送信するために使用するHTTPメソッドを定義する
<label>
タグはフォームの中でフォームの項目名と構成部品(チェックボックス、ラジオボタンなど)を関連付けるためのもの<input>
タグはフォームにおける入力欄を表す
- type属性では入力欄の種別を指定できる
- submit : 送信ボタン
- text : 1行テキストの入力欄
- email : メールアドレスの入力欄
- checkbox : チェックボックス(複数選択可能)
- radio : ラジオボタン(1つだけ選択可能)
<textarea>
タグは複数行の入力が可能な入力欄を作成するためのもの<button>
タグは<form>
タグで作成したフォームの中で汎用的にボタンを作成することができる
- type属性でボタンの形式を指定する
- submit : フォーム入力内容を送信する
- reset : フォーム入力内容をリセットする
- button : 何もしない汎用的な押しボタン
参照