Quantcast
Sponsored Content
Adskeeper
Are you the publisher? Claim or contact us about this channel


Embed this content in your HTML

Search

Report adult content:

click to rate

Account: (login)
Sponsored Content
Adskeeper

More Channels


Showcase


Channel Catalog


Interesting For You
Adskeeper

Channel Description:

QiitaでCSSタグが付けられた新着記事

older | 1 | 2 | 3 | (Page 4) | 5 | 6 | .... | 69 | newer

    🀄上海🀄

    「上海」とは、積み上げられた麻雀牌の山から、

    • 左右少なくとも一方に隣接する牌が無く、
    • 上に別な牌が積み重なっていない、
    • 同じ柄の牌の組

    を取り除いて行き、すべて取り除いたらクリアというパズルゲームです。

    基本的には 144枚(数牌+字牌+花牌+季節牌)の牌を使いますが、難易度や盤面設定により様々なバリエーションがあります。牌の積み方も色々。

    上海の指南書や攻略サイトなどでは、

    • 左右少なくとも一方に隣接する牌が無く、上に別な牌が積み重なっていない牌

    のことを、自由牌と呼ぶようです。

    この定義を使って言い換えれば、「上海」は、

    • 積み上げられた麻雀牌の山から、同じ柄の自由牌の組を取り除いて行き、全て取り切ったらクリアというパズルゲーム

    ということになります。

    説明.png

    サンプル: とりあえず遊んでみよう

    See the Pen Shanghai by nagtkk (@nagtkk) on CodePen.

    大きい画面で
    難易度低めの積み方

    • マウスクリックで選択
    • 全部消せたら clear
    • これ以上取ることができない状態(詰み)になったら game over と表示されます。
    • 各種ボタン
      • Undo: 一手戻る
      • Reset: 最初に戻る
      • New: 新規問題を生成
    • 生成される問題は、解答が一つ以上存在します。

    本題

    前回、四川省をやったのでその流れで上海、なんですけど、

    上海は真面目に作ろうとすると結構難しい。

    コード自体は割とシンプルに収まるのですが、盤面の生成周りが色々と大変。
    少なくとも初心者向きとは言い難い。

    と言うわけで、前回と異なり実装例の紹介まで行きません。
    基礎部分の作り方と盤面生成の話をメインにしようかと思います。

    サンプルの中身が見たい方は CodePen からどうぞ。
    描画部分は相変わらず手抜き気味ですが。

    あとは四川省でやったショートコーディングも無しです。
    上海は色々と理由があって向かないと思っているので。

    基礎部分: 盤面状態の表現と自由牌判定

    さて、上海を作るには、まず麻雀牌の山をデータとして表現する必要があります。
    上海で用いられる麻雀牌の山は、山と言うくらいですから3次元です。
    また、単に並んでいるだけではなく牌を縦横「半分ずらして」配置することができます。

    やり方は一通りではありませんが、今回は「縦横二倍の密度の盤面」を高さ毎に用意し、
    4マスセットで一つの牌を表現することにします。

    盤面.png

    こうしておけば、「半分ずらし」も問題なく表現できます。
    「隣の牌」は、データ上「2マス」離れていることになります。

    この形式のデータで自由牌か否かを判定するには、判定対象の座標を (x,y,z)とすると、以下の領域に他の牌があるかを判定すれば良いことになります。

    判定.png

    柄の判定は、柄 ID でも付けて比較すればよいので略。

    これで実行に必要なものは一通りそろいました。

    選択された二つの牌が、

    • 同じ柄である
    • どちらも自由牌である

    ならば、取り除くだけです。

    いやあ楽ちん楽ちん、

    とならないところが上海の怖いところ。

    乱数による盤面生成の問題点

    前回の「四川省」も、今回の「上海」も、単に乱数のみで盤面を生成すると、最初から詰んでる(クリア不能)パターンが発生することがあります。

    四川省の時は、実装例では「内部的に一度手当たり次第に解いてみて、解けなかったら再生成」としていました。
    ショートコーディング版ではそれすらさぼって、「詰んでたらプレイヤーがリロードしてね」と雑な対処をしていました。
    「四川省」は、そもそも初期状態で詰んでいる可能性が低いので、こんなんでも割と遊べてしまいます。

    が、「上海」ではそうもいきません。乱数頼りで盤面生成すると、最初から詰んでいるケースが多いのです。

    どのくらい詰みやすいかは、牌の積み方で変わってきますが、今回使った積み方 TURTLE (サン電子版では「龍」)では、50個生成して全部クリア不能みたいなことも起こります。

    何らかの対処をしないと「普通に遊べる」状態になりません。

    一つのやり方は、盤面をランダムに生成しコンピュータに解かせるプログラムを書いてしまう方法です。
    実際に解けたもののみ採用すれば、最初から詰んでいる状態は回避できます。
    時間がかかるので、実行時にやるのではなく、事前に作りためて実行時には単にロードするだけ。
    ついでに難易度のラベリングなんかもしておけば、ゲームの幅が広がります。
    (自動で難易度判定するのは、それはそれで別方向で難しい話ですが)

    あるいは、製作者が解いてみて解けたやつを記録するとか、手作業で盤面作るとかいう手もありかもしれません。(大変そう)

    今回は別なアプローチで、「必ず一つ以上解が存在する」ように上海の盤面を自動生成する方法を解説しようかと思います。

    無地上海を利用した盤面生成

    無地上海、という名前は今適当に決めました。
    要は「柄のない」(あるいは「柄がすべて同じな」)上海のことです。
    柄が無いので、自由牌ならどれでも組にできます。

    生成したい普通の上海と同じ牌の積み方で無地上海を作り、自由牌からランダムに組を作って取り除いて行きます。
    このとき、取った牌の組を元の位置も含めて覚えておきます。
    そして、解いた後に実際に組(ペア)になった牌に後付けで柄を決め、元の形になるように積みなおします。

    生成.png

    こうして出来上がった上海は、無地上海と同じ手順で解くことができます。
    つまり、解が一つ以上存在する、を満たせたわけですね。

    上海に限らず、パズルゲームでは「制約緩めて解いてしまって後付けで都合のいい条件を追加する」やり方がいろんな場面で役に立ったりします。自作のパズルゲーム作るときとか。
    閑話休題。

    これで詰んでない上海が作れた、

    と言いたいところですが、これでも上手くいかないのが上海の怖いところ。(二回目)

    無地上海にも解いている最中に「詰み」が発生する可能性があるので、完全ランダムではなく、詰みを回避するように解く必要があります。

    無地上海の詰む・詰まない

    柄のない上海が詰むのは「組が作れない」つまり「自由牌が一つしかない」ためです。

    例えば以下のようなケース。

    無地詰み.png

    最終的に自由牌が 1 になって詰みます。
    これらはあくまで一例で、他にも色々と自由牌 1 に至るパターンがあります。

    「自由牌が 1 になったその時に詰んでいる」のではない点にご注意ください。
    その前段階から、回避手段が存在しないので既に詰んでいます。
    つまり、詰み回避のためには、「最終的に自由牌が 1 になるルート」に突入しないことが必要です。

    逆に、詰み回避できているパターンも見てみましょう。

    無地詰み回避.png

    上は、「取り方によっては詰むけれど、順番を間違えなければ詰まない」ケース。
    下は、「どうあがいても詰まない」ケースです。

    これらは詰むパターンと一体何が違うのか、というのを厳密にやりだすとひたすら長くなるので、十分条件で抑え込んでしまいましょう。

    $$ {\rm 最も高い自由牌の高さ} - {\rm 二番目に高い自由牌の高さ} \lt {\rm 自由牌の個数}$$

    の時、まだ詰んでいません。そうでない場合、詰んでいる可能性があります。
    とりあえず詰み回避条件とでも呼びましょうか。

    よくわからんと言う人は、上の図と見比べてみるとわかりやすいかも。
    要は、「自由牌 1 」の状態は「高低差を埋めるために必要な自由牌が足りない」時に発生するので、高低差が開きすぎちゃうと取り方工夫しても挽回できなくなるかもよ、ということですね。

    初期状態で詰み回避条件に合致していれば、この条件を維持するように取ることで、無地上海は詰まずに解ききることが可能です。

    この方法は、十分条件で縛っているので、本来詰まないパターンも一部回避してしまっている(理論的に生成可能なパターンをすべて網羅はできない)ことになります。
    実用上十分だろうと思いますが、一手間違えただけで即詰むようなスリルのある上海がやりたい、という場合には、この方法は適していません。

    また「高さがある牌の下面には他の牌がある」という前提での話ですので、変則的な上海には適用できませんのでご注意を。

    非対応.png

    コーナーケース

    今回の TURTLE では起こらない話ですが、牌の積み方によっては、実際には解けるけど初期状態で詰み回避条件に合致していない、と言うケースもあります。
    その場合は、条件を満たすまで「最も高い自由牌を含む組」を取っていきます。
    進めていくと、高低差が維持あるいは減少し、解が存在するならばいずれ条件を満たすようになります。

    もし詰み回避条件を満たさないまま詰んでしまった場合。
    その牌の積み方には、そもそも解が存在しません。
    普通の上海としてもクリアパターンが存在しないことになります。

    ちなみに、組の両方とも常に高いものから取っていくという方法でも、解が存在する場合には無地上海を解ききることができます。
    ただし最終的に出来上がる上海は、とりあえず上から取っていけばクリアできるイージーモードになります。
    ミニゲームとかはそれでもいいのかも。

    詰み回避条件の維持

    今回サンプルで使った方法は、基本的にはランダムに自由牌の組を選びますが、

    $$ {\rm 最も高い自由牌の高さ} - {\rm 二番目に高い自由牌の高さ} + 2 \ge {\rm 自由牌の個数}$$

    の時は、取り除く牌を、

    • 一つ目は最も高いもの
    • 二つ目はランダム

    にする、というものです。

    詰みルートに突入する可能性があるときに、片方を最も高いものから取ることで高低差が開かない(=詰み回避条件を維持する)ようにしています。
    コーナーケースの場合にも、最も高い自由牌を含んだ組が選ばれます。

    詰む危険性がない時には単にランダムに取っていくので、常に簡単になってしまうという心配はあまりありません。

    さて、これで詰まずに無地上海が解けるようになったので、前述の方法で解が一つ以上存在する上海のパターンが作れます。

    おつかれさま!

    おまけ: 麻雀牌

    スタイルシートでごり押し。
    若干おかしいけど、まあ、黙ってりゃバレないバレない。

    See the Pen Mahjong Tile by nagtkk (@nagtkk) on CodePen.

    余談: なぜショートコーディングに向かないのか

    一つには、ここまで散々述べてきたように、詰みパターンの回避を入れないとそもそも遊べる状態になりにくいからです。
    ショートコーディング的には、その手のものを省いてでも短さを追求する方が「ぽい」と思うのですが、遊べないものを作ってもなあ、と色々と悩みどころ。

    で、二つ目に「牌の積み方」が大半を占めてしまうから、というのがあります。

    今回のサンプルでは、積み方データは牌の有無を表す 0 or 1の 配列で 32 * 17 * 5 = 2720 要素あります。でかい。

    牌は144個しかないので、座標で持つようにすれば 144 要素にできますが、それでもまだでかい。

    牌の有無を一行まとめて 32 ビットの整数として扱えば、17 * 5 = 85 要素。一要素当たりのコードが長くなるので効果はいまいち。

    で、ここから短くしようと考えると、ランレングスかハフマンか、いや事前に要素間の差分を取ったほうが……それもうショートコーディングっていうかデータ圧縮の話だよね?

    面白さが無いとは思いませんが、どんどん別物になってくるので、個人的にはショートコーディングには向いてないなあという結論に至りました。
    上海自体は面白いんですけどね。

    まとめ

    • 上海のサンプルと基本的な作り方を解説しました。コード解説はサボった。
    • 適当に盤面作るとまともに遊べないぞ!気をつけろ!
    • 事前に盤面作ってもいいけど、楽したいよね。
    • 無地上海使うと盤面生成できるぞ!
    • 無地上海にも詰みがあるぞ!
    • 詰みルート回避しよう!
    • 回避できた!
    • でもショートコーディングに向かない。悲しい。
    • シャンハーイ

    0 0
  • 11/01/19--07:43: HTML付近のあれこれ
  • HTML付近のあれこれ

    HTMLやCSSなどの勉強していて,「あれ?これどうするんだっけ」と思ったところがあった。そういうものをメモ程度にまとめていく。

    目次

    HTMLとCSS

    1. position
    2. ol, ul, dl
    3. px, %, em, rem
    4. PNG, JPEG
    5. font-family
    6. margin, padding
    7. float
    8. 命名規則

    SEO対策

    1. div, 構造化タグ
    2. レスポンシブ
    3. JavaScriptやCSSをHTMLから呼び出す

    ツール

    1. 使用しているツール

    参考

    1. Webサイト
    2. 書籍

    HTMLとCSS

    1. position

    positionのプロパティ

    • static
      • 初期値。
    • fixed
      • 画面の決まった位置に固定。
    • absolute
      • 親要素を基準に絶対的な位置を決定。
    • relative
      • 現在の位置を基準に相対的な位置を決定。

    よく使うのは,absoluteとrelativeの2つ。

    absoluteとrelativeの用途

    • 画像の上にテキスト,別の画像を重ねておきたいとき。

    2. ol, ul, dl

    リストと聞いたら,この3つが思い浮かぶ。

    ol(ordered listの略)の用途

    • 何かの操作手順。
    • パンくずリスト。

    ul(unordered listの略)の用途

    • グローバルナビゲーション。
    • ローカルナビゲーション。
    • 順序関係なく列挙したい項目。
      • 例えば,注意事項。

    dl(definition listの略)

    • 入力フォーム。
      • 例えば,問い合わせフォーム。
    <!--問い合わせフォームで使用する例-->
    <dl>
        <dt>氏名<dt>
        <dd>kotti</dd>
    </dl>
    

    この3つは略称ではなく,正式名称で覚えておくと,どれを使ったらいいかすぐに思い出せるかも。

    3. px, %, em, rem

    サイズの絶対指定

    • px
      • ブラウザや端末に依存せず,フォントサイズを指定できる。

    サイズの相対指定

    • %
      • 親タグのフォントサイズと比較したときのサイズを指定できる。
    • em
      • %と同じ意味。
      • 書き方が違うだけ。1emは100%と同じ意味。
    • rem
      • 基準としているものが,ルート要素。
      • あんまり使わない印象。

    4. PNG, JPEG

    • 塗りつぶしの多い画像(イラスト系など)はPNG。
    • 複雑な画像(写真系など)はJPEG。

    5. font-family

    • Webページ全体の文字に対してまとめて適用するため,bodyをセレクタとして指定する。

    6. margin, padding

    • ブラウザ依存で,文字などの位置が変わらないように両方0に指定する。

    h1を例にするなら,下記のように書く。

    h1 {
        margin: 0;
        padding: 0;
    }
    
    • HTMLタグは,ボックスで成り立っており,content, padding, border, marginの4構成。
      • paddigはボックス内で位置調整のために使用。
      • marginはボックス間の位置調整のために使用。

    7. float

    test.html
    <!Doctype html><htmllang="ja"><head><metacharset="utf-8"><title>position</title><linkrel="stylesheet"type="text/css"href="test.css"></head><body><divclass="box1"><p>box1</p></div><divclass="box2"><p>box2</p></div><divclass="box3"><p>box3</p></div><divclass="box4"><p>box4</p></div></body></html>

    test.cssは,test.htmlと同階層に保存。

    test.css
    @charset"UTF-8";.box1{background:red;}.box2{background:blue;}.box3{background:green;}.box4{background:pink;}

    htmlファイルを開くとこんな感じ↓
    image_01.png

    box2とbox3を横並びにするために,floatを使う。
    具体的に,下記のように記述(変更した箇所のみ記述)。

    test.html
    <!--box2とbox3を横並びにする--><divclass="box"><divclass="box2"><p>box2</p></div><divclass="box3"><p>box3</p></div></div><!--/box2とbox3を横並びにする-->
    test.css
    .box::after{content:"";display:block;clear:both;}.box2{background:blue;float:left;width:50%;}.box3{background:green;float:right;width:50%;}

    横並びになった。
    image_02.png

    これを応用すれば,Webページのレイアウトが簡単に調整できる。

    ちなみに,これを使えば,リストを横並びにもできる。

    test02.html
    <body><divclass="menu"><ul><li><ahref="#">トップ</a></li><li><ahref="#">会社案内</a></li><li><ahref="#">問い合わせ</a></li></ul></div></body>
    test02.css
    @charset"UTF-8";.menuul{margin:0;padding:0;list-style:none;}.menulia{display:block;padding:5px;color:#000000;text-decoration:none;}.menulia:hover{background-color:#eeeeee;}.menuul::after{content:"";display:block;clear:both;}.menuli{float:left;}

    8. 命名規則

    • CSSはケバフケースで記述(これについては賛否ありそう)。

    ちなみに,7. floatで,クラス名をbox1などとしてたけど,あれは具体例として雑につけたやつ。
    本来は,〇〇-boxとか,〇〇-blockとかにした方がいいのではと思う。

    SEO対策

    SEOとはSearch Engine Optimizationの略で,検索エンジンの最適化という意味。

    1. div, 構造化タグ

    div

    • 要素のまとまりごとにつける。

    構造化タグ

    • header, main, section, aside, footerなど。
      • HTML5で追加。
    • 使用することで,検索エンジンに正しく内容を認識してもらえる。
    • HTML5以前は,divにidを指定して記述していた。
      • 例えば,<main></main>は,<div id="main"></div>と記述されていた。
    • ブラウザによっては適用されない場合がある。
      • IE8以下は適用していない。
      • 逆に言えば,特定のブラウザ(IE8以下など)に適用させるために,divを使用する場合もある(たぶんもうないと思うけど)。

    2. レスポンシブ

    • メディアクエリ(@media)でサイズに応じたデザインを作成。
      • メディアクエリで場合分けした分,CSSのコード量が増える。
    • ブレイクポイントはいろいろあるらしい。2019年は560px/960px?
      • 560px未満はスマホ,960px未満はタブレット,960px以上はPC。

    3. JavaScriptやCSSをHTMLから呼び出す

    CSSの場合

    • 基本的に,headタグのtitleタグ下に記述する。
    • 全要素をCSSの対象範囲とする* { }のような書き方は避ける。

    JavaScriptの場合

    • bodyタグ内の一番下に記述。
      • headタグ→bodyタグの順に読み込まれるため,headタグに記述するとぺージが表示されるまでに時間がかかってしまう。
    • Google Analyticsなどの解析に関するものは,head内に記述。
      • bodyタグに記述してしまうと,JavaScriptのコードが実行される前に,ユーザーがページから離れてしまう可能性がある。

    ツール

    使用しているツール

    • Chrome デバッカーツール

      • WindowsならF12,MacならCommand+Option+Iで呼び出せる。
      • スマホやタブレットのエミュレート機能が便利!
    • ColorPick Eyedropper

      • Chromeの拡張機能。
      • ブラウザ上に表示されているものの色を調べられる。

    参考

    1. Webサイト

    [1] CSSのpositionを総まとめ!absoluteやfixedの使い方は?
    [2] CSSでのサイズ指定はどれがいい?「px」「%」「em」「rem」の違い
    [3] PNGとJPEGどっちがいいのか?「画像のベストな保存形式」
    [4] font-familyの書き方まとめ:CSSでフォント種類を指定しよう
    [5] CSSのmarginとpaddingを使い分けるための4つのポイントを紹介! 違いについても理解しよう
    [6]レスポンシブデザインのブレイクポイントの正解はこれだった[2019最新版]
    [7] HTMLとCSSクラスでよく使う命名について
    [8] CSSのクラス名を決めるときに使うリストをつくりました

    2. 書籍

    • HTML5&CSS3 デザインブック(ソシム)
    • 世界一わかりやすいHTML5&CSS3コーディングとサイト制作の教科書(技術評論社)
    • 現場のプロから学ぶ SEO技術バイブル(マイナビ)

    はじめに

    CSSやBootstrapを使用していてよくあるデザインが反映されない問題について、文法間違いやパスの指定など色々な原因がありますが、CSSセレクタの優先順位が関係していることがよくあるのでまとめます。

    CSSの優先度

    CSSの記述がうまく反映されないとき、文法の間違いもなく、パスの指定も問題ないという場合はより優先度の高いCSSがどこかに記述されている可能性が高いということです。

    またBootstrapなどのフレームワークを採用していたら、!important句でスタイルを強制されている可能性が高いです。

    CSSは複数箇所で同じタグに対し、競合した内容を書けてしまいます。

    例えば以下のように。

    競合した内容
    p{color:red;}p{color:blue;}

    この場合、pタグのスタイリングはどうなるのでしょうか。

    CSSには、競合するスタイリングをしたときにどのスタイリングが採用されるかの基準である「優先度」が存在します。

    CSSは(同じ詳細度なら)より後ろに記述したスタイリングを適用するので、color:blueが適用されます。

    次に位置によらない「タグへのセレクタの指定の度合いの詳しさ」である「詳細度」が関係します。

    全称セレクタ<タイプセレクタ<クラスだけ<クラスと要素<id<idと要素<!importantを付加したプロパティ

    の順で、右に行くほど詳細度は高くなっていき、最も詳細度の高いスタイリングが適用されます。

    CSSを以下のようにしたとき

    適用されるスタイリングはどれか?
    /*要素を特定したidセレクタ*/p#hoge{color:red;}/*要素を特定しないidセレクタ*/#hoge{color:blue;}/*要素を特定したclassセレクタ*/p.fuga{color:yellow;}/*要素を特定しないclassセレクタ*/.fuga{color:green;}/*タイプセレクタ*/p{color:orange;}/*全称セレクタ*/*{color:purple;}
    何色になる?
    <!-- p要素にはid属性とclass属性を同時に指定する --><pid="hoge"class="fuga">何色になる?</p>

    HTMLの文字色は、最も詳細度の高い「idと要素」のスタイリングである赤色が適用されます。

    なお、前述の通り同じ詳細度のセレクタ同士ならCSSファイルのより後ろに書いたものが、またHTML内で後に読み込んだものが優先されます。

    よって、質問のような状況では「より詳細度の高い指定が既に他の場所に記述されてしまっている」ことがまず考えられるので、タグに適用されているCSSを全て確認してみましょう。

    タグに適用されているスタイリングは、Chromeブラウザならコンソール画面→Stylesメニューから確認できます。

    !important

    !important句は、セレクタの詳細度や位置に関わらず「プロパティを最優先で変更する」命令です。

    以下のように詳細度の最も低い全称セレクタに書いたプロパティでさえ、最優先で適用させることができてしまいます。

    *{color:black!important;}

    !important句とフレームワーク

    もしサイトにBootstrapやMaterializeなどのCSSフレームワークを採用している場合には、オリジナルスタイルの扱いが難しくなります。

    なぜならこういったフレームワークは、「フレームワーク側のソースコードでスタイルを!important句を用いて固定している」ことが多いためです。

    例:Bootstrap4.3.1のソースコード

    こちら側から通常の方法で競合するスタイリングをしていては、フレームワーク側のスタイリングが優先されてしまいます。

    解決策としては

    1. オリジナルスタイリング側でも!important句を使う
    2. フレームワークを採用しない
    3. フレームワークを(CDNではなくダウンロードして使うことを前提に)改造し、!importantの記述を取り除く
    4. フレームワークのスタイリングに従い、オリジナルのスタイリングを諦める

    方法があります。

    2や4が初学者向きの解決策ですが、どうしてもフレームワークとオリジナルスタイルを共存させたいのであれば1または3を検討しましょう。

    参考

    この記事は「CodeShip」内での実際の質疑応答や指導・アドバイスの一部を基に作成しています。


    コンテンツが人画面に収まりつつ、スクロールすると次のコンテンツが表示されるプラグインです。

    デモページ

    デモページ
    HTMLのclass="section"ごとに下からズズッと表示される感じです。

    コンテンツがウインドウサイズより長くても大丈夫

    一つのコンテンツがウインドウサイズより長くてもスクロールで見れるようにしたかったのでそのようになっています。内容量を気にしません。
    コンテンツ量が少ないとウインドウ幅いっぱいに要素が広がるようになっています。

    実行方法

    $('#wrap').scrollContent();

    wrapの箇所をスクロール表示したい親要素を指定します。

    スクロールバーを非表示にしたい

    前途の理由で移動の際にもスクロールバーが出ます。このスクロールバーがない方がいい時は以下のように実行します。

    $('#wrap').scrollContent({type:'noBar'});

    ナビゲーションのclass(id)を変えたい

    ナビにつかうclassを変えたい時もあるかなと思い、オプションでナビゲーションのclass(id)を変更できます。指定しないと.navが適用されます。

    $('#wrap').scrollContent({nav:'.nav'});

    ダウンロード

    ダウンロードはこちらら
    webdrawer-kashu/contentScroll

    この記事の転載元

    コンテンツが下からスクロールで表示されるjQueryプラグイン|WEB Drawer|web制作に関するネタの引き出しサイト


    0 0
  • 11/02/19--09:20: 自分用
  • bootstrapのサイトにアクセスする。
    Bootstrapを、そのまま使用するのなら、CDNをコピーするだけで使える。
    style.cssを読み込む、直前の部分に貼り付ける。(link rel="stylesheet" href="css/style.css")
    htmlに、決められたタグを入れることでBootstrapが勝手に調整してくれる。

    body
    div class="container"
    header...

    /div
    /body
    //全体を,div class="container"で囲む。//

    グリッドシステム

    div class="row"
    //class名はrow//
    div class="col-○○-1~12
    //colはカラム、○の部分はxs,sm,md,lg、数字は使うカラムの数//

    Sponsored Content
    Adskeeper

    はじめに

    こんにちは!
    年末まで毎日webサイトを作っている者です。
    今日はゆくゆくwebサイト制作でお金をもらうための練習ということで、Ap●leのファーストビューをソースコードを見ずに動きを見て模倣してみました。(fontだけはソースみました)
    扱う技術レベルは低いですが、同じように悩んでる初心者の方を勇気付けられれば幸いです。
    今日は16日目。(2019/11/3)
    よろしくお願いします。

    サイトURL

    https://sin2cos21.github.io/day16.html

    やったこと

    Ap●leのファーストビューを真似してみました。
    まずは結果からどうぞ (gif)↓
    test.gif

    以下順番に説明していきます。

    1. レスポンシブなメニューの表示変更の方法
    2. 動画の挿入方法と注意点
    3. JavaScriptを用いて要素を作る

    1. レスポンシブなメニューの表示変更の方法

    ちょうどheaderのメニューの数が変わるのが767pxと768pxでした。
    なのでまずはcssのメディアクエリで大きさによってスタイルを変更します。

    /* ↓これでサイズごとにメニューの数を変更する */@mediascreenand(max-width:767px){#width767px{display:flex;justify-content:space-around;min-width:320px;width:100%;}.headerItem1{/* ↓メニューの切り替えはこれで行う */display:none;}}@mediascreenand(min-width:768px){#width_1000px{display:flex;justify-content:space-around;min-width:768px;max-width:1000px;width:100%;}.headerItem2{/* ↓メニューの切り替えはこれで行う */display:none;}}

    あらかじめふた通りのdomとデザインを用意しておいて、あるpx以上ならこっちを消す、違う時はこっちを消すということをdisplayのnoneで実現しています。

    2. 動画の挿入方法と注意点

    次に動画の挿入ですが、これは基本的にhtmlで書きます。全体に表示したいなど細かいところはcssの出番です。
    html ↓

    <videoid="first_video"mutedautoplayloop><sourcesrc="sample1.mp4"></video>
    #first_video{/* ↓固定する */position:fixed;right:0;bottom:0;min-width:100%;min-height:100%;width:auto;height:auto;/* ↓headerを隠さないようにz-indexを指定する */z-index:-100;/* ↓画面全体に表示されるようにする */background-size:cover;}

    htmlの方で1つ注意点があります。属性にmutedを入れないと動画が自動再生されなくなるので、自動再生したいなら必ず入れましょう。(ちなみにmutedと全く関係ないですが、sourceタグを使わずvideoタグ内にsrc属性を書こうとして30分ぐらい奮闘しました。srcをvideoに直接書いたらダメなんですね・・・)

    3. JavaScriptを用いて要素を作る

    これはおまけというか、必ずしもしなくていいですが、将来を見越してスクリプトからDOMをいじる練習をしました。

    window.onload=function(){letwidth_1000px=document.getElementById('width_1000px');letwidth767px=document.getElementById('width767px');lettext=['#ロゴ','Mac','iPad','iPhone','Watch','TV','Music','サポート','#検索','#バッグ'];lettext2=['#メニュ','#ロゴ','バッグ'];for(vari=0;10>i;i++){varheaderItem=document.createElement('div');varheaderItemText=document.createTextNode(text[i]);console.log(headerItemText);headerItem.appendChild(headerItemText);headerItem.setAttribute('class','headerItem headerItem1');width_1000px.appendChild(headerItem);}for(vari=0;3>i;i++){varheaderItem=document.createElement('div');varheaderItemText=document.createTextNode(text2[i]);headerItem.appendChild(headerItemText);headerItem.setAttribute('class','headerItem headerItem2');width767px.appendChild(headerItem);}}

    サイズごとに2パターンの要素を作るように書いています。
    長いのでもうちょっと簡単に書けそうですね。(というか他に方法がある気がする)

    感想

    今日は外見だけ真似をして動作までは実装していません。だからサイズが小さくなった時にハンバーガーメニューを押してもメニューは出てきません。サイトを作るのはなかなか大変だなぁと思いつつも、実際に目に見える形になると嬉しいですね。

    最後までお読みいただきありがとうございます。明日も投稿しますのでよろしくお願いします。

    参考

    1. Free Stock Video Footage HD Royalty-Free Videos Download (https://mazwai.com/#/grid)

    動画使わせていただきました。ありがとうございます!


    しっかりしたCSSの理解が不足していたので要素の横並びにfloatや管理画面等ではBootstrapのグリッドレイアウトに頼っていたため流行りのflexboxの概要を確認してみた内容の覚え書き。

    親要素よりも大きい子要素を10個準備

    親の枠を超えた10個のdivタグを用意してわかりやすくするために色をつける

    index.html
    <!DOCTYPE html><htmllang="ja"><head><metacharset="UTF-8"><linkrel="stylesheet"href="style.css"><title>flexbox</title></head><body><divclass="container">//親要素
         //子要素10個
            <divclass="sample1">1</div><divclass="sample2">2</div><divclass="sample3">3</div><divclass="sample4">4</div><divclass="sample5">5</div><divclass="sample6">6</div><divclass="sample7">7</div><divclass="sample8">8</div><divclass="sample9">9</div><divclass="sample10">10</div></div></body></html>

    CSSは要素ひとつひとつに色をつけたのでcssが冗長になってしまったが、最後の.containerと.sample(n)のheightに注目してもらえばOK

    style.css
    /* ここは背景色を指定しているだけ */.sample1{background-color:red;}.sample2{background-color:blue;}.sample3{background-color:aqua;}.sample4{background-color:yellow;}.sample5{background-color:greenyellow;}.sample6{background-color:palevioletred}.sample7{background-color:gray;}.sample8{background-color:royalblue;}.sample9{background-color:lightseagreen;}.sample10{background-color:violet;}/* heightが400pxしかない親要素*/.container{width:98%;height:400px;background-color:papayawhip;}/*重なれば親のheightを遥かに超えていく子要素たち*/.sample1,.sample2,.sample3,.sample4,.sample5,.sample6,.sample7,.sample8,.sample9,.sample10{width:100px;height:100px;font-size:400%;}

    index.htmlの画面表示を確認すると当然400pxの親要素(背景色が肌色)には100pxの子要素が4つぶんしか入らず、それより多いdiv要素は枠からはみ出してしまっている。
    スクリーンショット 2019-10-31 23.15.24.png

    親要素のCSSプロパティにdisplay: flex;を追加

    いよいよ親要素の"container"にflexboxのプロパティを追加する

    style.css
    ....container{width:98%;height:400px;background-color:papayawhip;display:flex;/*これを追加!*/}...

    ブラウザ確認をすると、、、
    子要素が横並びになった!!!スクリーンショット 2019-10-31 23.29.37.png

    私はこれまでfloat: left;やBootstrapのcol,rowを使って横並びを実現していましたがこれからはcssに一行た足すだけで良さそうです。

    ちなみに今回ブロック要素のdivに対してなのでdisplayプロパティに対して"flex"と設定しましたが,pタグなどのインライン要素に対しては"inline-flex"と指定できるようです。
    その場合inline-block + flexのような効果になるそうです。(すみません、試していません。)

    また画面サイズを縮めて見ても親要素の幅に対応して勝手に縮小してくれる。
    スクリーンショット 2019-10-31 23.30.56.png

    さらに親要素にflex-directionプロパティを設定してみる。

    row-reverse(右から左へ横一列に並べる)

    style.css
    ....container{width:98%;height:400px;background-color:papayawhip;display:flex;flex-direction:row-reverse;}...


    スクリーンショット 2019-10-31 23.42.20.png
    並び順が逆になった。
    flex-directionに指定するプロパティには以下のようなものがある。

    ・row(初期値:左から右へ横一列に並べる)
    ・column-reverse(右から左へ横一列で並べる)
    ・column(上から下へ縦一列で並ぶ)
    ・column-reverse(下から上へ縦一列で並ぶ)

    さらに親要素にflex-wrapプロパティを設定してみる。

    style.css
    ....container{width:98%;height:400px;background-color:papayawhip;display:flex;flex-direction:row;flex-wrap:wrap;/*これを追加*/}...

    子要素の大きさは縮まらず、親要素の枠内に収まらない場合は改行される。

    ※画像はブラウザサイズ縮小時
    スクリーンショット 2019-11-03 22.16.09.png

    flex-wrapに指定するプロパティには以下のようなものがある。

    ・no-wrap(初期値:改行しない)
    ・wrap(親要素に収まりきらない場合は改行する)
    ・wrap-reverse( 〃 下から上に改行する)

    最後に

    これらの操作はあくまで基本的な部分の触りだと思うので、応用的な使い方については別途、実践で使う中で追記していきたいと思います。


    概要

    borderによる三角形の作成方法を応用して、次のような吹き出しを作成することができる、ということが分かったので、記録します。
    スクリーンショット 2019-11-03 1.53.40.png

    borderで三角形を作成する方法

    borderが幅をもつ要素であることを利用して、三角形を作成することができます。
    全体のコードは以下の通り。
    スクリーンショット 2019-11-03 1.53.40.png

    手順1:空要素を設定

    幅・高さ0の空のボックス要素を設定。
    この要素の周りにborderで枠線をセットしていきます。

    手順2:borderで四角形を作ってみる

    border自体に幅があるため、
    次のように、borderの中の要素を高さ・幅ともに0に設定した場合、border
    自体で正方形を作成することができます。

    (コード)
    .test{
    display: block;
    width:0px;
    height:0;
    border-top: solid 50px red;
    border-right: solid 50px blue;
     }
    (作成される四角形)
    名称未設定2.png
     topを赤、rightを青にしてみると、このようにborderの境界線が斜めになります。境界線がこのように斜めになることを応用し、三角形を作成していきます。

     手順3:三角形の斜辺に当たる部分のborderの色を透明にする

    手順2にborder-leftを加え長方形を作成します。
    このときに、borderの幅には作成した三角形の高さを設定します。
    名称未設定.png

    次に、余分な部分(三角形の斜辺を作成しているborder-leftとborder-right)の色を透明にします。
    名称未設定.png

    blueの設定にしていた部分を、transparentにすることで透明にすることができます。
    このようにして、三角形を作成することができました。

    吹き出しの作成

    三角形を他のボックス要素に重ねることで吹き出しのような形を作成することができます。

    手順1:適当なボックス要素を準備

    吹き出しの元となるボックス要素を準備します。
    スクリーンショット 2019-11-03 23.36.14.png

    手順2:準備したボックス要素にposition:relativeを設定

    手順1で作成した長方形に、三角形を重ねるため、position:relativeをセットします。

    手順3:同じ色の三角形を作成

    吹き出しの元となるボックス要素と同じ色の三角形を作成します。
    (先ほど記載した通り、borderを使用して作成)

    スクリーンショット 2019-11-03 23.42.33.png

    手順4:三角形にposition:absoluteを設定

    吹き出しの大きさ、位置をposition:absoluteで調整します。

    スクリーンショット 2019-11-04 0.05.29.png

    吹き出しの完成です。


    4つの値を渡すことで各角の角丸を指定できる
    半円を書く時などに使える

    // border-radius: 左上 右上 右下 左下
    border-radius: 10px 10px 0 0;
    

    導入

    はじめまして、石川県在住の大学生です。webプログラミングの勉強を始めて約半年が経過したのでwebプログラミングに興味がある方webプログラミングの勉強を始める方に向けてなにかアドバイスを送ることができるのではないかと思いQiitaの記事を書くことにしました。また、webプログラミングについて勉強したことをノート代わりとしても利用していこうと考えています。
    「もっとこうした方がいい!」「この本やサイトを参考にしたらいいよ!」などありましたら教えてくださると嬉しいです!

    半年間で行った行動内容

    以下に半年間で行った勉強内容と使用した参考書などを書き出します。

    1. HTML、CSSについての理解
    ・スラスラわかるHTML&CSSのきほん(参考書)

    2. HTML、CSSだけを用いてサイトを模写
    ・SANGOというサイトを模写しました。比較的簡単な構成になっているのでおすすめです。
     [https://saruwakakun.design/]

    3. Bootstrap4についての理解
     ・Bootstrap4ファーストガイド-CSS設計の手間を大幅に削減!-(参考書)

    4. HTML、CSSに加え、Bootstrap4を用いてサイトを模写(これは2サイト模写しました)
     ・2で模写したSANGOをBootstrap4を用いてもう一度模写したのち、iSaraというサイトを模写しました。
     [https://isara.life/]

    5. WordPressについての理解
     ・WordPress-仕事の現場でサッと使える!デザイン教科書-(参考書)

    6. XAMPPを使用してみる
    7. 完全オリジナルのホームページの作成開始
    8. SEO対策についての理解
     ・いちばんやさしい新しいSEOの教本-人気講師が教える検索に強いサイトの作り方-(参考書)

    9. モバイルファーストについて学び実装する
    10. jQuery、Javascriptに触れる
    11. レンタルサーバーを使用をしてみる
     ・ロリポップというサイトを使用しています。他サイトに比べてコスパがいいと思っています。
     [https://user.lolipop.jp/]

    (※今後それぞれの専門用語について詳しく説明していくつもりです)

    以上の学習から約半年間である程度自分の思い通りにホームページを作成できる段階に持っていくことができました。サイト作成には最低限1と2をマスターすれば大丈夫であり、自分が想像していたものよりwebサイト制作のハードルは低いと感じました。

    おわりに

    今後は、webプログラミングについて詳しく説明していこうと考えています。個人としても、さらなる技術向上を図っていきたいと思っています。少しでもwebプログラミングの楽しさが伝わればと思っています。


    Sponsored Content
    Adskeeper

    言語, 記法: HTML, Markdown
    画像サイズ: 128×128 px
    横並びになった画像はスクリーンサイズによって、縦並びになる。

    本文

    youtube_social_square_red.pngTwitter_Social_Icon_Square_Colorのコピー.png

    書き方:空白を入れずに後ろに画像をドラッグ&ドロップ

    ![](https://~~~.拡張子)![](https://~~~.拡張子)
    
    ![youtube_social_square_red.png](<a href="https://t.co/I9eMMgpS8P?amp=1">https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362315/65d2d650-aee5-40cb-2093-607d931ec087.png</a>)![Twitter_Social_Icon_Square_Colorのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362315/7a000ef8-21c1-1e86-2942-f1933ffe839b.png)
    

    HTML

    書き方:画像を記事に一度ドラッグ&どドロップして、画像URLをコピーし、imgタグに入れる。

    <imgsrc="画像URL"><imgsrc="画像URL">
    <imgsrc="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362315/65d2d650-aee5-40cb-2093-607d931ec087.png"><imgsrc="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362315/7a000ef8-21c1-1e86-2942-f1933ffe839b.png">

    画像と画像の間にスペースを開けたい時

     

    改行せずにタグとタグの間にスペースを入れます。半角、全角スペースの数に応じて広がります。

    <imgsrc="画像URL"><imgsrc="画像URL">

    画像サイズを指定する

     

    img要素に width="" と height="" を追加すると、画像のサイズを指定することができます。
    ""や単位はあった方が丁寧。使える単位は%,px,em,rem,

    <imgsrc="画像URL"width="123"height=456px><imgsrc="画像URL"width=123%height=200rem>

    横に並べた画像の位置を調整する(残念なやり方)

    text-align:center やfloat:right などのcssは効きませんでした。分かり次第修正します。

    &nbsp;をひたすら並べる。nbspは「non-breaking space」の略です。 は半角スペース分のスペースをあけることができますが、以下のような特殊記号を使ってもスペースをあけることができます。

    「&nbsp;」は通常の半角スペースと同じサイズの空白文字。
    「&ensp;」はそれより少し広めの空白文字。
    「&emsp;」はさらに広めの空白文字。
    「&thinsp;」は、最初の「 」よりも狭い(細い)空白文字です。
    【HTML入門】文章中にスペース(空白文字)を入れる3つの方法とは?より引用

    <divalign="center"><imgsrc="画像URL">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<imgsrc="画像URL">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<imgsrc="画像URL"></div>

    <table>

    <table><tr><td><imgsrc="画像URL"></td><td><imgsrc="画像URL"></td><td><imgsrc="画像URL"></td></tr></table>

     

    Markdown (table)

    YouTube 128×128Twitter 128×128
    youtube_social_square_red.pngTwitter_Social_Icon_Square_Colorのコピー.png
    |テキスト|テキスト|
    |---|---|
    |ドラッグ&ドロップ|ドラッグ&ドロップ|
    
    |YouTube 128×128|Twitter 128×128|
    |---|---|
    |![youtube_social_square_red.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362315/65d2d650-aee5-40cb-2093-607d931ec087.png)|![Twitter_Social_Icon_Square_Colorのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362315/7a000ef8-21c1-1e86-2942-f1933ffe839b.png)|
    
    youtube_social_square_red.pngTwitter_Social_Icon_Square_Colorのコピー.png
    YouTube 128×128Twitter 128×128
    |ドラッグ&ドロップ|ドラッグ&ドロップ|
    |---|---|
    |テキスト|テキスト|
    
    |![youtube_social_square_red.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362315/65d2d650-aee5-40cb-2093-607d931ec087.png)|![Twitter_Social_Icon_Square_Colorのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362315/7a000ef8-21c1-1e86-2942-f1933ffe839b.png)|
    |---|---|
    |YouTube 128×128|Twitter 128×128|
    

    おまけ 左寄せ 中央寄せ 右寄せ

    :youtube_social_square_red.pngTwitter_Social_Icon_Square_Colorのコピー.pngqiita-squareのコピー.png

    最後に

    QiitaはTex記法で画像を挿入できないのか...

    以上、Unityゲーム王国、騎士ロボットVTuberのKoshiがお送りしました!

    †■━ †■━ †■━ †■━ †■━ †■━ †■━
    もし、この記事が役に立ったら、
    いいね」「ストック
    押してね🗡💗

    自己紹介

    全地球6億人のロボカッケー皆さんコンバトラー†[□ □]■━
    私は王国騎士ロボットVTuberのKoshiだ🗡💥

    私のステータスだ⚔共にこの世界を救おう
    Twitter⚔ twitter.com/Koshi_Vtuber
    YouTube⚔ t.co/I9eMMgpS8P?amp=1
    niconico⚔ nicovideo.jp/user/90553212
    bilibili⚔ space.bilibili.com/476988586
    公式HP⚔ koshi-4092b.firebaseapp.com

    【参考】
    Githubのmarkdownででかい画像のサイズを調整するには
    https://qiita.com/chezou/items/b62053636fb62a8b62a5
    画像を横に並べる 画像 並べ方
    http://yume.hacca.jp/koiki/gazo/yoko.htm
    【HTML入門】文章中にスペース(空白文字)を入れる3つの方法とは?
    https://www.sejuku.net/blog/50748#i-3


    スライドで表示するコンテンツが1つの場合は単純ですが、複数ある場合と閉じるボタンがある場合という条件があるスライドコンテンツの実装方法です。

    デモ

    デモ

    HTML

    index.html
    <ulclass="slideContent"><li><h2>見出しテキスト1</h2><divclass="inner"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam, quis, repudiandae neque incidunt quasi cumque quia id laudantium aspernatur impedit accusantium amet atque soluta tempore ex sequi pariatur blanditiis magnam.</p><pclass="close">閉じる</p></div></li><li><h2>見出しテキスト2</h2><divclass="inner"><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam, quis, repudiandae neque incidunt quasi cumque quia id laudantium aspernatur impedit accusantium amet atque soluta tempore ex sequi pariatur blanditiis magnam.</p><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam, quis, repudiandae neque incidunt quasi cumque quia id laudantium aspernatur impedit accusantium amet atque soluta tempore ex sequi pariatur blanditiis magnam.</p><pclass="close">閉じる</p></div></li>~~中略~~
    </ul>

    CSS

    CSSは見た目の調整以外では、最初にコンテンツを非表示にしておくために以下の指定をします。

    style.css
    .inner{display:none;}

    JavaScript

    script.js
    $(function(){if($('.slideContent').size()>0){//コンテンツの数varslideContentNum=$('.slideContent li').length;//コンテンツ分のフラグvarnavFlag=newArray();for(i=0;i<slideContentNum;i++){navFlag[i]=true;};//クリックした時の処理$('.slideContent h2').click(function(){//何個目のものがクリックされたかを確認varclickNum=$(this).parent().index();//フラグがtrueだったらif(navFlag[clickNum]){$(this).next('.inner').slideDown();$(this).addClass('current');navFlag[clickNum]=false;}else{$(this).next('.inner').slideUp();$(this).removeClass('current');navFlag[clickNum]=true;}});//閉じるをクリックした時の処理$('.slideContent .close').click(function(){varcloseNum=($(this).parents('li').index());$(this).parents('.inner').slideUp('fast');$(this).parents('.inner').prev('h2').removeClass('current');navFlag[closeNum]=true;});}});

    親のliが何番目のものかでフラグの番号をつけて開け締めをしています。

    よく忘れるのがコンテンツ分のフラグを作るところで、これが一個だけだと1番目押して開いた後に続けて2番目が開かないとか 2回クリックしないと動かないなどの現象が起きます。

    この記事の転載元

    複数のスライドダウンコンテンツを実装するjQuery


    firebaseでポートフォリオサイト作ってみた
    ※firebaseで動くのは静的ファイル(js,css,html)のみである

    初めにfirebaseにログインしプロジェクトを作成する。

    sample

    プロジェクト作成後にアプリを作成を選択しアプリを作る

    後にホスティングを利用する
     └ホスティングを利用するにはコマンドでアップするディレクトリにいる必要がある。

    開発用サーバーのコマンドは firebase serve
    デプロイはfirebase deploy

    完成サイト

    sample

    参考サイト
    https://qiita.com/Watakatsu/items/667f45081a6dfbc11074


    CSSのz-indexプロパティは何も指定しないと初期値autoですが、CSS仕様書9.9.1 Specifying the stack level: the 'z-index' propertyによると、autoのときThe stack level of the generated box in the current stacking contextMDN訳「現在の重ね合わせコンテキストで作られたボックスの重ね合わせレベル」)は0。一方、z-index: 0と指定すればこれも「現在の重ね合わせコンテキストで作られたボックスの重ね合わせレベル」が0。あれ?autoの場合と何が違うんでしょう?

    integer
    This integer is the stack level of the generated box in the current stacking context. The box also establishes a new stacking context.
    auto
    The stack level of the generated box in the current stacking context is 0. The box does not establish a new stacking context unless it is the root element.

    両者の違いは新しい重ね合わせコンテキストを作るかどうかにあるらしいのですが、説明読んだだけだとイマイチよくわからない。そこで、z-index: autoz-index: 0それぞれの場合に要素のレンダリングがどう違ってくるのかよくわかる例を作ってみました。

    サンプルの概要

    本記事に使ったサンプルのアニメーションについて、ソースコードはこちら。
    DEMO: https://codepen.io/kaz_hashimoto/pen/xxxpmOj

    HTMLのツリー構造の主要部分は以下のとおりです。

    html
    <divclass="b1 box">  <divclass="c1 child"></div>  <divclass="c2 child"></div>  <divclass="c3 child"></div></div><divclass="b2 box">  <divclass="c1 child"></div>  <divclass="c2 child"></div>  <divclass="c3 child"></div></div>

    このDEMOではアニメーションの各ステップで、z-indexなどのCSSプロパティをJavaScriptからdivにインラインで埋め込んでいます。具体的なCSSプロパティ値については、Chrome DevToolsなどブラウザのインスペクタから確認できます。

    z-index値を動かして表示の変化を見る

    最初の状態

    始めに、DEMOを開いた時の状態です(下図)。要素b1, b2にposition: relative、子要素c1, c2, c3にposition: absoluteを設定し、子要素の位置を互いにずらして配置しました。

    00.png

    見分けやすいよう上側のbox(b1)にはラベルAを、下側のbox(b2)にはラベルBを表示してあります。さらに子要素の背景色をc1 青#b0cdeb, c2 黄#fff9a5, c3 ピンク#f9b8bcで塗り分けました。

    各要素のz-index値はBのみz-index: 0を設定し、ほかはすべて指定なし(初期値auto)です。また、図にはJavaScriptのgetComputedStyle()で取得したz-indexの計算値を表示してあります。この図の段階では、要素の重ね合わせに関してABの表示に差はまだありません。

    ちなみに、子要素の重ね順がc3#f9b8bc> c2#fff9a5> c1#b0cdebになるのは、DOMを「行きがけ順に深さ優先」のtree orderで辿ることにより、HTMLで後ろに書いた方の要素が手前に描画されるためです。

    参考) CSS仕様書Appendix E. Elaborate description of Stacking Contexts

    Preorder depth-first traversal of the rendering tree,

    およびPainting order #8

    8. All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order.(以下略)

    autoと0の違いはココ!

    本題に戻り、最初の状態からABの子要素c2#fff9a5だけを引き出して、それぞれz-indexを-1に設定してみましょう(下図)。すると衝撃の事実がわかります(笑)
    01.gif
    ご覧のように、z-index: autoAではc2#fff9a5Aの裏側に移動したのに対して、z-index: 0に設定したBでは、c2#fff9a5Bの手前に留まっています。両者で重ね順に違いが生じるのはなぜでしょうか?そのカギは上述Appendix EのPainting order #8にありそうです。

    (中略) For those with 'z-index: auto', treat the element as if it created a new stacking context, but any positioned descendants and descendants which actually create a new stacking context should be considered part of the parent stacking context, not this new one. For those with 'z-index: 0', treat the stacking context generated atomically.

    まず、9.9.1によると、基本的に

    • root要素(背景黒#2d2d2d)は、root stacking contextを形成する。
    • 各boxはどれか1つの重ね合わせコンテキストに所属する。

    そこで、各boxの「現在の重ね合わせコンテキスト」=「所属する重ね合わせコンテキスト」に着目して項目の関係を分析すると下表のようになります。
    (SC: Stacking Context)

    boxz-indexstack level新SCの生成生成したSC a所属SC
    Aauto0No-root SC
    Aのc2#fff9a5-1-1Yessc1root SC b
    Aのc1#b0cdeb, c3#f9b8bcauto0No-root SC
    B00Yessc2root SC c
    Bのc2#fff9a5-1-1Yessc3sc2 c
    Bのc1#b0cdeb, c3#f9b8bcauto0No-sc2

    a) 「生成したSC」と「所属SC」との紐付けがわかるように、便宜上識別子を付けました。
    b) 上述の「... should be considered part of the parent stacking context」より、親要素Aの所属SCの一部とみなされる。
    c) 上述の「... For those with 'z-index: 0', treat the stacking context generated atomically」より、Bが作る重ね合わせコンテキストsc2は不可分であり、Aのようにc2を分離して扱わない。

    そして、重ね順の決め方は9.9.1によると、

    (中略) an integer stack level, which is its position on the z-axis relative other stack levels within the same stacking context. (中略) Boxes may have negative stack levels. Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.

    とのことなので、所属SCが同じグループのboxどうしのstack levelを比較して、tree orderも考慮すると最終的な重ね順は以下のようになります。(番号が小さい方がユーザーから見て奥側)

    重ね順boxz-indexstack level生成SC所属SC
    1Aのc2#fff9a5-1-1sc1root SC
    2Aauto0-root SC
    3Aのc1#b0cdebauto0-root SC
    4Aのc3#f9b8bcauto0-root SC
    5B00sc2root SC
    6Bのc2#fff9a5-1-1sc3sc2
    7Bのc1#b0cdebauto0-sc2
    8Bのc3#f9b8bcauto0-sc2

    確かにAのc2#fff9a5Aより奥に、Bのc2#fff9a5Bより手前になります。

    ところで、サンプルの図中に表示している「z-index: 0」などのテキストはp要素で埋め込んでいるため、DOMのノードとしてはBとは別物なので、重ね順の計算上はABなどのboxとは分けて扱われます。たとえば下図で示したように、Bのc2#fff9a5のtop位置を上にずらしていくと、c2のborder+背景+コンテンツのテキストがBのラベル「z-index: 0」の下に潜り込んでしまうのがわかります。(重ね順を見分けやすいようフォントサイズと色も変えました)

    02a.gif

    これは9.9.1の以下の説明のとおり、Bの子孫どうしの中で、位置指定されてないp要素の方が、z-index: -1のc2#fff9a5より描画順が後ろ(手前に)になるためです。

    Within each stacking context, the following layers are painted in back-to-front order:
    1. the background and borders of the element forming the stacking context.
    2. the child stacking contexts with negative stack levels (most negative first).
    3. the in-flow, non-inline-level, non-positioned descendants.
    (略)

    このDEMOでは重ね順を視覚的にわかりやすいように、boxとラベルのテキストを一体であるかのように表示していますが、より正確にはboxとは「div要素のbackground+border」を指しており、コンテンツは含まれません。


    表題の「autoと0の違い」については以上で明確になりました。ついでに、このDEMOを使ってz-indexのそのほかの振る舞いも見ていきたいと思います。

    重ね合わせコンテキストをまるごと移動

    前節に図示した状態から、Bの位置を移動して矩形の一部をAに重ねてみましょう。8個のboxが、前節の表で割り出した重ね順に従っていることがわかります(下図)。
    02.gif

    重ね合わせコンテキストの概念を現実のモノに例えると、付箋を貼った1枚の書類を机に重ねていく様子をイメージするとわかりやすいかもしれません。サンプルの図にあてはめると、

    • #2d2d2dの背景が机の表面
    • 書類ABがあり、それぞれ3枚付箋を貼ってある
    • 書類の表面に付箋用の「重ね合わせコンテキスト」が形成される
    • 付箋にはstack levelが割り当てられ、その書類に貼られる付箋どうしの重なり順を決めている
    • 書類にもstack levelが割り当てられ、机に書類を重ねて置く時の重なり順を決めている

    CSSを書いていて、z-indexが効かないように見えたり、難しく感じたりする理由の1つは、「付箋のstack level」と「書類のstack level」が頭の中でごっちゃになってしまうことです。次の例で見てみましょう。

    Stack Levelのスコープ

    前節の図で、Bとその子要素c1#b0cdeb, c2#fff9a5, c3#f9b8bcのz-indexをすべて整数値に変えてみます(下図)。
    03.gif
    Bとc2#fff9a5に着目すれば、「重ね合わせコンテキスト」と呼ばれる理由がよくわかります。Bのz-indexを100に増やして、c2#fff9a5のz-indexを-200に大きく減らしても、c2は依然Bの上に描画されます。これはstack levelが比較される対象(コンテキスト)が両者で異なるためです。

    • c2#fff9a5のstack level=-200が比較される対象は、Bが生成した重ね合わせコンテキスト内の要素c1, c2, c3のstack level。結果、それらの中で最小値を持つc2がスタックの最下位に描画される。
    • Bのstack level=100が比較される対象は、Bが所属する重ね合わせコンテキスト内の要素(Aや、Aのc2)のstack level。親要素と子要素のz-indexを比較しても意味がない

    z-indexが及ぶ範囲

    最後に、Aとその子要素のz-indexもいろいろ変えてみました(下図)。
    04.gif
    以下の2点に注目です。

    • Aのc1#b0cdeb, c3#f9b8bcのz-index値をいくら大きくしても、重ね順はBとその子要素より上にならない。stack levelは重ね合わせコンテキストをまたがって比較されない。
    • Aのz-indexをautoから整数値に変えると、Aのc2#fff9a5Aの裏側から前面に移動する。Aが新たに重ね合わせコンテキストを生成したため、c2のz-indexはそちらのコンテキスト内でのstack levelになる。

    先ほどの「書類と付箋」の関係に例えると、前者は、書類Aに貼った付箋どうしの重ね順を変えているだけであり、重ね順の番号(z-index)にどんなに大きな数字を割り当てても付箋が飛び越えて前面の書類Bの上に混ざることはない、というイメージですね。


    CSSを覚えたての頃、私は漠然と「z-indexを大きくすれば最前面に表示されるだろう」と実際やってみてそうならなかったり、z-indexに-1を設定したのにboxがしつこく前面に表示されたりして原因がわからずハマったことが度々ありました。今回サンプルを作ってみて、z-indexの振る舞いに関する疑問が解消しました。


    概要

    前回:【ASP.NET Core MVC】ASP.NET Core MVCであみだくじを作ってみる 3 (モデルの追加)
    今回は、cssを使ってビューのレイアウトを作成していきます。
    コントローラー間でのモデルデータの受け渡しも考えてみます。

    コントローラー間でモデルを受け渡す

    ASP.NET Core でのセッションとアプリの状態をざっと読み、TempDataを使うことにしました。
    HomeControllerのIndexアクションに、モデルデータをTempDataにセットする処理を追加します。

    HomeController.cs
    usingNewtonsoft.Json;/// <summary>/// HomeビューでPOSTした時のアクション/// </summary>/// <param name="name"></param>/// <param name="model"></param>/// <returns></returns>[HttpPost]publicIActionResultIndex(stringname,KujiModelmodel){// 入力エラーがある時は何もしないif(!ModelState.IsValid)returnView(model);// [結果を設定する]ボタンを押下した場合if(name=="set"){// くじの数が減った場合は、結果入力欄を減らすwhile(model.NumberOfKuji<model.Result.Count){model.Result.RemoveAt(model.Result.Count-1);}// くじの数が増えた場合は、結果入力欄を増やすwhile(model.NumberOfKuji>model.Result.Count){model.Result.Add(newResultModel());}returnView(model);}TempData["kuji"]=JsonConvert.SerializeObject(model);// くじコントローラーを呼ぶreturnRedirectToAction("Index","Kuji");}

    TempData["kuji"] = model としたくなるところですが、オブジェクトはセットできないようです。
    このため、JsonConvert.SerializeObjectでjson文字列に変換してからセットしました。

    KujiController側で、TempData["kuji"]を受け取ります。

    KujiController.cs
    usingAmidakuji.Models;usingMicrosoft.AspNetCore.Mvc;usingNewtonsoft.Json;namespaceAmidakuji.Controllers{publicclassKujiController:Controller{[HttpGet]publicIActionResultIndex(){ModelState.Clear();// 受け取ったTempDataからデータを取得するvarjson=TempData["kuji"]?.ToString();if(json!=null){varmodel=JsonConvert.DeserializeObject<KujiModel>(json);returnView(model);}returnView(newKujiModel());}}}

    JsonConvert.DeserializeObjectで、json文字列をKujiModel型にデシリアライズしています。
    デシリアライズ後のモデルをビューに渡すことで、Homeビューで入力したデータをKujiビューでも使えるようになります。

    cssファイルを追加する

    JavaScript、CSS、画像等の静的ファイルは、Webルート(既定ではwwwroot)ディレクトリに格納されています。
    ASP.NET Core MVCでは、デフォルトのcssフレームワークとしてBootstrapが導入されていますが、
    今回はオリジナルのcssを作ります。

    ソリューションエクスプローラーの「wwwroot\css」を選択します。
    右クリックでメニューを表示し、追加⇒新しい項目を選択します。
    スタイルシートを選択します。ここでは、名前を「kuji.css」としました。
    css.PNG
    Home\Index.cshtmlやKuji\Index.cshtmlの<style>をcssに移動します。
    各cshtmlの<style>~<\style>は削除しておきます。

    kuji.css
    /*あみだくじデータの設定領域*/.kuji-items{display:grid;/*グリッドレイアウトにする*/grid-auto-columns:100px;/*1列あたりの幅 100px*/grid-auto-rows:36px;/*1行あたりの高さ 30px*/background-color:#99CCCC;/*背景色*/margin:0pxauto;/*中央寄せ*/padding:10px;}/*あみだくじデータの設定領域の入力項目*/.kuji-items>input{height:30px;/*高さ*/}/*くじを作るボタン*/.create_btn{font-weight:bold;/*太文字*/padding:0.25em0.5em;/*文字余白*/text-decoration:none;/*文字装飾なし*/color:#FFF;/*文字色*/background:#008080;/*背景色*/margin-left:10px;/*左側余白*/height:30px;/*高さ*/}/*くじコンテナ*/.kuji-container{height:100px;/*高さ*/background-color:#CBFFD3;/*背景色*/}

    「Views\Shared\_Layout.cshtml」の<head>内にcssへのリンクを追加します。

    _Layout.cshtml
    <head><metacharset="utf-8"/><metaname="viewport"content="width=device-width, initial-scale=1.0"/><title>@ViewData["Title"] - Amidakuji</title><linkrel="stylesheet"href="~/lib/bootstrap/dist/css/bootstrap.min.css"/><linkrel="stylesheet"href="~/css/site.css"/><!-- kuji.cssを追加 --><linkrel="stylesheet"href="~/css/kuji.css"/></head>

    cssにUIを定義する

    試行錯誤の結果、あみだ部分はグリッドレイアウトを利用することにしました。
    kuji.cssに以下を追加します。内容はコードにコメントで書きました。

    kuji.css
    ・・・省略・・・/*タイトル*/.kuji-container>h1{color:#000000;/*文字色*/background:#E6FFE9;/*背景色*/border-bottom:solid3px#0000FF;/*下線*/}/*説明文*/.kuji-container>p{color:#000000;/*文字色*/border-bottom:solid3px#0000FF;/*下線*/}/*あみだくじの領域*/.kuji-line{display:grid;/*グリッドレイアウトにする*/grid-auto-columns:minmax(10px,auto);/*1列あたりの幅 10px以上*/grid-auto-rows:minmax(25px,auto);/*1行あたりの高さ 25px以上*/background-color:#99CCCC;/*背景色*/position:relative;/*後述の「あみだを隠すためのマスク領域」の基準点とするためにrelativeを指定*/}/*あたり・はずれ等の結果*/.kuji-line>div{margin:0pxauto;/*中央寄せ*/}/*縦線*/.vertical-line{background-color:#000000;/*背景色*/width:1px;/*幅*/height:auto;/*高さ*/margin:0pxauto;/*中央寄せ*/}/*横線*/.horizontal-line{background-color:#000000;/*背景色*/width:100%;/*幅*/height:1px;/*高さ*/margin-left:50%;/*左マージン 縦線を中央寄せしているため、幅50%分をずらして縦線の位置から始める*/}/*くじを辿る時の縦線*/.vertical-line.follow{background-color:#FF0000;/*背景色*/width:3px;/*幅*/}/*くじを辿る時の横線*/.horizontal-line.follow{background-color:#FF0000;/*背景色*/height:3px;/*幅*/}/*選択肢ボタン*/.select-btn{color:#0000FF;/*文字色*/width:25px;/*幅*/height:25px;/*高さ*/border-radius:50%;/*角丸 50%で円になる*/border:solid2px#0000FF;/*枠線*/text-align:center;/*文字の中央寄せ*/margin:0pxauto;/*中央寄せ*/}/*選択肢ボタンのマウスオーバー時*/.select-btn:hover{background-color:#6495ED;/*背景色*/}/*選択したボタン*/.select-btn.selected{color:#FF0000;/*文字色*/border:solid2px#FF0000;/*枠線*/background-color:#FFDDFF;/*背景色*/}/*あみだを隠すためのマスク領域*/.mask{position:absolute;/*「あみだくじの領域」を基準点とするためにabsoluteを指定*/width:90%;/*幅 「あみだくじの領域」の90%の幅*/height:76%;/*高さ 「あみだくじの領域」の76%の高さ*/top:12%;/*上位置 「あみだくじの領域」の上から12%の位置*/left:5%;/*左位置 「あみだくじの領域」の左から5%の位置*/text-align:center;/*文字の中央寄せ*/border:solid2px#808080;/*枠線*/background-color:#E6FFE9;/*背景色*/background-image:radial-gradient(#80808010%,transparent20%),radial-gradient(#80808010%,transparent20%);/*背景画像*/background-size:10px10px;/*背景画像のサイズ(幅 高さ)*/}

    「あみだを隠すためのマスク領域」についての説明を補足します。
    背景画像に円形グラデーションを指定し、background-sizeで幅、高さを10pxに揃えることで円を描いています。
    この円が、マスク領域のサイズ分繰り返されます。

    定義したcssを使ってビューをあみだくじっぽくする

    Kuji\Index.cshtmlを以下のように変更します。
    くじの数は5本固定で、マスク領域を隠したり表示したりする機能はありません。
    このあたりは、次回Razorの学習で改善していくつもりです。

    Kuji\Index.cshtml
    @model Amidakuji.Models.KujiModel
    
    @{
        ViewData["Title"] = "あみだくじ";
    }
    
    <divclass="kuji-container"><h1>@Model.Title</h1><p>くじの数は、@Model.NumberOfKuji 本です。</p><!--あみだくじの領域(グリッドレイアウト)--><divclass="kuji-line"><!--選択肢ボタン--><ahref="#"class="select-btn"style="grid-row:2;grid-column:1">1</a><ahref="#"class="select-btn"style="grid-row:2;grid-column:2">2</a><ahref="#"class="select-btn"style="grid-row:2;grid-column:3">3</a><ahref="#"class="select-btn"style="grid-row:2;grid-column:4">4</a><ahref="#"class="select-btn"style="grid-row:2;grid-column:5">5</a><!--縦線--><divclass="vertical-line"style="grid-row:3 / span 15;grid-column:1"></div><divclass="vertical-line"style="grid-row:3 / span 15;grid-column:2"></div><divclass="vertical-line"style="grid-row:3 / span 15;grid-column:3"></div><divclass="vertical-line"style="grid-row:3 / span 15;grid-column:4"></div><divclass="vertical-line"style="grid-row:3 / span 15;grid-column:5"></div><!--横線--><pclass="horizontal-line"style="grid-row:4;grid-column:1"></p><pclass="horizontal-line"style="grid-row:10;grid-column:1"></p><pclass="horizontal-line"style="grid-row:13;grid-column:1"></p><pclass="horizontal-line"style="grid-row:8;grid-column:2"></p><pclass="horizontal-line"style="grid-row:12;grid-column:2"></p><pclass="horizontal-line"style="grid-row:14;grid-column:2"></p><pclass="horizontal-line"style="grid-row:6;grid-column:3"></p><pclass="horizontal-line"style="grid-row:13;grid-column:3"></p><pclass="horizontal-line"style="grid-row:5;grid-column:4"></p><pclass="horizontal-line"style="grid-row:9;grid-column:4"></p><pclass="horizontal-line"style="grid-row:15;grid-column:4"></p><!--結果--><!--横幅を揃えるため、PadRightで5文字分に揃える--><divstyle="grid-row:18;grid-column:1">@Model.Result[0].Item.PadRight(5, ' ')</div><divstyle="grid-row:18;grid-column:2">@Model.Result[1].Item.PadRight(5, ' ')</div><divstyle="grid-row:18;grid-column:3">@Model.Result[2].Item.PadRight(5, ' ')</div><divstyle="grid-row:18;grid-column:4">@Model.Result[3].Item.PadRight(5, ' ')</div><divstyle="grid-row:18;grid-column:5">@Model.Result[4].Item.PadRight(5, ' ')</div><!--1行分を余白とする--><divstyle="grid-row:19;grid-column:1 / span 5"></div><!--あみだを隠すためのマスク領域--><divclass="mask"></div></div></div>

    「grid-row:2;grid-column:1」という書き方をしている箇所があります。
    これは、グリッドレイアウトの中で、2行目の1列目、という意味です。
    「grid-column:1 / span 5」等となっている箇所は、1列目から始めて5列分の領域という意味です。
    Excelのセル結合を思い浮かべると分かりやすいかもしれません。

    実行してみる

    マスク領域あり
    デザイン①.PNG
    マスク領域なし
    デザイン②.PNG

    まとめ

    今回は、cssを使ってビューのレイアウトを作成しました。
    次回は、Razorを使ってマスク領域を隠したり表示したりする機能を作ります。
    次回分はこちら⇒ASP.NET Core MVCであみだくじを作ってみる 5 (Razorを使う)


    Sponsored Content
    Adskeeper

    ブラウザで動くWebページのプログラミング実装をフロントエンドと呼びます。
    最近はJSON色つけ係と呼ばれてたりしますが、
    Web開発未経験・初心者向けに最低限知っておいたほうが良い基礎知識とテクニックに関して体系的にまとめておきます。
    (CodePenによる動作例付き)

    環境構築に関しては(兎に角)早くプロトタイプを作る技術(初心者向け)を参考にしてください。

    HTML、CSS、JavaScriptはブラウザ自体の実装に依存します。
    この記事では比較的汎用的に使える書き方やHTML、CSS、JSを記載したつもりですが
    最新のJavaScript APIやCSS3の機能によってはブラウザによってサポートされていない機能もあります。(特にIE)
    各機能に関してはCan I useで現在のブラウザの対応状況を確認することができます。

    HTML

    HTML(Hyper Text Markup Language)は、ウェブページを作成するために開発された言語です。
    現在、インターネット上で公開されてるウェブページのほとんどは、HTMLで作成されています。
    タグと呼ばれる<>で囲われた命令文で記述します。
    <>子要素</>のような階層構造を記述できる形式になっています。
    ブラウザはHTML構造を解釈して内容を画面上に表示(レンダリング)します。
    DOM(Document Object Model)とも呼びます。

    基本構造

    <div>子要素
    </div>

    入れ子で階層的に書くことができます

    <div><div><div>要素1
        </div></div><div>要素2
      </div></div>

    特に子要素がない場合は、末尾/>でクロージングします(セルフクロージング)

    <div/>

    よく使うタグ

    • html: HTMLページであることを示すタグ
    • title: ページのタイトルを記述するためのタグ
    • meta: ページのメタ情報を記述するためのタグ
    • head: ページのヘッダー部分を記述するためのタグ
    • body: ページのボディ(メイン)部分を記述するためのタグ
    • div: ブロックの塊を示します、レイアウトを組むときに主に使います。
    • ol: 順序ありリスト
    • ul: 順序なしリスト
    • details, summary, dl: 展開式の要素です。summaryに展開するタイトル、dlに展開する子要素を記述します。
    • table, tbody, th, tr, td: テーブル要素、thに見出し、tr単位に行作成、tdに内容を記述します。
    • h1, h2, h3, h4, h5, h6: 見出し要素、h1, h2...の数字が大きくなるにつれて見出しが小さくなります。
    • p: パラグラフ、文章を記載します。
    • span: デザイン微調整によく利用されるタグ(インライン要素)
    • form: フォーム要素。ユーザに入力してもらったデータをサーバに送信する用途で使います。
    • label: ラベル要素。フォーム要素の中で使われることが多いです。
    • input: 入力欄要素。フォーム要素の中で使われることが多いです。
    • button: ボタン要素。ユーザインタラクティブのトリガーとして使われます。
    • a: ハイパーリンク要素。別ページへのリンクやページ内リンク(アンカーリンク)として使われます。
    • img: イメージ要素
    • audio: 音声プレイヤー要素
    • video: 動画プレイヤー要素
    • canvas: 2D、3Dのグラフィックを描画するための領域
    • style: スタイル要素(CSS等)
    • script: スクリプト要素(JavaScript等)

    ブロックレベル要素、インライン要素

    タグにはブロックレベル要素のタグ、インライン要素のタグがあります。
    一般的なブラウザではブロックレベルの要素のタグは改行され、インライン要素のタグは改行されません。
    ブロックレベル要素の子要素にインライン要素のタグを子要素にできますが、
    インライン要素のタグにブロックレベル要素のタグを子要素にしてはいけません。
    (ブロック要素のタグの文章などを記載するのがインライン要素のタグの役割)

    参考:ブロックレベル要素とインライン要素

    属性値(attribute)

    タグの種別によって属性値をもつ場合があります。
    次の例はinputタグのtype属性値を指定する場合です。
    type属性値にtextを指定すると入力欄が作成されます。

    <inputtype='text'placeholder='入力欄'/>

    See the Pen input by teradonburi (@teradonburi) on CodePen.

    type属性値にbuttonを指定して、value属性値に「ボタン」という文字を指定するとボタンに変わります。

    <inputtype='button'value='ボタン'/>

    See the Pen button by teradonburi (@teradonburi) on CodePen.

    このように属性値を変えることでタグの振る舞いが変わります。

    id

    id属性を指定することで後述のCSSやJavaScriptからタグを参照することができます。
    idはそのページでユニークな値にする必要があります。

    See the Pen id by teradonburi (@teradonburi) on CodePen.

    class

    class属性を指定することで後述のCSSやJavaScriptからタグを参照することができます。
    idと違って、複数のタグに対して指定することができ、一括でスタイルを適用したい場合などに重宝します。

    See the Pen class by teradonburi (@teradonburi) on CodePen.

    Webページの最低限のHTML構造

    最低限のhtmlは次のようになっています。(HTML5)
    metaタグのviewportに関してはモバイルでは割と必須感あるので最低限のものとして入れています。
    <!-- -->で囲われた部分はコメントと呼び、ブラウザで処理されないコードです。

    <!DOCTYPE html><htmllang="ja"><head><title>タイトル</title><!-- モバイル用の表示設定 --><metaname="viewport"content="width=device-width, initial-scale=1"/></head><body><!-- ここに表示したいタグを追加 --></body></html>

    基本的に次のような階層構造になっている必要があります。

    - html
      - head
        - title 
        - meta
      - body
    

    ほとんどのタグはbody部分に追加していきます。(主にページに表示されるタグ)

    div

    コンテンツの塊の親要素として使う事が多いです。レイアウトの調整にも使います。
    (CSS flexboxの項にて説明)

    リスト

    olタグは順序ありリスト、ulタグは順序なしリストとして表示されます。

    See the Pen list by teradonburi (@teradonburi) on CodePen.

    展開式リスト

    details, summary, sl, dtタグを使うことで展開式のリストの作成ができます

    See the Pen details by teradonburi (@teradonburi) on CodePen.

    tableタグを使うことで表を作成することができます。
    表のタイトルにcaptionタグ、見出しにthead、thタグ、表内容にtbodyタグ、行にtrタグ、tdタグなどを使います

    See the Pen table by teradonburi (@teradonburi) on CodePen.

    見出し、パラグラフ、span

    h1~h6は見出しタグです。数字が大きくなるにつれて小さくなります。
    ちなみにページ先頭のh1タグにはGoogleの検索結果に表示されるという特性があります。
    pタグには文章を書きます。
    h、pタグはブロックレベル要素のため、改行されます。
    h、pタグともにデフォルトで余白(margin、padding)があります。
    spanタグはインライン要素のため、改行されずに横に並びます。

    See the Pen h,p,span by teradonburi (@teradonburi) on CodePen.

    リンク

    aタグでリンクを作成できます。href属性でリンク先を指定、_blank属性で別タブで開きます。
    idとhrefに#id名を指定することでページ内リンク(アンカーリンク)に飛ぶことができます。

    See the Pen a by teradonburi (@teradonburi) on CodePen.

    フォーム

    フォーム入力欄を作成するにはformタグを使用します。
    action属性にはデータを送信する先のurl(サーバAPI)を指定します。
    method属性にはHTTPメソッドを指定します。通常はPOSTを指定します。(HTTPメソッドでよく使うものにはGET、POST、PUT、DELETEがあります)
    enctype属性にはMIMEタイプを指定します。ファイル等まで全て添付して送信する場合はmultipart/form-dataを指定します。
    送信する対象のデータに関しては、inputタグもしくはselectタグ、textareaタグのいずれかに対してname属性を指定します。
    入力した内容はvalueパラメータとしてサーバに送信されます。
    inputタグのtype属性は色々な種別の入力欄に対応しています。
    注意したいのは、ブラウザによってinputタグの表示が異なることです。
    (このため、入力のUIとしてライブラリを使うことも少なくありません)

    • text: 1行テキスト
    • email: メールアドレス
    • password: パスワード
    • radio: ラジオボタン
    • checkbox: チェックボックス
    • range: スライダー
    • number: スピナー
    • color: カラーパレット
    • date: 日付
    • time: 時間
    • file: ファイル
    • hidden: 隠しパラメータ(入力欄としては表示しないがサーバに送信するパラメータ。value属性と併用することが普通でCSRF対策に主に使う)
    • submit: 送信ボタン

    複数テキストはtextareaタグ、選択リストタグはselect+optionタグを使います。
    また、inputタグ、textareaタグにrequired属性をつけることで必須項目となります。
    (入力欄が空の場合にsubmitボタンが押せない)

    See the Pen form by teradonburi (@teradonburi) on CodePen.

    画像、音声、動画

    画像の表示にはimgタグを使います。src属性に画像のurlを指定します。
    音声ファイルの再生にはaudioタグを使います。src属性もしくはsourceタグのsrc属性を使い音源のurlを指定します。
    (sourceタグは複数追加することができ、mp3以外の予備の音源を用意することで、mp3が再生できないブラウザでも再生できるようになります。)
    controls属性を指定することでプレイヤーコントロールを表示させることができます。(プレイヤーのUIに関してはブラウザによって表示が異なるので注意)
    動画ファイルの再生にはvideoタグを使います。audioタグとほぼ同じですがwidth, height属性で動画の表示サイズを変更できます。

    See the Pen img, audio, video by teradonburi (@teradonburi) on CodePen.

    余談ですが、音声はmp3形式、動画がmp4形式のほうが再生できるブラウザが多いです。(大体のブラウザがサポートしている)

    canvas

    JavaScriptと組み合わせて描画処理することが普通なのでJavaScriptの項目で説明

    style

    styleタグにはCSSと呼ばれる、タグのスタイルやレイアウトを変更するためのスクリプトを記述できます(詳細はCSSの項で説明)
    headタグの子要素として記述します。
    styleタグ内に囲まれた部分でCSSを記述します。

    <head><style type="text/css">p{color:red;}</style></head>

    外部のCSSファイル(.cssファイルとして保存できる)を呼び出す場合は、linkタグを使います。
    href属性に読み込むCSSファイルを指定します。
    rel属性はstylesheet、type属性にはtext/cssを指定します。

    <head><linkhref="main.css"rel="stylesheet"type="text/css"/></head>

    script

    scriptタグの内部にはスクリプトを記述できます。type属性にtext/javascriptを指定するとJavaScriptの処理を記述できます。(詳細はJavaScriptの項で説明)

    <script type="text/javascript">window.onload=function(){// DOMが読み込み完了したときの処理}</script>

    外部のJavascriptファイル(.jsファイルとして保存できる)を呼び出す場合は、src属性を使います。

    <script type="text/javascript"src="main.js"></script>

    CSS

    HTMLタグのレイアウトの調整、装飾、アニメーションを担当するスクリプト言語です。
    HTMLがページの構造だとすれば、CSSは表示の見た目(スタイル)を修正するための言語です。
    CSSファイルをlinkタグで読み込む、styleタグ内にCSSを記述する、もしくはstyle属性でタグに直接指定(インライン)することができます。

    <divstyle='color:orange;'>要素</div>

    セレクタ

    CSSのスタイルをタグに割り当てるには、どのタグを対象にするかという適応範囲をセレクタで指定します。
    よく使われるセレクタに次のようなものがあります。

    参考:セレクタ

    名称セレクタの書式セレクタの対象使用例備考
    全称セレクタ*すべての要素* {color:red;}影響範囲が広すぎるのであまり使わないほうが良い
    要素型セレクタ要素名要素名で指定した要素p {color:blue;}
    idセレクタ要素名#id名id名が指定された要素div#sample {color:green;}影響範囲が明示的なので積極的に使いたい
    classセレクタ要素名.class名class名が指定された要素div#sample {color:green;}影響範囲が明示的なので積極的に使いたい
    擬似クラス要素名:link未訪問のリンクa:link {color:black;}基本的にaタグのみ使える
    要素名:visited訪問済のリンクa:visited {color:red;}基本的にaタグのみ使える
    要素名:hoverカーソルが乗っている要素a:visited {color:red;}
    要素名:activeクリック中の要素a:visited {color:red;}基本的にクリック可能な要素で使える
    要素名:focusフォーカスされている要素input:focus {background:grey;}基本的にフォーカス可能な要素で使える
    要素名:first-child要素内の最初の子要素h1:first-child {color:purple;}
    要素名:last-child要素内の最後の子要素h1:last-child {color:purple;}
    要素名:nth-child(n)要素内のn番目の子要素h1:nth-child(2) {color:purple;}
    疑似要素要素名:first-line要素の最初の行h2:first-line {color:green;}
    要素名:first-letter要素の最初の文字h2:first-letter {color:red;}
    要素名:before要素の直前h3:before {content:"『";}
    要素名:after要素の直後h3:after {content:"』";}
    属性セレクタ要素名[属性名]特定の属性を持つ指定要素a[target] {color:pink;}
    要素名[属性名="属性値名"]特定の属性値を持つ指定要素a[target="_blank"] {color:lightgreen;}
    要素名[属性名~="属性値名"]属性値候補(ホワイトスペース区切り)に属性値名を持つ要素a[class*="sample"] {color:aqua;}
    要素名[属性名*="属性値名"]属性値候補に属性値名を持つ要素a[class*="sample"] {color:aqua;}
    要素名[属性名^="属性値名"]属性値が属性値名で始まる要素a[class^="sam"] {color:aqua;}
    要素名[属性名$="属性値名"]属性値が属性値名で終わる要素a[class$="ple"] {color:aqua;}
    複合セレクタセレクタ,セレクタ複数のセレクタのスタイルを一括で指定h4, h5 {color:black;}
    子孫セレクタセレクタ セレクタ下の階層の子孫要素div section {color:black;}
    子セレクタセレクタ>セレクタ直下の階層の子要div > article {color:grey;}
    隣接セレクタセレクタ+セレクタ直後に隣接している要素article + p {color:orange;}
    後ろセレクタセレクタ~セレクタ要素の後ろにある同じ階層の要素h1 ~ p {color:orange;}

    See the Pen cssセレクタ by teradonburi (@teradonburi) on CodePen.

    スタイルの優先順位と!important

    ある要素が複数のセレクタから選択された場合にどのスタイルが適応されるか優先順位が決まっています。
    (特に問題になるのが、複数のセレクタから同じスタイルを当ててる場合です。)

    参考:CSSセレクタの優先順位の計算方法

    次の例はcolorスタイルをdivに対して指定してます。
    本来であれば、last-childのほうがclassに対して優先順位が低いのですが、!importantを付与することで優先順位が逆転しています。

    See the Pen !important by teradonburi (@teradonburi) on CodePen.

    以下のように優先順位を覚えておくと良いでしょう
    !important > タグのstyle属性(インライン) > id > class=属性セレクタ > その他
    ただし、!importantは以下の点から極力使わないほうが良いでしょう

    • 表示のパフォーマンスが落ちる(重複している無駄なスタイルを削除する方を優先したほうが良い)
    • そもそもidやclassで代用できるはず
    • !importantで書いてしまうと後勝ちの!importantでしか上書きできなくなる(このため、優先順位がわからなくなりCSSの修正が困難になる)

    width, height, margin, padding

    タグ自体の幅、高さを指定するにはwidth, heightを使います。
    外側の余白を指定するにはmargin、内側の余白を指定するにはpaddingを使います。

    幅、高さ、余白に関しては単位指定します。
    よく使う単位にpx,%,vw(vh)などがあります。

    width:100px;/* px指定 */width:100%;/* (親要素に対する幅)%指定 */width:50vw;/* ビューポート(画面幅)に対する割合指定(100vwで画面全幅) */height:100px;/* px指定 */height:100%;/* (親要素に対する高さ)%指定 */height:50vh;/* ビューポート(画面高さ)に対する割合指定(100vhで画面全高さ) */margin:10px;/* 外側余白10px */padding:10px;/* 内側余白10px */

    また、
    min-width, min-heightで最小の幅、高さを指定
    max-width, max-heightで最大の幅、高さを指定
    することができます。
    (width, heightの%と組み合わせることが多いです)

    margin,paddingに関しては一括で指定する方法と個別に指定する方法があります。

    margin:10px;/* 上下左右10px */margin:10px5px;/* 上下10px左右5px */margin:5px6px7px8px;/* 上5px右6px下7px左8px(時計周り) */margin-top:10px;/* 上10px */margin-right:10px;/* 右10px */margin-bottom:10px;/* 下10px */margin-left:10px;/* 左10px */padding:10px;/* 上下左右10px */padding:10px5px;/* 上下10px左右5px */padding:5px6px7px8px;/* 上5px右6px下7px左8px(時計周り) */padding-top:10px;/* 上10px */padding-right:10px;/* 右10px */padding-bottom:10px;/* 下10px */padding-left:10px;/* 左10px */

    See the Pen dyyRRwo by teradonburi (@teradonburi) on CodePen.

    border

    枠線を指定できます。
    border: border-width border-style border-color;を指定します。

    参考:border-style

    See the Pen border by teradonburi (@teradonburi) on CodePen.

    background

    タグの背景を指定します。
    background-colorで背景色を指定します。
    background-imageでurlと組み合わせて背景画像を指定します。
    background-repeatで背景画像の繰り返しするか指定します。no-repeatだと繰り返ししません。
    background-sizeで背景画像のタグに対してどの形式のサイズで表示されるかを決めます。
    よく使うものでcontainだと背景画像のアスペクト比を保ったままタグの幅高さに合うように内側で表示されます。
    coverだと背景画像のアスペクト比を保ったままタグの外側に背景画像が見切れて表示されます。
    background-positionで背景画像の表示位置を決めます。centerはタグの中央に背景画像を表示します。
    background-size:contain; background-position:center;もしくはbackground-size:cover; background-position:center;の組み合わせはよく使います。

    See the Pen background by teradonburi (@teradonburi) on CodePen.

    background-sizeによく似たスタイルにimgタグ、videoタグのobject-fitスタイルがあります。
    こちらもかなり便利なのですが、IEで使えないという問題点があります。
    (そのためpolyfillを入れて対応するなどの手段が必要になります。)

    See the Pen object-fit by teradonburi (@teradonburi) on CodePen.

    color, font-size, font-weight, line-height, text-align

    文字色を変えるにはcolorで色を指定します。
    blueなどのカラーネームで指定するか、
    #FF0000のような16進数のカラーコードで指定します。(RGB)
    font-sizeで文字のサイズを指定します。
    font-weightで文字の太さを指定します。boldを指定すると太文字になります。
    line-heightはテキスト同士の行間を指定することができます。
    text-alignはテキストの並びを指定します。centerで中央寄せになります。
    注意点としては上記の文字に関するスタイルは子要素全てに適応されます。

    See the Pen color, font-size, font-weight, line-height, text-align by teradonburi (@teradonburi) on CodePen.

    font-family, webfont

    font-familyで表示するフォントを変更することができます。
    実はOSで使えるフォントが違うため、フォントがなかった場合に予備のフォントを複数指定しておくと良いです。
    また、独自のフォントファイル(ttf,woffなど)を読み込んで使うこと(WebFont)ができます。
    Google Fontsのようにホスティングで提供されている場合は
    @importで読み込むことができます。
    ファイルから読み込む場合は@font-faceのsrcで読み込みます。

    参考:font-familyの書き方まとめ:CSSでフォント種類を指定しよう
    参考:Font-familyメーカー

    See the Pen webfont by teradonburi (@teradonburi) on CodePen.

    position, left, top, right, bottom

    positionは何を起点にした位置関係を指定します。
    よく使うパターンは親要素をposition:relative;にして子要素にposition:absolute;の要素を作成します。
    こうすることで親要素を起点に子要素のtop, leftの位置調整をすることでタグ同士を重ねることができます。
    もう一つよく使うパターンはposition:fixedでページ全体のフッターやヘッダーを指定する場合です。
    ヘッダーの場合はtop: 0px;、フッターの場合はbottom: 0px;で配置できます。
    position:fixedになっているタグはスクロール時でもその位置が変わることはありません(スクロールに追従して同じ位置に残り続ける)
    position:stickyになっているタグはスクロール時にそのタグが見切れるタイミングになるとfixedに切り替わります。
    どこに残り続けるかの位置をtopもしくはbottomで指定します。
    ただし、position:stickyはIEが対応していないことに注意が必要です。

    See the Pen position by teradonburi (@teradonburi) on CodePen.

    display,visibility

    displayは要素の表示形式を指定します。
    よく使われるものにインライン要素をブロックレベル要素に変更したり(display: block)
    display:noneで要素を非表示にしたりします。
    非表示でよく似ているスタイルにvisibility:hiddenがありますが、こちらはレイアウトの状態は残っているため、
    span5の上にspan4の空白が残っています。
    visibility:hiddenの使いみちとしてはhtmlメールなどの開封確認やページのアクセスログを送信するために
    1x1pxのimgタグ(インプレッションピクセル)をvisibility:hiddenとして埋め込むなどの利用用途があります。
    他によく使うdisplay:flex、display:gridに関しては後述します。

    See the Pen display by teradonburi (@teradonburi) on CodePen.

    flexbox

    flexboxを使うには親要素にdisplay:flexを指定する必要があります。子要素が指定の配置になります。
    flex-directionは子要素の配置の向きを指定します。flex-direction:rowで横方向、flex-direction:columnで縦方向の配置になります。
    justify-contentは並べている向きに対して子要素をどちら側に寄せるか指定します。
    justify-content:flex-startを指定すると並べる向きの開始位置に寄ります。
    justify-content:centerを指定すると並べる向きの中央位置に寄ります。
    justify-content:flex-endを指定すると並べる向きの終了位置に寄ります。
    flex-directionの向きで縦横の寄せる向きが逆転していることに注意してください。
    align-itemsは並べている向きの垂直方向(flex-direction:rowの場合は縦向き、flex-direction:columnの場合は横向き)に対して子要素をどちら側に寄せるか指定します。
    align-items:flex-startを指定すると開始位置に寄ります。
    align-items:centerを指定すると中央位置に寄ります。
    align-items:flex-endを指定すると終了位置に寄ります。
    こちらもflex-directionの向きで縦横の寄せる向きが逆転していることに注意してください。
    flex-grow:1は子要素のサイズの伸び率を指定します。デフォルトは0ですが、並んでいる向きの子要素の累計で伸び率が決まります。
    flex-growの値がそれぞれ、0 1 0だとした場合、flex-directionの向きに中央が全余白を埋めるように伸びます。
    flex-wrapで折り返しするかの指定ができます。flex-wrap:wrapを指定すること折返しされます。
    ただし、justify-content:centerを指定している場合、最後の行が左寄せにならないため、dummy要素を作成して穴埋めするというテクニックを使っています。
    flexboxを駆使すればどんなレイアウトも柔軟に定義できるため、必修です。

    See the Pen flexbox by teradonburi (@teradonburi) on CodePen.

    他にも色々flexbox関連のスタイルがありますが、それだけで1つの記事ができてしまうので
    詳細は以下の記事などを参考にしてください。

    参考:もう迷わない!CSS Flexboxの使い方を徹底解説

    grid

    グリッド形式でレイアウト配置ができるため、大変便利なのですがIEは対応していません。
    前述のflexboxで対応するか、polyfillで対応する必要があります。
    グリッドレイアウトを使うには親要素にdisplay:gridを指定する必要があります。
    grid-template-columnsにfr(フレーム)という単位で横方向のトラック数を指定します。
    例えば、repeat(3, 1fr)は1frを3回繰り返すという意味なのでgrid-template-columns: 1fr 1fr 1fr;と同じになります。
    grid-auto-rowsはトラック当たりの高さ、grid-auto-columnsはトラック当たりの幅を指定します。
    column-gapはトラック間の縦方向の余白、row-gapはトラック間の横方向の余白を指定します。
    各トラックがどれくらいのフレームを使うのかを
    grid-column-start、grid-column-endで幅方向のフレーム数
    grid-row-start、grid-row-endで高さ方向のフレーム数
    を指定します。startに関しては1から開始することに注意が必要です。
    詳細は次の記事が説明わかりやすいので参考になります。

    参考:CSS Grid Layout を極める!(基礎編)

    See the Pen grid by teradonburi (@teradonburi) on CodePen.

    word-break,white-space

    word-breakは単語の折返しを指定します。デフォルトの状態では単語単位で折り返しされるため、要素の外にテキストがはみ出る場合があります。word-break:break-all;を使うことで単語途中でも折返しされるため、テキストが要素の外にはみ出ることはなくなります。
    white-spaceは空白文字や改行文字をどう扱うかを指定します。通常は空白文字などは無視されます。
    white-space:pre-wrapを使うと折返ししつつ、改行文字も考慮されるため良い感じな見た目になります。

    See the Pen white-space, word-break by teradonburi (@teradonburi) on CodePen.

    text-overflow、line-clamp

    text-overflow: ellipsisを使うことでテキストが要素内に入り切らなかった場合に...で省略されます。

    参考:text-overflow

    See the Pen text-overflow by teradonburi (@teradonburi) on CodePen.

    複数行の場合はline-clamp(IE以外)を使います。

    参考:CSSで複数行3点リーダーを実現する「line-clamp」がついにIE以外に対応したよ!

    See the Pen line-clamp by teradonburi (@teradonburi) on CodePen.

    shadow

    shadow(影)には二種類あります。テキスト自体に影をつけるtext-shadowとタグの輪郭に影をつけるbox-shadowがあります。
    文法は水平方向の影 垂直方向の影 ぼかし具合 影の色で指定します。

    See the Pen shadow by teradonburi (@teradonburi) on CodePen.

    opacity

    opacityは透明度を意味します。0〜1で透明度を指定します。

    See the Pen opacity by teradonburi (@teradonburi) on CodePen.

    border-radius

    border-radiusを指定することでタグの角を丸くすることができます。
    ちなみにborder-radiusの値を大きく振り切ると円になります。

    See the Pen border-radius by teradonburi (@teradonburi) on CodePen.

    gradient

    背景にグラデーションをかけるにはlinear-gradient、radial-gradientを使います。
    linear-gradientが線形のグラデーション、radial-gradientが円形のグラデーションをかけます。
    linear-gradientの第1引数は角度を指定します。後ろの色は何色指定しても構いません。
    radial-gradientの第1引数は円形グラデーションをかける位置を指定します。第2引数以降は色と半径を指定します。

    See the Pen gradient by teradonburi (@teradonburi) on CodePen.

    filter

    filterの種類によっては使えないブラウザがあるので注意が必要です。

    • brightness: 明度
    • contrast: コントラスト
    • grayscale:グレースケール
    • saturate: 彩度
    • sepia: セピア
    • hue-rotate: 色相
    • invert: 色相反転(ネガポジ)
    • blur: ぼかし
    • opacity: 透明度
    • drop-shadow: 影

    filterを複数組み合わせるときはスペースで区切って指定します。

    参考:Photoshopはもういらない?明度も彩度も超手軽に変えられるCSSフィルターがスゴい

    See the Pen filter by teradonburi (@teradonburi) on CodePen.

    mix-blend-modeを使うとさらに複雑な表現ができますが、
    mix-blend-modeに関して詳細は以下を参考にしてください。

    参考:mix-blend-mode

    transform

    trandformはタグの変形を行います。
    scaleで拡大縮小、rotateで回転、translateで移動を行うことができます。
    3次元の場合はscale3d、rotateX、rotateY、rotateZ、translate3dを使います。
    奥行きを反映するためにはperspectiveを使います。
    行列の掛け算となっており、並び順で計算結果が異なるので注意が必要です。
    transform: translate(10px, 100px) rotate(45deg)transform: rotate(45deg) translate(10px, 100px)は表示される結果が異なります。
    他にもskewなどがありますが、詳細は次の記事が参考になります。

    参考:【CSS3】Transform(変形)関連のまとめ

    See the Pen transform by teradonburi (@teradonburi) on CodePen.

    transition

    transitionは2つのスタイル間の変化をアニメーション表現します。
    アニメーションさせたいスタイルをtransitionで指定します。
    一括でスタイルを変化させたい場合は1番目のパラメータにallを指定します。
    2番目のパラメータにはアニメーションの時間を指定します。
    3番目のパラメータにはアニメーション関数を指定します。linear、ease-in-outなどの関数を指定します。
    アニメーション関数の挙動はMDNの例がわかりやすいのでこちらを参考にしてください。
    参考:transition-timing-function

    スタイル別でアニメーション速度を変えたい場合はスタイル名で複数指定します。

    See the Pen transition by teradonburi (@teradonburi) on CodePen.

    animation

    animationはスタイルの変化をキーフレームアニメーションで表現します。
    transitionに対して、キーフレームを@keyframesで定義する必要がある違いがあります。
    フォーマットはanimation: アニメーション名 アニメーション時間 アニメーション関数 繰り返し回数 アニメーションの方向です。
    繰り返し回数はinifiniteを指定すると無制限の繰り返しとなります。
    アニメーションの方向はよく使うものにnormal,reverse,alternativeなどがあります。
    キーフレームの書式は次のようになっています。

    @keyframesアニメーション名{0%{/* 0%のときのスタイル */}x%{/* x%のときのスタイル */}100%{/* 100%のときのスタイル */}}

    0%、100%のみの場合はfrom, toでも指定できます。

    See the Pen animation by teradonburi (@teradonburi) on CodePen.

    メディアクエリ

    メディアクエリを使うと画面サイズによって割り当てるスタイルを変えることができます。
    レスポンシブデザインなどで使います。
    次のように@media screen and (max-width: 画面サイズ)のように使います。
    例えば、PC用レイアウトとモバイル用レイアウトで文字色を変えるには次のようにします。
    レスポンシブでよく使うのはflex-directionをPCではrow、モバイルでcolumnにするなどです。

    /* PC用スタイル */div{color:red;}/* モバイル用レイアウト */@mediascreenand(max-width:768px){div{color:blue;}}

    See the Pen mediaquery by teradonburi (@teradonburi) on CodePen.

    フォーム制御

    基本的にフォームのvalidate制御(正しい値が入力されているか)、submit制御(送信ボタンが押せるか)はJavaScriptでやることが普通なのですが、
    実は簡単なものはCSSでもできちゃったりするので紹介します。

    参考:【CSS猛者への道①】CSSのみで入力フォームのチェックを行う主な3つの便利技法を記録。

    pointer-eventsスタイルがミソでこれをnoneに指定することでsubmitボタンが押せなくなります。
    :not(:placeholder-shown)擬似クラスがplaceholderが表示されていない(=入力されている)を示しています。
    :valid擬似クラスが正しい入力がされているかを示しています。(type=emailの入力欄などは簡易的なメールチェックはされている)
    :in-range擬似クラスで入力値が入力範囲内かを示しています。
    :checked疑似クラスでチェックされているかを示しています。
    すべての入力欄の後、~セレクタにてsubmitボタンが押せるかの判定をセレクタで行います。

    See the Pen form-check-css by teradonburi (@teradonburi) on CodePen.

    とはいえ、セレクタで強引にやるのには限界があるのでJavaScriptで本来やるべきです。

    ベンダープレフィックス

    ベンダープレフィックス(接頭辞)とは、ブラウザベンダーが独自の拡張機能を実装したり、草案段階の仕様を先行実装する場合に、 それが拡張機能であることを明示するために付ける識別子のことです。

    主要ブラウザのベンダープレフィックスは以下のようになっています。

    • -moz-:Firefox
    • -webkit-:Google Chrome、Safari
    • -o-:Opera
    • -ms-:Internet Explorer

    たとえば、transformスタイルに完全対応していないブラウザはベンダープレフィックスを付ける必要があります。
    (時代の変化で確定した時点で対象のスタイルのベンダープレフィックスは不要となります)

    transform:scale3d(1,1,1);-weblit-transform:scale3d(1,1,1);/* Safariのtransformに対応する */

    CSSリセット

    ブラウザ別のCSSの差異をなくすためにページ読み込み時にCSSを上書きしてスタイルを統一することをCSSリセットと呼びます。

    参考:古いCSSリセットからはもう卒業!モダンブラウザに適した新しいCSSリセット -A Modern CSS Reset

    とはいえ、全てリセットする必要はないです。理由としてはUIライブラリを入れた場合に不要だったりするからです。
    (不要なCSSはレンダリングパフォーマンスが落ちる)
    ただし、html, bodyに関しては初期化しておくと便利なことが多いので、自分は以下のCSSリセットをよく使っています。

    html,body{margin:0;padding:0;box-sizing:border-box;min-height:100vh;scroll-behavior:smooth;text-rendering:optimizeSpeed;}

    ちなみにフォームに関してはブラウザによって差異が激しいのでCSSリセットしたほうが都合が良い場合が多いです。
    もしくはUIライブラリを入れてしまうのも手です。

    参考:フォーム要素のスタイルをリセットする

    CSSのパフォーマンス向上

    以下の手順でCSSの見直しをします。

    1. CSSファイルのMinify化:CSSファイルに分離し、CSSファイル自体をMinify(圧縮&難読化)する
    2. セレクタを見直す
    3. 似通ったmargin,paddingや色コードをまとめる
    4. 重複しているスタイルを削除する

    この過程で基本的に!importantもいらなくなるはずです。
    自前でCSSを極力書かずにUIライブラリを使ってしまうのも手です。
    ライブラリではテーマが用意されていてスタイルの統一性が担保できていることやMinify機能を持つものが多いです。

    参考1:<CSS>サイトの表示速度を意識したセレクタの書き方
    参考2:CSS 最適化によるパフォーマンス改善

    デザイン

    デザインに関しては一朝一夕で身につくものではないので、日々勉強が必要です。
    (特に写真、ロゴ、アイコン等の画像作成に関しては完全にクリエイティブな分野なので専門の勉強が必要です)
    以前ランディングページ作成(LP)に関してまとめたものがあるのでこちらも参考にしてください。

    参考:ノンデザイナーでもイケてるLPを作成する方法

    また錯視に関するデザインの調整をすることで、より洗練されたデザインになります。(若干高度なトピック)

    参考:UIのデザインでよく見かける、目の錯覚による違和感を取り除くデザインテクニックのまとめ

    JavaScript

    ブラウザで実行されるスクリプト(フロントエンド)は基本的にJavaScriptで書かれていることが多いです。
    HTMLのDOMツリーが構築された後にDOMを動的生成したり、HTMLタグの属性値を変更したり
    DOMのCSSを変更したり、サーバ(バックエンド)に通信してデータ(主にJSONや画像、音声データ等)を取得したりすることが用途として多いです。
    サーバ側でもNodeJSを使えばJavaScriptでサーバの処理を書くことも可能、IoTでも使えたりと幅が広いプログラミング言語。
    TypeScriptからJavaScriptに変換するというのも最近のトレンドです。(TypeScriptに関してはここでは触れない)

    基礎文法に関してはそれだけで書籍になってしまうのでここでは述べません。
    次のJavaScriptのモダンな基礎文法に関して一通りまとまってるサイトが参考になります。
    参考:js-primer

    最近はbabel、webpack、parcelなどでES5に変換して開発するのが普通なのでES6以前の文法は全てレガシー文法です。
    レガシーな文法を覚える必要は今更ないので、以下の記事でレガシーな文法かどうか参考にしてください。
    (ただし、どれがレガシー文法なのか知るのは大事)

    参考:JavaScript初級者のためのコーディングガイド
    参考:イマドキのJavaScriptの書き方2018

    この記事ではJavaScriptフレームワークは使わずに書いています。
    (どのブラウザでも標準で組み込まれているJavaScriptライブラリを俗にVanilla JSと呼ぶ)
    ReactやVueなどのモダンJSフレームワークも裏側ではVanilla JSが使われています。
    昔はjQueryなどのVanilla JSをラップしたライブラリもメジャーでしたが、
    個人的に今更jQueryは使う必要ないかなと思っています。(使わなくても同等のことができる)
    参考:You Don't Need jQuery

    HTMLElement

    HTMLElementはHTML要素をJavaScriptで操作するときに扱うオブジェクトです。
    あらゆるHTML要素はHTMLElementから継承されており、操作できます。

    参考:HTMLElement

    document.querySelector('CSSセレクタ')でHTMLElementオブジェクトを取得できます。
    JavaScriptでDOM操作をする場合は、正確にはページ読み込み時のDOMの取得タイミングには気をつける必要があります。
    ブラウザのレンダリングの仕組みとしてDOMツリーの構築→画像などのリソース読み込み→JavaScriptでのDOM操作
    (DOMツリーの構築完了を待つ必要がある)

    // DOMツリーの構築を待つdocument.addEventListener("DOMContentLoaded",function(){// ここで取得})

    画像などのリソースの読み込み待ち(読み込んだ画像をJavaScript側で参照)をする場合などは、loadイベントでページの読み込みまで待たないといけません。
    JavaScript側で動的にHTML要素を生成してDOMツリーに挿入することができます。
    HTML要素を生成するには、document.createElement('要素名')を指定します。
    生成したHTML要素の内容を変更するにはinnerHTMLで内容を書き換えすることができます。
    innerHTMLの場合、子要素などの記述などもできます。
    生成したHTML要素をDOMツリーに追加するにはHTMLElement,appendChild(HTMLElement)などを使います。

    // divを作成constdiv=document.createElement('div')div.innerHTML='<span style="color: red;">赤色</span>'main.appendChild(div)

    CSSセレクタで該当する要素を全て取得するには
    document.querySelectorAll('CSSセレクタ')を使います。
    配列のHTMLElementオブジェクトが取得できます。
    innerTextはテキストとして操作します。
    (例えば、innerText内に<span>文字列</span>などを挿入してもタグとして扱われず文字列として扱われてそのまま表示されます)

    // liの要素を全て取得constli=document.querySelectorAll('li')leti=0for(constlofli){i++consttext=l.innerTextl.innerText=text+i}

    See the Pen HTMLElement by teradonburi (@teradonburi) on CodePen.

    HTMLImageElement

    Imageオブジェクト(HTMLImageElement)はHTMLElementを継承したオブジェクトです。
    new Image()でコンストラクタ形式で生成することもできます。(document.createElement('img')と同じ)
    画像リソースをsrc属性指定で動的に読み込むこともできます。
    ただし、onloadイベントやonerrorイベントは非同期のコールバックのため、
    次のようにpromise形式でwrapしたほうが使いやすいでしょう。

    functionloadImage(src){returnnewPromise((resolve,reject)=>{constimg=newImage()img.onload=()=>resolve(img)img.onerror=(e)=>reject(e)img.src=src})}

    参考:HTMLImageElement

    See the Pen image by teradonburi (@teradonburi) on CodePen.

    HTMLAudioElement

    Audioオブジェクト(HTMLAudioElement)はHTMLElementを継承したオブジェクトです。
    new Audio()でコンストラクタ形式で生成することもできます。(document.createElement('audio')と同じ)
    controls属性をtrueにするとAudioプレイヤーのコントロールが表示されます(プレイヤーのコントロール表示はブラウザ依存)

    参考:HTMLAudioElement

    See the Pen audio by teradonburi (@teradonburi) on CodePen.

    HTMLAudioElementは基本的な再生制御しかできませんが、
    WebAudio APIを使うとMIDIシーケンサみたいなものを独自に作ることができたり、音声にエフェクトかけるといった高度なことができるようになります。
    和音を鳴らすのにもある程度知識が必要ですが以下が参考になります。

    参考:Web Audio APIでコインの音を作る

    また、こちらはブラウザによってメモリリークを起こしたり、ユーザアクションがないAudioContextが取得できないといった罠が多かったりします。(後、概念とデバッグが難しい)

    参考:Web Audio APIの闇

    HTMLVideoElement

    HTMLVideoElementはHTMLElementを継承したオブジェクトです。
    videoタグに相当し、動画の制御をJavaScriptでできます。

    参考:HTMLVideoElement

    See the Pen video by teradonburi (@teradonburi) on CodePen.

    LocalStorage

    localStorageを使うとブラウザにデータを半永続的に保存することができます(ドメイン単位)
    localStorage.setItem(key, data)でデータを保存することができます。
    JavaScriptをオブジェクトを直接保存することができないので文字列(JSON文字列)に変換しています。
    JSON形式に変換するにはJSON.stringifyを使います。
    保存したデータを取得するにはlocalStorage.getItem(key)を使います。
    取得したデータがJSON文字列の場合、JSON.parseで文字列からJavaScriptオブジェクトに変換できます。
    一度保存されたデータはブラウザをリロードしてもブラウザに残り続けます。
    明示的にlocalStroageのデータを消すには、localStorage.removeItem(key)を使います。

    See the Pen localStorage by teradonburi (@teradonburi) on CodePen.

    Fileオブジェクト

    File APIを使うとユーザがアップロードしたファイルの操作をブラウザ上で直接取り扱うことができます。
    よく使う例として、画像ファイルをinputタグからアップロードしたとき、Fileオブジェクトとして格納されて取得できます。
    取得したファイルのファイル名、MIMEタイプなどを取得できます。
    URL.createObjectURLを使うとFileオブジェクトを一時的なURLとして変換することができます。
    (このURLはimgタグ、audioタグ、videoタグなどのsrcとして指定することができます。)

    See the Pen File API by teradonburi (@teradonburi) on CodePen.

    もうちょっと複雑な例は以下が参考になります。

    参考:JavaScript で File API を使用してファイルを読み取る

    FormDataオブジェクト

    JavaScriptでフォームデータが正しいものが入力されているかチェック(validate)する制御を送信前に行うことができます。
    FormDataオブジェクトを使うことで入力されたFormのデータを参照したり、JavaScript側で追加したりできます。

    参考:JavaScript によるフォームの送信

    JavaScriptでのデータ通信にはXHR(XMLHTTPRequest)もしくはFetch APIを使って行われることが一般的です。
    または、XHRをラップしたライブラリaxiosを使う方法などがあります。

    See the Pen FormData by teradonburi (@teradonburi) on CodePen.

    アップロードする先のサーバが必要ですが、
    glitchというサービスを使うことで簡易的にNodeJSのサーバを立てています。
    以下、サーバ側の実装です。

    server.js
    constexpress=require('express')constapp=express()constmulter=require('multer')constcors=require('cors')constupload=multer({dest:'uploads/'})// APIエラーハンドリングするためのwrapperconstwrap=(fn)=>(req,res,next)=>fn(req,res,next).catch(err=>{console.error(err)if(!res.headersSent){res.status(500).json({message:'Internal Server Error'})}})// エラーハンドリングprocess.on('uncaughtException',(err)=>console.error(err))process.on('unhandledRejection',(err)=>console.error(err))process.on('SIGINT',()=>process.exit(1))// CORS(別ドメインからの通信を許可する)app.use(cors())// publicフォルダapp.use(express.static('public'))// POSTデータを取得するためのミドルウェアconstbodyParser=require('body-parser')app.use(bodyParser.urlencoded({extended:true}))app.use(bodyParser.json())// アップロードAPIapp.post('/api/upload',upload.single('image'),wrap(async(req,res)=>{console.log(req.body)console.log(req.file)res.json({image:req.file,...req.body})}))// サーバ起動app.listen(process.env.PORT,()=>{console.log('server started')})

    今回はファイル送信があったため、バックエンドを実装しましたが、
    JSONデータを返す、APIサーバのモックであれば、json-serverを使うとさらに簡単にモックサーバの作成ができます。

    WebRTC

    WebRTC(Web realTime Communication)のことでリアルタイムビデオチャットをブラウザで行うための機能です。
    getUserMediaによるカメラからのリアルタイム動画取得とWebSocketによるPeerConnection通信により実現されています。
    カメラからの動画取得のサンプルはこちら

    参考:「MediaDevices.getUserMedia() 」について

    WebSocketに関してはSocket.ioというライブラリを使うのが一般的です。

    ビデオ会議のサンプル:Socket.io | WebRTC One-to-One Video Chat

    Canvas, WebGL

    Canvasを使うことで独自の画像処理やDOMを画像化するなどといった特殊なこともできます。

    参考:Canvasを用いた9つの画像処理フィルターとそのアルゴリズムの解説

    See the Pen canvas by teradonburi (@teradonburi) on CodePen.

    DOMを画像化する方法は直接実装するよりhtml2canvasを使ってしまったほうが手っ取り早いです。

    WebGLに関しては、本格的な3Dをウェブ上で表現するための技術です。
    初期化にはCanvasの延長上でwebglのcontextを取得する必要があります。

    参考:WebGL 入門

    数学的な計算(ベクトル、行列)の知識が必要なのとシェーダー等やれることが多すぎるのと仕様がかなり頻繁に更新され、
    直接扱うのはかなり大変なため、
    Three.jsA-Frameなどのライブラリを使うことが多いです。
    頑張れば、本格的な3Dゲームもブラウザ上で実現可能です。(もちろんパソコンのスペックも必要ですが・・・)
    参考までに以前作ったものを上げておきます。

    参考:Web上でちょっと本気の3Dアクションゲームを作る

    Web Animation API

    Web Animation APIを使うとCSS3のキーフレームアニメーションをJavaScriptで行うことができます。
    (ただし実験的な機能なため、まだ動かないブラウザが多いので実プロダクトでは使えません。)

    参考:Element.animate()

    See the Pen Web Animation API by teradonburi (@teradonburi) on CodePen.

    スクロールアニメーション

    Vanilla JSで直接実装するのが大変なものにスクロールアニメーションがあります。
    クリックしたら指定のアンカーリンクまでスクロールアニメーションするといった挙動です。
    smooth-scrollというライブラリを使うとあっさり実装できます。

    参考:Vanilla.jsのアニメーションスクロールプラグイン「Smooth Scroll」

    See the Pen Smooth Scroll by teradonburi (@teradonburi) on CodePen.

    パララックス

    スクロールアニメーション同様Valilla JSで表現するのが厄介なのが、パララックスです。
    これは、スクロールに連動してHTML要素がアニメーションすることです。
    こちらもrellaxというライブラリを使えば比較的簡単に実現できます。

    See the Pen Rellax by teradonburi (@teradonburi) on CodePen.

    まとめ

    Webフロントエンドの基礎的な部分に関して説明しました。
    さらにWebフロントエンドに対する知識と理解を深めるには次のものを勉強すると良いと思います

    また、実践でプロダクトを作りながら覚えていくと良いでしょう。
    拙書ですが、グロースハックの記事を書きました。(宣伝)

    note:スタートアップ界隈4年目エンジニアが苦労したグロースハック手法について語る
    kindle版:スタートアップで知っておきたい知識・グロースハック手法入門

    内容はほぼ同じです。


    はじめに

    この記事は以前私が投稿した記事の続編となります。合わせて読んで頂けると嬉しいです:relaxed:
    Vueを扱えるようになりたいけどJavaScript書いたことがなかったので、JavaScriptとVueを同時に勉強する。
    今回は、前回のコードを改修〜見た目実装までの手順を記載しました!
    完成品はこちらとなります:sparkles:
    ezgif-4-dce3ca87fab9.gif

    前回のコードを改修

    まずは前回のコードの手直しから始めましょう。

    前回の記事で改修案のコメントをくださった方ありがとうございます。
    参考にさせていただきながら、進めていきたいと思います!

    前回のコードはこちら

    game.vue
    <template><div><p>じゃんけん!</p><button@click='guu'>グー</button><button@click='tyoki'>チョキ</button><button@click='paa'>パー</button><p>わたしは{{watashi}}</p><p>あいては{{aite}}</p><p>この勝負…{{result}}</p></div></template><script>exportdefault{name:'Game',data(){return{watashi:'',watashi_hand:'',aite:'',aite_hand:'',result:''}},methods:{guu(){this.watashi='グー'this.watashi_hand=0this.aite_no_te()this.syouhai()},tyoki(){this.watashi='チョキ'this.watashi_hand=1this.aite_no_te()this.syouhai()},paa(){this.watashi='パー'this.watashi_hand=2this.aite_no_te()this.syouhai()},aite_no_te(){switch(Math.floor(Math.random()*3)){case0:this.aite='グー'this.aite_hand=0breakcase1:this.aite='チョキ'this.aite_hand=1breakcase2:this.aite='パー'this.aite_hand=2break}},syouhai(){switch(((this.watashi_hand-this.aite_hand+3)%3)){case0:this.result='引き分けっ'breakcase1:this.result='あなたの負け…'breakcase2:this.result='あなたの勝ち!'break}}}}</script>

    この後、見た目を実装するために画像を挿入したりするので、そもそも必要のない部分が出てきます。
    その部分に関しては改修の余地があっても手直しせずに削除し、残す部分だけ手を加えていきます。

    改修後はこちら

    game.vue
    <template><div><p>じゃんけん!</p><buttonv-for="item in shapes":key="item.key"@click="select(item.key)">{{item.label}}</button><p>この勝負…{{resultText}}</p></div></template><script>exportdefault{name:'Game',data(){return{shapes:[{label:'グー',key:0},{label:'チョキ',key:1},{label:'パー',key:2}],resultText:'',player:'',bot:''}},methods:{select(key){this.player=keythis.result()},result(){this.bot=Math.floor(Math.random()*3)switch(((this.player-this.bot+3)%3)){case0:this.resultText='引き分けっ'breakcase1:this.resultText='あなたの負け…'breakcase2:this.resultText='あなたの勝ち!'break}}}}</script>

    解説していきます。
    watashiaiteに関しては画像やボタンで手がわかるように表現したいので、結果的にいらなくなるため消しました。
    グー、チョキ、パーとそれに関連した数字を今まではmethods内にその都度書いていましたが、これをdata内に一箇所にまとめます。

    data(){return{shapes:[{label:'グー',key:0},{label:'チョキ',key:1},{label:'パー',key:2}],...

    グーの場合は0というふうに既に決まっているので、配列にまとめることができました。これでいちいちグーとか=0とか書かなくてよくなりました。

    今度はボタンの部分を見ていきます。

    <button@click='guu'>グー</button><button@click='tyoki'>チョキ</button><button@click='paa'>パー</button>

    私はボタンタグを三つ配置していましたが、こちらはfor文を使う事でボタンタグを一つにすることができます。

    <buttonv-for="item in shapes":key="item.key"@click="select(item.key)">
      {{ item.label }}
    </button>

    こうですね。
    さらにfor文を使用し@click="select(item.key)"となったことで、クリック時の関数も一つにすることができます。

    guu(){this.watashi='グー'this.watashi_hand=0this.aite_no_te()this.syouhai()},tyoki(){this.watashi='チョキ'this.watashi_hand=1this.aite_no_te()this.syouhai()},paa(){this.watashi='パー'this.watashi_hand=2this.aite_no_te()this.syouhai()},

    三つもあった関数が記述が

    select(key){this.player=keythis.result()},

    これ一つだけになります。
    syouhaiはダサいのでresultに名前を変更。watashi_handもダサいのでplayerに名前を変更。 aite_no_te()の処理はbotに名前を変えつつresult内に移動させます。

    result(){this.bot=Math.floor(Math.random()*3)switch(((this.player-this.bot+3)%3)){case0:this.resultText='引き分けっ'breakcase1:this.resultText='あなたの負け…'breakcase2:this.resultText='あなたの勝ち!'break}},

    this.botってせずにswicth文の中に直接Math.floor(Math.random() * 3)を書いてもいいんですが、画像の出しわけでthis.botは使いたいのでこういう書き方をしています。

    画像の挿入とアニメーションの実装

    さて、現時点では相手の手が表示されない為わからず、勝敗の結果しか表示されなくなっています。
    今度は相手の手をグーチョキパー三つの画像で表示させていきます。

    アニメーションの方法ですが、画像を配列に入れてそれを順番に表示って方法は既にされているかたがちらほら見かけてしまったので、
    同じだとつまらなかったので私はcssで頑張っていきます。

    まずはグーチョキパーの画像を用意しましょう。
    私はフリー素材を拝借して色を塗りました。ちなみに、画像はsrc/assets/に入れましょう。

    シンプルに表示させます。画像もちょうどいいサイズにcssをいじっておきました。

    <p>じゃんけん!</p><imgsrc="@/assets/rock.png"><imgsrc="@/assets/scissors.png"><imgsrc="@/assets/paper.png">

    表示はこんな感じ。
    スクリーンショット 2019-08-01 17.58.56-min.png

    これをbotに入る数字に合わせて表示を出しわけます。ついでにボタンの横ではなくて上に表示したいのでdivで囲います。

    <div><imgv-if="this.bot === 0"src="@/assets/rock.png"><imgv-if="this.bot === 1"src="@/assets/scissors.png"><imgv-if="this.bot === 2"src="@/assets/paper.png"></div>

    スクリーンショット 2019-08-01 18.05.32-min.png

    これでボタンをかちかちするとランダムに画像が一つだけ表示されるようになりました。

    ボタンを押したあとはこれで問題ないのですが、ボタンを押すまでの間は画像をどぅるるるる(伝われ)ってしたいのでまずはボタン押す前と後で表示を出しわけましょう。

    <divv-if="pon"><imgv-if="this.bot === 0"src="@/assets/rock.png"><imgv-if="this.bot === 1"src="@/assets/scissors.png"><imgv-if="this.bot === 2"src="@/assets/paper.png"></div><divv-else><imgsrc="@/assets/rock.png"><imgsrc="@/assets/scissors.png"><imgsrc="@/assets/paper.png"></div>
    data(){return{shapes:[{label:'グー',key:0},{label:'チョキ',key:1},{label:'パー',key:2}],resultText:'',player:'',pon:false}},methods:{select(key){this.pon=truethis.player=keythis.result()},

    ボタンを押す前と押した後で分けるためにponを実装しました。デフォルトではponfalseで、ボタンをクリックするとtrueになりどれか一枚の画像が表示される仕組みです。

    ponfalseの時、3枚の画像をどぅるるると表示させたいのですが、これはcssのanimationで実装してきます。
    cssに下記の記述を追加して、各画像のclassanimationを追加します。

    <divv-else><imgclass="animation"src="@/assets/rock.png"><imgclass="animation"src="@/assets/scissors.png"><imgclass="animation"src="@/assets/paper.png"></div>
    .animation{animation-name:img;animation-duration:0.3s;animation-iteration-count:infinite;opacity:0;}@keyframesimg{0%{opacity:0;}25%{opacity:1;}50%{opacity:0;}}

    こんな感じ。
    ezgif-4-4d39de42eeb1.gif
    画像が出たり消えたりしていますね。
    次は各画像にdelayをかけて表示するタイミングをずらして、3枚の画像を重ねます。

    <divclass="img-area"><divv-if="pon">
        ...
      </div><divv-else><imgclass="animation"src="@/assets/rock.png"><imgclass="animation scissors"src="@/assets/scissors.png"><imgclass="animation paper"src="@/assets/paper.png"></div></div>
    .img-area{position:relative;margin-bottom:10px;}.animation.scissors{position:absolute;top:0;left:45%;animation-delay:0.1s;}.animation.paper{position:absolute;top:0;left:45%;animation-delay:0.2s;}

    ezgif-4-dba5ce2f7029.gif
    完璧ですね。GIFなんでちょっと違和感ありますが、実際だと綺麗にどぅるるるしてくれてます:thumbsup:

    ここでちょっと機能追加

    じゃんけんをやり直すには、現状画面をリロードするしかなく不便なので「もう一度!」ボタンを実装します。

    <button@click="retry">もう一度!</button>
    retry(){this.pon=falsethis.resultText=''this.player=''},

    これでok。retry()deta内を最初の状態に戻しています。

    Bootstrapを使ってデザインを良くする

    あとやりたい事は、
    ①ボタン周りのデザインをかっちょよくしたい:star:
    ②ボタンをクリックした時に、色を変えるなどして何のボタンをクリックしたかわかりやすくしたい:bulb:
    この2点です。どちらもBootstrapでちゃちゃっとできちゃいますので実装しちゃいます。
    Bootstrapの適用方法・使い方に関してはここで説明すると長くなると思い、別で記事を作成しましたので興味がある方は参考にしてください。
    Vue.jsにBootstrapを適用させる方法

    こちらの公式ページのテンプレートを使用します。
    https://bootstrap-vue.js.org/

    <div><b-button>
       :pressed.sync="item.state" variant="outline-success"
       v-for="item in shapes" :key="item.key"
       @click="select(item.key)">
       {{ item.label }}
      </b-button></div><b-buttonvariant="outline-danger"@click="retry">もう一度!</b-button>

    ボタンがクリックされたらstateがtrueになり、色が緑色のままになるようにしました。
    また、shapesにもデフォルトでstateがfalseになるように記述を追加しています。

    ついでに全体的なcssをちょいちょいと調整します。
    vueのlogoは、「vueで作ったよ!」って事が一目でわかるので残しておきました。ちょっとデカかったのでサイズはいじりましたが:sweat_smile:

    完成コードはこちら:sparkles:

    <template><div><p>じゃんけん!</p><divclass="img-area"><divv-if="pon"><imgv-if="this.bot === 0"src="@/assets/rock.png"><imgv-if="this.bot === 1"src="@/assets/scissors.png"><imgv-if="this.bot === 2"src="@/assets/paper.png"></div><divv-else><imgclass="animation"src="@/assets/rock.png"><imgclass="animation scissors"src="@/assets/scissors.png"><imgclass="animation paper"src="@/assets/paper.png"></div></div><div><b-button:pressed.sync="item.state"variant="outline-success"v-for="item in shapes":key="item.key"@click="select(item.key)">{{item.label}}</b-button></div><b-buttonvariant="outline-danger"@click="retry">もう一度!</b-button><div>この勝負…<br/><spanclass="text">{{resultText}}</span></div></div></template><script>exportdefault{name:'Game',data(){return{resultText:'',player:'',pon:false,shapes:[{label:'グー',key:0,state:false},{label:'チョキ',key:1,state:false},{label:'パー',key:2,state:false}]}},methods:{select(key){this.pon=truethis.player=keythis.result()},result(){this.bot=Math.floor(Math.random()*3)switch(((this.player-this.bot+3)%3)){case0:this.resultText='引き分けっ'breakcase1:this.resultText='あなたの負け…'breakcase2:this.resultText='あなたの勝ち!'break}},retry(){this.pon=falsethis.resultText=''this.player=''this.shapes=[{label:'グー',key:0,state:false},{label:'チョキ',key:1,state:false},{label:'パー',key:2,state:false}]}}}</script><stylescoped>button{margin:10px5px;box-shadow:none!important;}img{width:10%;}.animation{animation-name:img;animation-duration:0.3s;animation-iteration-count:infinite;opacity:0;}.animation.scissors{position:absolute;top:0;left:45%;animation-delay:0.1s;}.animation.paper{position:absolute;top:0;left:45%;animation-delay:0.2s;}.img-area{position:relative;margin-bottom:10px;}.text{font-size:50px;}@keyframesimg{0%{opacity:0;}25%{opacity:1;}50%{opacity:0;}}</style>

    ezgif-4-dce3ca87fab9.gif
    画像周りとか、retry()とかdata()とか、もっときれいに短く書けそうな気がします…
    勝敗結果を保存して戦歴表示とかも…
    でも、やりたかったことができて一旦キリがいいのでここでおしまいにします。

    さいごに

    ここまで読んでくださってありがとうございました。
    どなたかの参考になれば嬉しいです!
    誤字脱字・発信した情報に間違い等ございましたら、指摘して頂けますと幸いです:bow:
    また、説明にわかりづらい点がございましたら、改善致しますのでぜひコメントください:pray:


    0 0
  • 11/04/19--19:36: float の解除 clearfix
  • 子要素が全てfloatの時の、親要素の高さ

    通常、親要素の高さは子要素を包む高さとなるが、子要素が全てfloatの時、親要素の高さは0となってしまうという性質がある。

    float は浮いているという意味で、親要素からみると float の子要素は存在しないように見えるからである。

    <!DOCTYPE html><htmllang="ja"><head><metacharset="utf-8"><title></title><linkrel="stylesheet"href="css/reset.css"><linkrel="stylesheet"href="css/style.css"></head><body><headerclass="header"></header><divclass="wrapper"><mainclass="main"></main><divclass="sidemenu"></div></div><footerclass="footer"></footer></body></html>
    .header{width:100%;/* border: 1px solid red; */}.wrapper{width:970px;/* border: 1px solid red; */margin:30pxauto40px;}.main{display:block;float:left;width:660px;}.sidemenu{float:right;width:275px;}.footer{width:100%;}.header,.main,.sidemenu,.footer{border:1pxsolid#aaa;background-color:#ccc;}.header,.footer{height:100px;}.main,.sidemenu{height:500px;}

    mainクラスとsidemenuクラスにはそれぞれfloatが指定されているため高さを認識できなくなり、footerが上がってしまう。

    スクリーンショット 2019-11-05 12.19.32.png

    改善策

    親要素にclearfixクラスみたいにクラス名をつける(使いまわせるように)。

    <divclass="wrapper clearfix"><mainclass="main"></main><divclass="sidemenu"></div></div>

    擬似要素を使用しclear: both;とし(もしくは 'clear: left;')、floatを解除することで、高さを認識できるようになり、この問題を解決することができる。
    https://saruwakakun.com/html-css/basic/before-after

    .clearfix::after{content:'';display:block;clear:both;}

    スクリーンショット 2019-11-05 12.29.18.png


    webプログラミング言語とは?

    webプログラミング言語は、webサービスにおいて自分のアイデアを形にしたり、みんなに使ってもらったりするための言語です。
    大きく分けるとフロントエンドとバックエンドの2つに分類することができます。

    フロントエンドとは

    フロントエンドとは、ブラウザに働きかけるもので、簡単に言うと「見せる」モノです。ホームページやブログなど目に見える部分を担当する言語です。サイトに装飾や動きを与えるなど目に見えて自分が作成したプログラムが反映されていくので自分はやっていて楽しいです。(笑)

    フロントエンドの言語
    - HTML
    - CSS
    - Javascript
    - jQuery    

    ホームページやブログは、HTML、CSSのみで作ることが可能であり、サイトに動きを付けたい場合にJavascriptやJQueryを用います。

    バックエンドとは

    バックエンドとは、サーバ内で動く仕組みなどのことで、私たちの目には見えないとことで働くモノです。また、バックエンドのことをサーバーサイドと言い換えることもできます。サーバーサイドの言語は、目に触れる部分ではなくアプリやサービスの内部を担当する言語です。

    バックエンドの言語
    - PHP
    - MySQL
    - WordPress    

    フロントエンドに興味を持ったあなたに

    私は、ホームページなどウェブサイト制作に興味があったのでフロントエンドを中心に現在勉強をしています。そのようなこともありフロントエンドを始めるにあたって使いやすいおすすめの環境を記載します。
    プログラミングを始めるためには、まずエディタを用意をする必要があります。

    おすすめのエディタ

    エディタとは、一言でいうとプログラムを書くためのソフトです。自分が「使いやすい!」と思い、おすすめするエディタは、「Visual Studio Code」です。VScodeは、補完機能が充実しているので文法ミスも少なくなり、初心者の方にお勧めです。
    以下のURLからダウンロード可能です。
    [https://code.visualstudio.com/]

    フロントエンドは、エディタでプログラムを書き、ブラウザで動作を確認する形になります。

    とりあえずやってみよう!

    自分がwebプログラミングを始めたのは、友達の「一緒にHTMLの勉強しよ!」という一言がきっけでした。自分のやりたいことが見つかっていなかった私は、とりあえず勉強してみることにしました。そこから徐々にwebプログラミングの面白さに気づいていきました。
    挑戦することで視野が広がることを実感しました
    フロントエンドとバックエンドのどちらか自分が興味を持つほうから勉強を始めていくことをお勧めします!


    パンくずリストとは

    20191024_2_Qiita01.jpg
    [メルカリより]https://www.mercari.com/jp/guide/car/transport_guide/
    こういうのとか

    20191024_2_Qiita02.jpg
    [Web Design Trendsより]https://webdesign-trends.net/entry/2310
    こういうのをパンくずリストという

    名前の由来

    童話「ヘンゼルとグレーテル」からきているとのこと。

    パンくずリストを作ろう

    bread-crumbs.html
    <!DOCTYPE html><htmllang="ja"><head><metacharset="utf-8"><title>パンくずリスト</title><linkrel="stylesheet"href="css/bread-crumbs.css"></head><body><divclass="bread-crumbs"><ul><li><ahref="#">ホーム</a></li><li><ahref="#">カテゴリー1</a></li><li><ahref="#">カテゴリー2</a></li><li>カテゴリー3
          </li></ul></div></body></html>
    bread-crumbs.css
    body{margin:0;}.bread-crumbsul{list-style:none;text-decoration:none;padding:0;margin:10px10px;}.bread-crumbsli{display:inline;}.bread-crumbsli:after{content:'>';color:#000000;}.bread-crumbsli:last-child:after{content:none;}.bread-crumbslia{text-decoration:none;color:#218b21;}.bread-crumbslia:hover{text-decoration:underline;}

    シンプルなパンくずリストができました
    20191105_Qiita01.png

    疑似要素を使ってを表示していますが、下の記述がないと一番右側にもが表示されてしまいます。
    やっていることは一番後ろのli要素の疑似要素は無し(非表示)ということです。

    .bread-crumbs li:last-child:after {
        content: none;
    }
    

    パンくずリストを作るのは別にli要素じゃなくてもいいのでは?と思ったのですが、Googleではli要素を推奨しています。
    https://developers.google.com/search/docs/data-types/breadcrumb


    Sponsored Content
    Adskeeper

older | 1 | 2 | 3 | (Page 4) | 5 | 6 | .... | 69 | newer


You may like
Adskeeper