- 投稿日:2020-12-16T22:14:03+09:00
CSS セレクタ 備忘録
セレクタ
はじめに
CSSのセレクタに関する基礎知識を備忘録にまとめてみました。
セレクタの種類
シンプルセレクタ Simple Selector
セレクタを構成する最小単位のこと。
仕様書で定義されているシンプルセレクタは下記。
p { color: #FFF; }ユニバーサルセレクタ
* を指定すると、すべての要素が適用対象。
* { color: #FFF; }クラスセレクタ
ピリオド(.)に続けてHTMLのclass属性の値を指定すると、そのclass属性の値を持つ要素が適用対象。
※class属性の値全体が一致する必要はない。指定している値がclass属性に含まれれば適用される。<!-- 適用対象のHTML--> <p class="desc item">テスト</p> /* CSSのサンプル */ p.desc { color: #FFF; }IDセレクタ
#に続けてHTMLのID属性の値を指定すると、そのid属性の値を持つ要素が適用対象。
p#description {color: #FFF; }属性セレクタ
特定の属性が指定されている要素、特定の属性に特定の値が指定されている要素が適用対象。
[属性名] 属性名の属性が適用対象。※属性値は無関係
a[title] { color: #FFF; }[属性名 = "属性値"]
属性名の属性に属性値の値が指定したものと完全一致する属性が適用対象。
a[title = "TOPへのリンク"] { color: #FFF; }[属性名 ~= "属性値"]
属性名の属性に属性値の値が指定したものと一致する属性が適用対象。
指定している値が属性に含まれれば適用される。<!-- 適用対象のHTML--> <p class="desc item">テスト</p> /* CSSのサンプル */ p[class~="desc"] { color: #FFF; }[属性名 |= "属性値"]
属性名の属性に属性値の値が指定したものと一致する or 指定した値で始まり直後に-で終わる要素が適用対象。
言語のサブコードに使用される。<!-- 適用対象のHTML--> <p lang="en-US">test</li> /* CSSのサンプル */ p[lang|="en"] { color: #FFF; }[属性名^="属性値の始め"]
属性名の属性の値が属性値の始めで始まる要素が適用対象。
<!-- 適用対象のHTML--> <p class="desc item">テスト</p> /* CSSのサンプル */ p[class^="de"] { color: #FFF; }[属性名$="属性値の終わり"]
属性名の属性の値が属性値の終わりで終わる要素が適用対象。
<!-- 適用対象のHTML--> <img src="sample.jpg"> /* CSSのサンプル */ img[src$="jpg"] { width: 50%; }[属性名*="属性値の一部"]
属性名の属性の値が属性値の一部を含む要素
<!-- 適用対象のHTML--> <a href="https://example.com">sample</a> /* CSSのサンプル */ a[href*="example"] { color: #FFF; }疑似クラス
要素が特定の状態にあるとき等に限定して適用対象にするのが疑似クラス。
全部で23種類ある。:link
リンク先をまだ見ていない状態のa要素
a:link{ color: #FFF; }:visited
リンク先を既に見た状態のa要素
a:visited { color: purple; }:hover
カーソルが上にある状態の要素が対象
a:hover { color: red; }:active
マウスのボタン等が押されている状態の要素
a:active { color: green; }\ntn-child(式)
先頭から〇個目の要素から△個おきに適用
/* リスト中の2番目の <li> 要素を選択 */ li:nth-child(2) { color: lime; } /* 兄弟要素の中で3つおきに 要素を選択 */ :nth-child(4n) { color: lime; }:ntn-last-child(式)
最後から〇個目の要素から△個おきに適用
/* 兄弟要素の中で、後ろから数えて 3つおきに要素を選択 */ :nth-last-child(4n) { color: lime; }:ntn-of-type(式)
先頭から〇個目の要素から△個おきに適用(指定した要素と同じ要素のみ)
<!-- HTMLのサンプル --> <div> <div>This element isn't counted.</div> <p>1st paragraph.</p> <p>2nd paragraph.</p> <div>This element isn't counted.</div> <p>3rd paragraph.</p> <p class="fancy">4th paragraph.</p> </div> /* CSSのサンプル */ /* 兄弟の <p> 要素の中で、 3つおきに選択 */ p:nth-of-type(4n) { color: lime; } /* 奇数の段落 */ p:nth-of-type(2n+1) { color: red; } /* 偶数の段落 */ p:nth-of-type(2n) { color: blue; } /* 最初の段落 */ p:nth-of-type(1) { font-weight: bold; } /* .fancy クラスは1番目ではなく4番目の p 要素にしかついていないので、これは効果がありません */ p.fancy:nth-of-type(1) { text-decoration: underline; }「an+b」
上記の式が指定できる疑似クラスの式は「an+b」という形式の式または「odd」「even」というキーワードが指定できる。
「odd」を指定すると奇数個目だけ適用され、「even」を指定すると偶数個目だけに適用される。/* 奇数個目 */ p:nth-of-type(odd) { font-weight: bold; }「an+b」という式は、aとbの部分を整数に置き換えて使用する。(0でも負でも可)
nは0以上の整数を表す。例)
:ntn-child(2n+1)2*0+1=1、2*1+1=3、2*2+1=5という形で1,3,5個目に適用される。
:ntn-child(2n+0)と書いた場合
2*0+0=0、2*1+0=2、2*2+0=4という形で2,4個目に適用される。
0は省略して2nというような形式で記述可能。※注意
-of-typeで終わっていれば指定した要素と同じタイプで見ていくがntn-childであれば関係なく先頭の要素から見ていく。疑似要素
タグで囲われている範囲全体をそのまま適用対象にするのではない特殊なセレクタを疑似要素。
CSS3で下記の4種類。::first-line
ブロックレベルの要素の1行目が適用対象。
<!-- HTMLのサンプル --> <p class="sample">スタイルはこの段落の最初の行にのみ適用されます。 その後のすべての文字列は普通のスタイルになります。分かりますか?</p> <span>ブロックレベル要素ではないので、この文字列の最初の行は、 特殊なスタイルになりません。</span> /* CSSのサンプル */ .sample::first-line { color: blue; }::first-letter
ブロックレベル要素の1文字目
<!-- HTMLのサンプル --> <h2 id="letter">My heading</h2> /* CSSのサンプル */ #letter::first-letter { color: red; }::before
要素内容の先頭にコンテンツを追加。
<!-- HTMlのサンプル --> <span class="ribbon">オレンジのボックスがどこにあるか注意してください。</span> /* CSSのサンプル */ .ribbon::before { content: "このオレンジのボックスを見てください。"; }::after
要素内容の最後にコンテンツを追加
<!-- HTMlのサンプル --> <p class="boring-text">古くつまらないテキストです。</p> /* CSSのサンプル */ .boring-text::after { content: " <- ツマラナイ!"; color: red; }疑似要素は、結合子も含めたセレクタ全体の最後尾に1つしかつけれない。
参考にしたサイト
- 投稿日:2020-12-16T19:36:03+09:00
スタイルシートクラス命名規則の迷いに終止符を打つ
class名命名規則
誰もがつまずくであろう、スタイルシートのclass命名規則。未だに正解が分からずにclass名をつけてる人がいるだろう。
class名について調べても結局、抽象的な答えしか見つからない。ある程度の規則にそっていれば、あとは個人のやりやすういようにと。。 なぜ、抽象的な答えしかないのか。
理由は、プロジェクトごと、企業ごとに命名規則が、設けられていたり、独自の命名規則を採用している。また、 sassを使用できれば、BEM記法が定番であったりと、各環境が異なるため、一概にこの、class名の付け方が正解と言えないのです。そこで今回は、class名をつけるのに困っている方に
・class名の付け方
・なにを意識しながら付ければいいのか
具体的な、答えを提示します。<想定読者> スタイルシートのclass名をつけるのに困っている人、始めたばかりの人
<想定読者> コンポーネントの機能ごとに細分化してclass名をつけていない人以下の理解が、まだだと感じた人は、以下を理解してから読み進んでください。
・class命名規則(BEM,OOCSS,SMACSSS、など)
・コンポーネントの理解
ずばりclass名はどうすればいいのか。
現在では、いくつかのclass命名規則が存在します。
しかし、規則が違っても、どの命名規則もコンポーネントの機能ごとに細分化を行い、その細分化したコンポーネントごとに、classを命名していくと言うことが理解できます。
この、「コンポーネントの機能ごとにclass名をつける」と言うことが、スタイルシートclass命名の迷いをなくす、最大のポイントです。
この、「コンポーネントの機能ごとにclass名をつける」と言うことができるようになればどの命名規則に直面しても、困る事はありません。
また、class名をつける際に、重要なのは
- 予測しやすい
- 再利用しやすい
- 保守しやすい
- 拡張しやすい
- コンポーネントでまとめる
・予測しやすい
予測しやすい、と言うのは期待どうりに振舞うかどうか、と言うことです。他のルールが影響して、記述したルール通りの振る舞いを見栄えにならない
または追加したルールが他のルールに影響を与えることがないようにすると言うこと。
・再利用しやすい
スタイルがコピーアンドペーストされてふくらみ続けるCSSにならないためにも、再利用しやすいルールを持つ事は重要です。再利用しやすいルールと言うのは
抽象的で、機能ごとに分離されている必要があります。遭遇したuiデザインのマーックアップ、CSSを一度作れば、再度同じようなUIに遭遇した
ときに、わざわざ書き直す必要がないようにするのが理想です。
・保守しやすい
新しいルールを追加、更新するときに既存のルールのリファクタリングを必要としない事が大事です。追加したルールによって、既存のルールを壊してしまうのは避けましょう。
・拡張しやすい
自分と、自分以外のプロジェクトに関わる開発者にとってメンテナンス・管理がしやすいものであると言うこと。
これらを、意識して細分化しclass名をつけてください。この意識は絶対にしてください。
そして、「コンポーネントの機能ごとにclass名をつける」と言うことを理解し、できるようになるまで、
『OOCSSの規則でclass名をつけてください。』
OOCSSを使用することで、オブジェクト思考でコンポーネントを簡単なclass名をつけるので、わかりやすくコンポーネントごとに細分化することができ
また、コンポーネントの機能を英語でclass名にするで、余計な事は考えずにclass名を決められます。class名を英語にするのに困ったらこちらを参照してください。
正しくコンポーネントごとに、細分化すると言う意識を理解していないのがclass命名で困る原因です。
OOCSSで行う理由は、コンポーネントごとにclass名をつけるのが一番容易であること、またコンポーネントごと細分化することに慣れることができることです。
そうすることで、class命名に困ることなくはなくなります。また、上記の五つの意識がOOCSSでできるように なれば、どの規則にも細かい規則に気をつければ、応用ができます。
働いている会社が、BEM記法を採用しているから、BEM記法だけで行うのではなく、一度OOCSSで、class名をつける基礎を固めることが重要です。 そうすれば、今後class名をつけるのに困る事はないでしょう。 目安として、コーディング練習ができるデザインを配布している命名 することに、慣れました。是非この方法を試してみてください。 実際に、私は三回これをこなすことで、コンポーネントごとに、細分化しそれらに、class名をつけることに慣れました。
意識するのは、その各要素がなんの機能なのか、理解すること。スタイルを当てるためにclass名をつけることのないようにすること。
この理解ができていないと、よくないclass名をつけたり、class名をつけるのに時間がかかってしまいます。
最期に、もう一度言います。「コンポーネントの機能ごとにclass名をつける」これが本当に大事です。
まとめ
スタイルシートclass命名に困っていたら、OOCSSでコンポーネントの機能ごとに細分化し、それにclass名をつけていく。
コンポーネントごとに細分化することの大切さを理解する。
ただ、今回紹介した方法は、どの場面でも使えると言うわけではありません。そのとき、そのときでclass命名の規則は変わります。
どんな、状況、命名規則に遭遇しても困らないために、備えることのできる方法です。
- 投稿日:2020-12-16T18:42:31+09:00
Pinterestのように写真を表示する
はじめに
絶賛ポートフォリオ製作中の駆け出しエンジニアです
インスタグラムのような古着専用の写真投稿サイトを作っています
その時に写真の投稿一覧画面でPinterest(https://www.pinterest.jp/) というサイトのように写真を並べるために奮闘しましたので備忘録として残したいと思います
コード
before
post.html.erb<div class = contents-row > <% @items.each do |item| %> <ul class='item-lists'> <li class='list'> <%= link_to items_path(item.id), method: :get do %> <%= image_tag(item.image, class:"item-img") %> <% end %> </li> </ul> <% end %> </div>post.scss.contents-row { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; margin: 0 auto; width: 95vw; } .item-lists { margin: 5px; } .list { width:25vw; } .item-img { width: 100%; height: auto; border-radius: 30px; vertical-align: bottom; }after
post.html.erb<div class = contents-row > <ul class='item-lists'> <% @items.each do |item| %> <li class='list'> <%= link_to items_path(item.id), method: :get do %> <%= image_tag(item.image, class:"item-img") %> <% end %> </li> <% end %> </ul> </div>post.scss.contents-row { display: flex; justify-content: center; align-items: center; margin: 0 auto; width: 95vw; } .item-lists { column-count: 3; column-gap: 15px; column-fill: auto; } .list { width:25vw; } .item-img { width: 100%; height: auto; border-radius: 30px; vertical-align: bottom; margin: 5px; }行ったこと
• 【html】 ulタグがeach文の中に入っていたのでeach文の外に出した
• 【css】 item-listsにcolumn-countなどを記述し、それに合わせてそれぞれ調整した参考サイト
- 投稿日:2020-12-16T18:39:30+09:00
SVG + CSS + Node.js + receiptline で電子レシートを発行してみよう
マークダウン言語で紙のレシートや電子レシートを簡単に作れる receiptline。
https://github.com/receiptline/receiptline
https://www.npmjs.com/package/receiptline今回は receiptline 本来の用途と考えられる、電子レシートの発行です!
レシートを設計する
デザインツール
ReceiptLine Designer を使います。使い方はこの連載記事の初回から。
いますぐ試したい方は、開発元のホームページで公開されているのでこちらへ。
ロゴの背景を透明に
以前の記事で作成したロゴ画像を再利用します。
GIMP の「色を透明度に」 (Color to Alpha) 機能で、背景色を白から透明にしました。
2023年度インボイス制度対応
前回の記事で学習した、簡易適格請求書等の記載事項も追加しておきます。
- ① 適格請求書発行事業者の氏名又は名称及び登録番号
- ② 課税資産の譲渡等を行った年月日
- ③ 課税資産の譲渡等に係る資産又は役務の内容(課税資産の譲渡等が軽減対象資産の譲渡等である場合には、資産の内容及び軽減対象資産の譲渡等である旨)
- ④ 課税資産の譲渡等の税抜価額又は税込価額を税率ごとに区分して合計した金額
- ⑤ 税率ごとに区分した消費税額等又は適用税率
作成したレシートデータ
ReceiptLine{image:iVBORw0KGgoAAAANSUhEUgAAASAAAAAwAgMAAADMTE88AAAACVBMVEVwAAsAAAD///9xeVj9AAAAAXRSTlMAQObYZgAAAdZJREFUSMftlsFu4zAMRMUD73sI/0c59M4Amv//lXJI2XEWaGSgAVrsxuihtqgnmjOk09r7+pcv7esYAEtMM19yrCkWxwnOgEbk1Fc5nwBpRNgCpGdAhKi/4NVYaFmD1qqlYi8ACU6Y6BRo/DaQjk3hiARv4BeB834aVXBDk1bL0lHlCEs0Qz5zP4A89FVW3rgWNwGxWrRuCVIC7Ao3HjBCamY6mt7GHSQ9/rnQVEGZIBmlBPL0Fsvoig8Mg9N6KJAAB5ASFPDYzUcJytgEFXAQzpf2/ajMCMeMjCAwMX8A9ZQjQUJQ7mZs5G4TZMcaXRJd3bKBLOZLz4gC9Q00Y8030FE1Vga5egf5put0rTwDbT4SalV6fQmyp6DZIqCONXe+Aqk/A82mlcF3RO7eQeMRZH0JElePJ3P336BNfjwtdg42CV9PHynu8ldjSO7NIhxAD/Lvo1YDZONPgdIlg26JvwT4BAmud1AZstsOkhz+Fo3pERHhdLxiMCy9z89VgcAmnaCyPfCxg2hqnn4NWr/MtWgD0Fdeqt9qLAwbOyiaNtXRXV3eDeZlfAmKlPrxK6WbD2umR02i0diyyBmTdVEmvhhR3//Mv0H/M8jwIhBWv7ve189enyEmqNlnG50wAAAAAElFTkSuQmCC} 柳都市星降町7丁目8番9号 登録番号 T1234567890123 2020年12月16日(水)12:34 #0903 {border:line; width:22} ^領 収 書 {border:space; width:3,*,3,8; text:nowrap} 166003 |2021葱鏡餅 水引 | 3個| ¥1,620* 691004 |洗面器45RPM N025 | 1個| ¥1,210~ - {width:auto; text:wrap} 小 計 |4点 | ¥2,830~ (税率10%対象 | ¥1,210) (内消費税等10% | ¥110) (税率 8%対象 | ¥1,620) (内消費税等 8% | ¥120) - 合 計 | ^¥2,830 お預り | ^¥3,000 お釣り | ^¥170 |*印は軽減税率対象商品です {code:202012160903; option:code128,2,48}電子レシート発行サーバーを作る
Node.js
Node.js で電子レシートを発行する HTTP サーバーを作ります。
receipt.js
の内部構成は、以下のようになっています。
- ReceiptLine
- 作成したレシートデータ (固定) を SVG に変換する
- HTML
- 作成した SVG を HTML に埋め込む
- HTTP サーバー
- 任意の GET リクエストを受けて、作成した HTML を返す
receipt.jsconst http = require('http'); const receiptline = require('receiptline'); // ReceiptLine const text = `{image:iVBORw0KGgoAAAANSUhEUgAAASAAAAAwAgMAAADMTE88AAAACVBMVEVwAAsAAAD///9xeVj9AAAAAXRSTlMAQObYZgAAAdZJREFUSMftlsFu4zAMRMUD73sI/0c59M4Amv//lXJI2XEWaGSgAVrsxuihtqgnmjOk09r7+pcv7esYAEtMM19yrCkWxwnOgEbk1Fc5nwBpRNgCpGdAhKi/4NVYaFmD1qqlYi8ACU6Y6BRo/DaQjk3hiARv4BeB834aVXBDk1bL0lHlCEs0Qz5zP4A89FVW3rgWNwGxWrRuCVIC7Ao3HjBCamY6mt7GHSQ9/rnQVEGZIBmlBPL0Fsvoig8Mg9N6KJAAB5ASFPDYzUcJytgEFXAQzpf2/ajMCMeMjCAwMX8A9ZQjQUJQ7mZs5G4TZMcaXRJd3bKBLOZLz4gC9Q00Y8030FE1Vga5egf5put0rTwDbT4SalV6fQmyp6DZIqCONXe+Aqk/A82mlcF3RO7eQeMRZH0JElePJ3P336BNfjwtdg42CV9PHynu8ldjSO7NIhxAD/Lvo1YDZONPgdIlg26JvwT4BAmud1AZstsOkhz+Fo3pERHhdLxiMCy9z89VgcAmnaCyPfCxg2hqnn4NWr/MtWgD0Fdeqt9qLAwbOyiaNtXRXV3eDeZlfAmKlPrxK6WbD2umR02i0diyyBmTdVEmvhhR3//Mv0H/M8jwIhBWv7ve189enyEmqNlnG50wAAAAAElFTkSuQmCC} 柳都市星降町7丁目8番9号 登録番号 T1234567890123 2020年12月16日(水)12:34 #0903 {border:line; width:22} ^領 収 書 {border:space; width:3,*,3,8; text:nowrap} 166003 |2021葱鏡餅 水引 | 3個| ¥1,620* 691004 |洗面器45RPM N025 | 1個| ¥1,210~ - {width:auto; text:wrap} 小 計 |4点 | ¥2,830~ (税率10%対象 | ¥1,210) (内消費税等10% | ¥110) (税率 8%対象 | ¥1,620) (内消費税等 8% | ¥120) - 合 計 | ^¥2,830 お預り | ^¥3,000 お釣り | ^¥170 |*印は軽減税率対象商品です {code:202012160903; option:code128,2,48}`; const svg = receiptline.transform(text, { cpl: 32, encoding: 'cp932', spacing: true }); // HTML const style = 'float: left; padding: 24px; background: lavender;'; const html = `<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>レシート</title> </head> <body> <div style="${style}">${svg}</div> </body> </html>`; // HTTP Server const server = http.createServer((req, res) => { switch (req.method) { case 'GET': res.end(html); break; default: res.end(); break; } }); server.listen(8080, "127.0.0.1", () => { console.log('Server running at http://127.0.0.1:8080/'); });実行
電子レシート発行サーバーを起動します。
$ node receipt.js
Web ブラウザーで
localhost:8080
を開きます。
receiptline ライブラリが動作しない IE11 でも表示 OK。
作成された SVG データ
レシートデータから生成された SVG データです。
中身はパス、画像、テキスト、Web フォント、フィルター、いろいろ入っています。SVG<svg width="384px" height="684px" viewBox="0 0 384 684" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><style type="text/css"><![CDATA[@import url("https://fonts.googleapis.com/css2?family=Kosugi+Maru&display=swap");]]></style><defs><filter id="receiptlineinvert" x="0" y="0" width="100%" height="100%"><feFlood flood-color="#000"/><feComposite in="SourceGraphic" operator="xor"/></filter></defs><g font-family="'Kosugi Maru', 'MS Gothic', 'San Francisco', 'Osaka-Mono', 'Courier New', 'Courier', monospace" fill="#000" font-size="24" dominant-baseline="text-after-edge"><g transform="translate(48,0)"><image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASAAAAAwAgMAAADMTE88AAAACVBMVEVwAAsAAAD///9xeVj9AAAAAXRSTlMAQObYZgAAAdZJREFUSMftlsFu4zAMRMUD73sI/0c59M4Amv//lXJI2XEWaGSgAVrsxuihtqgnmjOk09r7+pcv7esYAEtMM19yrCkWxwnOgEbk1Fc5nwBpRNgCpGdAhKi/4NVYaFmD1qqlYi8ACU6Y6BRo/DaQjk3hiARv4BeB834aVXBDk1bL0lHlCEs0Qz5zP4A89FVW3rgWNwGxWrRuCVIC7Ao3HjBCamY6mt7GHSQ9/rnQVEGZIBmlBPL0Fsvoig8Mg9N6KJAAB5ASFPDYzUcJytgEFXAQzpf2/ajMCMeMjCAwMX8A9ZQjQUJQ7mZs5G4TZMcaXRJd3bKBLOZLz4gC9Q00Y8030FE1Vga5egf5put0rTwDbT4SalV6fQmyp6DZIqCONXe+Aqk/A82mlcF3RO7eQeMRZH0JElePJ3P336BNfjwtdg42CV9PHynu8ldjSO7NIhxAD/Lvo1YDZONPgdIlg26JvwT4BAmud1AZstsOkhz+Fo3pERHhdLxiMCy9z89VgcAmnaCyPfCxg2hqnn4NWr/MtWgD0Fdeqt9qLAwbOyiaNtXRXV3eDeZlfAmKlPrxK6WbD2umR02i0diyyBmTdVEmvhhR3//Mv0H/M8jwIhBWv7ve189enyEmqNlnG50wAAAAAElFTkSuQmCC" x="0" y="0" width="288" height="48"/></g><g transform="translate(0,72)"><text x="54,78,102,126,150,174,198,210,234,258,270,294,306">柳都市星降町7丁目8番9号</text></g><g transform="translate(0,102)"><text x="54,78,102,126,150,162,174,186,198,210,222,234,246,258,270,282,294,306,318">登録番号 T1234567890123</text></g><g transform="translate(0,132)"><text x="0"> </text></g><g transform="translate(0,162)"><text x="12,24,36,48,60,84,96,108,132,144,156,180,192,216,228,240,252,264,276,288,300,312,324,336,348,360">2020年12月16日(水)12:34  #0903</text></g><g transform="translate(48,192)"><text x="0,12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,204,216,228,240,252,264,276">╔══════════════════════╗</text></g><g transform="translate(48,216)"><text transform="scale(1,1)" x="0,12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,204,216,228,240,252,264,276">║                      ║</text><text transform="scale(2,1)" x="24,48,60,84,96">領 収 書</text></g><g transform="translate(48,240)"><text x="0,12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,204,216,228,240,252,264,276">╚══════════════════════╝</text></g><g transform="translate(0,270)"><text x="0,12,24">166</text><text x="48,60,72,84,96,120,144,168,180,204">2021葱鏡餅 水引</text><text x="240,252">3個</text><text x="300,312,324,336,348,360,372">¥1,620*</text></g><g transform="translate(0,300)"><text x="0,12,24">691</text><text x="48,72,96,120,132,144,156,168,180,192,204,216">洗面器45RPM N02</text><text x="240,252">1個</text><text x="300,312,324,336,348,360,372">¥1,210 </text></g><g transform="translate(0,330)"><text x="0,12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,204,216,228,240,252,264,276,288,300,312,324,336,348,360,372">════════════════════════════════</text></g><g transform="translate(0,360)"><text x="0,24,48">小 計</text><text x="132,144">4点</text><text x="300,312,324,336,348,360,372">¥2,830 </text></g><g transform="translate(0,390)"><text x="0,12,36,60,72,84,96,120">(税率10%対象</text><text x="300,312,324,336,348,360,372">¥1,210)</text></g><g transform="translate(0,420)"><text x="0,12,36,60,84,108,132,144,156">(内消費税等10%</text><text x="324,336,348,360,372">¥110)</text></g><g transform="translate(0,450)"><text x="0,12,36,60,72,84,96,120">(税率 8%対象</text><text x="300,312,324,336,348,360,372">¥1,620)</text></g><g transform="translate(0,480)"><text x="0,12,36,60,84,108,132,144,156">(内消費税等 8%</text><text x="324,336,348,360,372">¥120)</text></g><g transform="translate(0,510)"><text x="0,12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,204,216,228,240,252,264,276,288,300,312,324,336,348,360,372">════════════════════════════════</text></g><g transform="translate(0,540)"><text x="0,24,48">合 計</text><text transform="scale(2,1)" x="120,132,144,156,168,180">¥2,830</text></g><g transform="translate(0,570)"><text x="0,24,48">お預り</text><text transform="scale(2,1)" x="120,132,144,156,168,180">¥3,000</text></g><g transform="translate(0,600)"><text x="0,24,48">お釣り</text><text transform="scale(2,1)" x="144,156,168,180">¥170</text></g><g transform="translate(0,630)"><text x="0,12,36,60,84,108,132,156,180,204,228,252,276">*印は軽減税率対象商品です</text></g><g transform="translate(91,636)"><path d="M0,0h4v48h-4zM6,0h2v48h-2zM12,0h6v48h-6zM22,0h4v48h-4zM30,0h2v48h-2zM36,0h6v48h-6zM44,0h4v48h-4zM52,0h2v48h-2zM58,0h6v48h-6zM66,0h2v48h-2zM70,0h4v48h-4zM78,0h6v48h-6zM88,0h2v48h-2zM94,0h6v48h-6zM102,0h4v48h-4zM110,0h4v48h-4zM118,0h2v48h-2zM124,0h2v48h-2zM132,0h2v48h-2zM138,0h2v48h-2zM144,0h4v48h-4zM154,0h4v48h-4zM162,0h2v48h-2zM166,0h6v48h-6zM176,0h4v48h-4zM186,0h6v48h-6zM194,0h2v48h-2zM198,0h4v48h-4z" fill="#000"/></g></g></svg>電子レシートの背景をカスタマイズする
ソースコードの CSS を変更して、電子レシートの背景をカスタマイズします。
単色
お店のキャンペーンでよく使われるピンクレシートと黄色いレシート。
receipt.jsconst style = 'float: left; padding: 24px; background: pink;';receipt.jsconst style = 'float: left; padding: 24px; background: #ff9;';多色
サーマルロール紙にはできないグラデーション。
receipt.jsconst style = 'float: left; padding: 24px; background: linear-gradient(skyblue, lightyellow);';receipt.jsconst style = 'float: left; padding: 24px; background: linear-gradient(lightgreen, snow, beige);';透かし
「複写」「COPY」の画像をタイル状に並べます。画像は CSS に埋め込みます。
画像の Data URI 形式への変換は ReceiptLine Designer を使うと簡単です。
画像をロードしてimage:
をdata:image/png;base64,
に置き換えます。
receipt.jsconst style = 'float: left; padding: 24px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANgAAADYAQMAAACz7r+uAAAABlBMVEXc3tv5+/j5MJA8AAADWklEQVRYw+2YPW7bMBSAqTAwMxTmBVwqR2g3G1AiH8W9gYMsCuLGSg3UW3yBwDlElwLNYMGDlza+QFsoMFqvDAy0NCpENQqRj3yCshfRmyh9En8eH98PCamllucih0+wPjT3MFPQZAh5GbQ5YvQ7tH3E2ATaAWK8Ae0MMXEAXUjEgpZpDjGLzCA0TxGTkelSIeal0tP/XSJGk9Uo1t/N0PJGi0UV478nS9MHYiL3Hw2L0fIuWpnF9t3lRQrGTps2GwQS2Fg5O3H88h765NmxzXx//tXowRcDZw18PIVJc2WrpcG5ME8tZ5cYYQKYoLZGOWkEwJpsZg2429hoYA1+mQPrxATWR9gNy0FvpzMvBcOmj3xu2It1aivfy3zYJ38pma18dUzMTP2pcuy8HwDjt1nDOW+Rxc6u8YEzjG3ayCI9YD/P4wrWYNnaZbAk7m8XLuuxpHjB8uHNO3cufFJ0SrMwv3KZr7d3p6M/U2SSLNPsy8Y9q35GivNIPydr5R4BRQoTpVcJOo+7JWjGt3mMfZE2bb5dILJnGNu+x+4mNiy5wgz+W01LTBhvc11i2qewqF1i2lxZEJXmopVBRR+7zEtZ5U2JB4piJbXksyq3sXOG0EVcB8Faaqmllv9TIGW5KMWHGUSKEksh/S3FAAg5CUpHyX7U1SzGaXMz0NFLEMyEiWwBwTGuxWUl6yw0i0p9vp7LcupUyInFephNZLnG0WFzIrsVjOajdjFMm3C3nuCrUccw381twsWHT4UaRT+8ddjbpfILxuXAydLJ2bdMMyaVW2e92T7qisZLpMu8zU2mZ0dTxNZh2jN5Fard7k7BKGLEWmsJuQbKRI7u+sCEW2CG1+Y/SkTDzSM7CsYLnE4l31gs82Pbctn6o3lIVAgm2qAzurT2Mo3ALDiLPSuZG85k36pXnJoztGuEQPRI5GSjkNq1A0mcaia1WCQPbcPj0mIPst+1D0cEIxytlJMfBqGCMmRx65TGEZdQhkxajur7LAUmhEBlP7AgDKpcQ6iGUZVLOZe/ZBV7uP+BS2PD0vkc+RQa6xddNka+iI6hXirdJkD66y7vX0UDllu6TYB5H+BU3DK0V/jGwKqFT7C7GdiWVX1ZEsZVnrZ8IWK7reYTAWC/joG1PBv5C4viMg7LEHCAAAAAAElFTkSuQmCC);';地紋
領収書やチケットでよく見かける地紋です。小さな素片をタイル状に並べます。
const style = 'float: left; padding: 24px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADAQMAAACplL1tAAAABlBMVEX/pQD////52iT3AAAAFElEQVQI12M4l/+AYf/mCQyFdwoAJNIF3T0xRTsAAAAASUVORK5CYII=);';また何か作ったら投稿します。ではまた!
- 投稿日:2020-12-16T17:55:53+09:00
positionを使用しているp要素を左揃えのままデバイスの中央に配置する方法
こんにちは。niinaです。
先日メインビジュアルの画像上に配置するコピーライトを、左揃えのまま中央に配置する方法がわからず苦悩していました…
問題になっていたのは、中央配置したいコピーライト部分のh2要素にposition指定をしていたため、margin: 0 auto;が効かないということでした。
解決策がわかったので備忘録として記録しておこうと思います。positionを使うと要素が浮いたような状態になる
今回の場合は、メインビジュアルの最下部にコピーライトを置きたかったので、コピーライトの位置をpositionで指定することにしました。
html<div class="mv"> <h2 class="mv-copy">コピーライトです</h2> </div>css.mv { position: relative; } .mv-copy { position: absolute; bottom: 0; }何も知らなかった私は安易に.mv-copyにmargin: 0 auto;すれば左揃えのまま、中央配置にできるもんだと思っていました。
が、実はpositionを使った場合、marginは効かなくなってしまうのです。
何故か??
それはpositionを使うことで、その要素自体が浮いたような状態になってしまうからです。positionとtransformで要素を移動させよう
それでは中央に配置するためにはどうすればいいのでしょうか。
そこで使うのがpositionとtransformです。
実際に見ていきましょう。css.mv-copy { position: absolute: bottom: 0; left: 50%; /*まずは要素を左に50%移動させる(要素の最左部がど真ん中にくる)*/ transform: translateX(-50%); /*余分に左に移動してしまった要素の半分だけ右に戻す*/これで完成です。
- 投稿日:2020-12-16T16:48:54+09:00
Qiitaのアイコンを四角くするcss
開発経緯
- 自分は丸いアイコンが嫌
- タグとOrganizationとの区別をつけたかった
qiita
Mozilla Format
qiita-icon.css@-moz-document domain("qiita.com") { .css-100alwu,.css-1q2yu52 img,.it-Header_authorImage,.of-PopularItem_userImage img, .od-MemberCardHeader_icon,.op-Members_member,.op-Members_member img,.tl-UserInfo_image, .ra-User_image img,.ra-User_image,.us-ImageSelect_itemIcon img,.p-settings_userLogo img, .p-settings_userLogo,.tl-ItemContent_userImage img,.tl-ItemContent_userImage, .ai-User_image,.st-Header_loginUser img,.ot-Members_member img,.ot-Members_member, .of-PopularItem_userImage,.of-ItemLink_userImage img,.of-ItemLink_userImage, .searchResult_userIcon,#logly-lift-4279494 .logly-lift-ad-icon, .adventCalendarItem_authorIcon,.it-Reference_authorImage, .co-Item_userImage{ /* User Icon */ border-radius: 0; box-shadow:0 0 3px #5c0; } .ra-Tag_image img,.ra-Tag_image,.tsi-Content_editLink img,.tsr-User_image, .tsr-User_image img,.ot-TagItem_icon{ /* Tag Icon */ border-radius: 0; box-shadow:0 0 3px #f0f; } .ra-Organization_image img,.ra-Organization_image,.op-About_icon img, .op-About_icon,.tsr-Organization_image img,.tsr-Organization_image , .ol-Item_image img,.ol-Item_image,.ol-NewestsItem_image img, .ol-NewestsItem_image,.css-auq0z5{ /* Organization Icon */ border-radius: 0; box-shadow:0 0 3px #ff0; } }UserScript
UserScript.js// ==UserScript== // @name qiitadon_icon // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @match https://qiitadon.com/* // @grant none // ==/UserScript== (function() { window.setInterval("func();", 1000); func=function(){ ele=document.querySelector("a.account__header__avatar"); ele.href=(ele.style["background-image"]).slice(5,-2) } })();
- 投稿日:2020-12-16T16:40:20+09:00
【CSS】フッター要素を表示領域に固定させる
はじめに
駆け出しエンジニアのyosukeです!
先日、私が所属するevoluの自社サービスとして「 小説執筆アプリ - Mono - 」をリリースしました!サーバーサイド側は半月くらいで作り終え、デスクトップ表示の最低限のUIを作ったところでのリリース(デプロイ)でしたので、これからフロント側の改修作業しているところです!
苦手なCSSでのレイアウト整正で特にハマったところをメモります!フッター要素を固定にしてどの画面サイズでも表示位置を維持させたい
書き方
HTML<div class="fixed_footer"> <footer> #フッターコンテンツ </footer> </div>css.fixed_footer { /* writingsページの「保存ボタンありフッター」の固定 */ position: fixed; /* フッターの固定 */ bottom: 0px; /* 位置(下0px) */ left: 0px; /* 位置(左0px) */ width: 100%; /* 横幅100% */ height: 60px; /* 縦幅60px */ }これで、画面を縮小したりスクロールしてもフッターは常にこの位置に固定表示される様になります!
以上です!
- 投稿日:2020-12-16T15:53:03+09:00
サイコロ4 ~ もっとDOM操作で色々体裁を整えつつ完成させる~
と、いうわけで、昨日の続きです。
数当てゲームとして完成させる
必要な材料は大体そろっているので、組み合わせてゲームとして動くようにします。
ゲーム内容的にはテキストベースの場合と同じなんですが、まず予想した数字を選択して、それからサイコロを自分で振るという流れにしようと思ってます。画面作成
サイコロと数字の盤はもうできています。
でも、なにをすべきか指示するメッセージが欲しいですよね。
テキストベースの場合、まず尋ねるのダイアログが上がり、そこにサイコロの出目を入力するように、メッセージがありますよね。「何が出るかな?」のラベル作成し、メッセージ1に代入。改行作成。 「予想した数字をクリックして下さい。」のラベル作成し、メッセージ2に代入。おっと……
いきなり行き詰まりますよ!
サイコロは、tableを「HTML設定」して作っているけど、HTML設定は、追加ではなくまるっと書き換えてしまうので、折角作成したラベルが消えちゃいます(´・ω・`)
単純にラベルはspan、改行はbrなので、サイコロ作るHTMLで、tableの前にHTMLとして追加することももちろん出来るんですけど、なるべくなでしこでやっていきたいですよね(サイコロ自体をHTML設定で作っておいて何ですが;;;)というわけで、「DOM要素作成」です。
ボタンなどのように「**作成」という命令にはなっていないHTMLのDOM要素も、これで作れちゃいます。(作成するだけではダメで、「DOM子要素追加」がセット商品です)なでしこ3マニュアル > plugin_browser/DOM要素作成
なでしこ3マニュアル > plugin_browser/DOM子要素追加「table」をDOM要素作成し、サイコロへ代入。 DOM親要素へサイコロをDOM子要素追加。 サイコロに「 <tr><td id="eye0"></td><td id="eye1"></td><td id="eye2"></td></tr> <tr><td id="eye3"></td><td id="eye4"></td><td id="eye5"></td></tr> <tr><td id="eye6"></td><td id="eye7"></td><td id="eye8"></td></tr> 」をHTML設定。 「サイコロを振る」のボタン作成して、サイコロボタンに代入。外枠のtableをサイコロという名前で「DOM要素作成」して「DOM子要素追加」することで、先に作ったラベルの下に追加出来ました。そしてサイコロtableの中に目の部分を「HTML設定」します。
あと、サイコロ振るボタン。
そして、予想を選択する数字盤のコードもくっつけて見た目は取りあえずこんなものかな?動作
サイコロ振ったり、数字を選択したりという一番重要な部分はもう出来ているけど、全体を通してゲームらしい流れになるように。そして、変な操作をしても予定外のことが起きないようにしていく。細々としたこと、結構大事(`・ω・´)
数字を選択するまではサイコロを振れないよう、ボタンを無効にする。
メッセージ出したところで絶対にありますよね~。順番間違えて押しちゃうとか。
フラグを用意して数字を選択するまではスルーするようにしてもいいんですが、そもそもボタンが押せないようになってる方が間違いないので、初期状態ではボタンを無効にして置いて、数字を選択したら押せるようにすることにします。サイコロボタンの「disabled」にオンをDOM属性設定。毎回disabledが綴りを調べないと書けないよ(ノД`)
これは、HTMLのbuttonの属性の1つで、要素の操作を無効にするもので、オンにすると押しても動作しなくなります。(オフ(0)以外を設定すると全部オンになるっぽく思われます)
※disabledにすると色が薄くなったり、ボタンが凹むアクションが無くなったりするのが普通ですが、ボタンが標準状態の時と同様、見た目はCSSの設定に依存します。選択したら、メッセージを変えて、サイコロを振るよう促す。
描画中キャンバスをマウス押した時のイベント内で、メッセージを書き換え、サイコロボタンも有効にする。
メッセージ1に「予想は{予想}です。」をテキスト設定。 メッセージ2に「これで良ければサイコロを振って、勝負!」をテキスト設定。 サイコロボタンの「disabled」にオフをDOM属性設定。サイコロを振っている間は、数字を選択出来ないようにする。
数字選択終了のフラグを作る。
サイコロボタンを押したらオンにして、オンの場合はキャンバスをマウス押した時の処理をスルーするようにする。
サイコロボタンは再び無効にして何度も連続して押せないようにする。サイコロボタンをクリックした時には C=0。数字選択終了=オン。 //ここ! サイコロボタンの「disabled」にオンをDOM属性設定。 0.1秒タイマー開始した時には(T) ……(中略) 描画中キャンバスをマウス押した時には、 もし、数字選択終了=オフならば、 //ここ! もし、(マウスX>マス*6)または(マウスY>マス)でなければ、 予想は(マウスX/マス+1)を切捨て。 予想で盤描画。 ……正誤表示
もう普通に言うでいいかなw(急にてきとー;)
結果を発表したら、もろもろ元に戻して、続けてもっかい出来るようにしとく。●正誤判定 もし、予想=出目ならば、「正解!!?」と言う。 違えば、「残念でした~?」と言う。 メッセージ1に「何が出るかな?」をテキスト設定。 メッセージ2に「予想した数字をクリックして下さい」をテキスト設定。 数字選択終了=オフ。0で盤描画。 ここまで。ちょっと絵文字も使ってみました~☆
ブラウザで動くので、絵文字が表示出来るのはもちろんのこと、絵文字を変数として使うことも出来るようですよ。楽しいですね♪おわります?
見た目にも楽しい数当てゲームになったでしょうかねえ?
視覚的にサイコロがサイコロとして表示されるということを除くと、キー入力を伴わずマウスで数字を選択できるようにしたくらいですが、操作性は大事ですよね~☆
ゲーム自体はほんの数行のものがなんでこんなに長くなるんだよという感じですが、いちおう、ブラウザ用のplugin_browserのDOM操作や描画の機能をあれこれ使ってご紹介してみたつもりです。
他にも、ローカルストレージとかAJAX送信とかとかありますが、サイコロだけに6まで欲しい気もしますが、数当てゲームで一体何を保存し何をGET送信するというのか……;
せいぜい音声合成で出目を読上げてもらうくらいですかねえ?
ネタが尽きているので、それで無理矢理引っ張るかも?(笑)
- 投稿日:2020-12-16T15:53:03+09:00
CSSの限界はどこにある。
前置き
CSSって思ったより凄いよって記事です。
高校生の分際で一丁前にCSSを語るなと有識者諸兄に怒られそうなので先にお詫びしておきます。大変申し訳ございませんでした。本題
謝ったので好きな事言えます。
CSSアニメーション
まずは広く知られてるであろう所から。
CSSでアニメーションが記述できる。それだけの代物。
See the Pen
ExgWJJY by HATO (@hatopoppo)
on CodePen.
最近だとハンバーガーメニューとかで見かける。( transitionで実装してる物の方が多いけど )
これを頑張れば、
See the Pen
mdrWZXY by HATO (@hatopoppo)
on CodePen.
こういう事もできる。
因みにコードはtransform-originでrotationの原点を関節の位置に変えて回してるだけ。
コードの行数と比例する形にはなるがとりあえずアニメーションに限界はなさそう。CSS変数
CSSは変数も扱える。
See the Pen
GRjWVpp by HATO (@hatopoppo)
on CodePen.
もちろんこれだけでも、全体の色味変えたりする点でとても便利だが、本命はこちら。
See the Pen
wvzJVWg by HATO (@hatopoppo)
on CodePen.
ダークモード対応。
mediaで端末がダークモードか否か判定して結果により変数を変える。今例示した二つはどちらもcolorを変数に入れた物だったが、数値型も扱えればvwやremのような単位のついたものも扱える。さらに 「 inline 」 とか 「 flex 」 のような文字列ですら扱える為スタイリングの幅が広がりそう。
因みにCSSアニメーションと組み合わせるとこういう事もできる。
See the Pen
PoGpMpG by HATO (@hatopoppo)
on CodePen.
hsl1 の h2 だけを変数で変化させたもの。これでもちゃんと動くのがすごい。
鬼のようなアニメーションの長文を見てもらうとわかるだろうが、残念ながらCSSアニメーションでは変数間の補完はできない。その為短い間隔で色を描き変えないといけない。少し残念。
ただ相変わらず限界は見えない。変数によって出来ることが広がりすぎ。attr
属性値の取得もできる。
See the Pen
LYRWwdY by HATO (@hatopoppo)
on CodePen.
こんな感じ。
pタグに付いたdata属性、data-textから文字列を持ってきた。
尚attrはCSS Level4に位置付けられる物であり、まだ草案段階のため、今は擬似要素のcontentにしか使えない。だが、今後colorプロパティに使えるようにする事なども検討されている。
data属性はjsからも扱いやすい3ので、そこからスタイルなども弄れるようになるととても面白くなりそう。
See the Pen
oNzZKVb by HATO (@hatopoppo)
on CodePen.
とりあえず今できることは、日付等のデータを入れることくらい。
これもコンポーネントっぽくてかなり需要はありそう。終わりに
初心者向けだとかプログラミング言語じゃない4だとか怪しげな情報商材屋のTwitterのプロフィールによく書いてあるだとか散々揶揄された言語ですが、見かけによらず奥深く、限界が見えないのがCSSです。
今回は飽く迄も分かりやすさ重視で、一目でわかるようなCSSの変貌を中心に据えましたが、色々と組み合わせてやれば意外と器用な事もできます。
最近は、CSS in JS など生のCSSを追いやろうとする流れが散見されますが、追いやられるべきCSSは過去の遺産となろうとしています。
限界知らずの、これからも成長していくCSSで、是非楽しい開発を。CSS is GOD
色相 明度 彩度の3つで構成される色の表し方 ↩
色相 ↩
Object.dataset.hoge で取得や変更が出来る。 ↩
因みに最近MDNが行ったアンケートで「今書いてるプログラミング言語は何ですか」という設問で選択肢にHTMLとCSSがあったので誰が何と言おうとプログラミング言語です。チューリング完全だし。http://hoo89.hatenablog.com/entry/2014/09/12/164712 ↩
- 投稿日:2020-12-16T09:42:06+09:00
【初心者でもわかる】CSSで縦書きを実装する
どうも7noteです。縦書き対応する方法について。
日本語には横書きだけでなく縦書きもあるのでCSSで対応していきます。
縦書きにするCSS
index.html<p class="tategaki">徒然なるままにうんたら<br>かんたら</p>style.css.tategaki { -webkit-writing-mode: vertical-rl; /* Safari用 */ -ms-writing-mode: tb-rl; /* IE用 */ writing-mode: vertical-rl; }解説
ベンダープレフィクス(webkitやms)を付けなければ各種ブラウザに対応できないので注意が必要です!
writing-modeには様々な指定ができるのですが、おそらく一番使われるのがvertical-rl
かなと思います。
縦書きにしたのち、右から左に行が進む書き方ですね。その他の書き方についてはMDNのサイトで確認できます!
https://developer.mozilla.org/ja/docs/Web/CSS/writing-mode変わった縦書きの方法
無理やりですが、こんな書き方で縦書きもできます。あまりするメリットはないですが。
index.html<p class="tategaki"> <span>徒</span> <span>然</span> <span>な</span> <span>る</span> <span>ま</span> <span>ま</span> </p>style.css.tategaki { display: flex; flex-direction: column; }※ 1行のみ対応。
まとめ
WEBでは縦書きのシーンはあまりないですが、CSSが用意されているあたり需要は意外とあるんじゃないかなと思います。
アジアの一部地域、特に日本では一般的に縦書きが利用されている事を思うと、日本人のためのCSSなのかなとも思えてきますね。ちょっと親近感がわきました。
おそまつ!
~ Qiitaで毎日投稿中!! ~
【初心者向け】WEB制作のちょいテク詰め合わせ
- 投稿日:2020-12-16T01:25:25+09:00
背景を半透明で美しくするCSS
apple musicのサイトで使われていたCSSです。
backdrop-filter: saturate(75%) blur(15px);
- 投稿日:2020-12-16T01:03:15+09:00
アコーディオンメニュー
自分用の備忘録に作りました。
pureなJSでアコーディオンメニューを実装し、一応簡単な形ですがレスポンシブ対応してるので、参考にしてください。完成図
コード
※注意点としては、コードはPCファーストになってます。
html<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>navber</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Font Awesome --> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.1/css/all.css" integrity="sha384-vp86vTRFVJgpjF9jiIGPEEqYqlDwgyBgEF109VFjmqGmIY/Y4HV4d3Gp2irVfcrp" crossorigin="anonymous"> <!-- Google Font --> <link rel="preconnect" href="https://fonts.gstatic.com"> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap" rel="stylesheet"> <!-- CSS --> <link rel="stylesheet" href="./css/style.css"> <!-- JS --> <script src="./js/main.js"></script> </head> <body> <!-- header --> <header> <h1>NavberTest</h1> <p>~ navber test web app ~</p> </header> <!-- navigation for pc --> <nav class="pc-nav"> <ul> <li><a href="#">menu1</a></li> <li><a href="#">menu2</a></li> <li><a href="#">menu3</a></li> </ul> </nav> <!-- navigation for sp --> <nav class="sp-nav"> <ul> <li><a href="#">menu1</a></li> <li><a href="#">menu2</a></li> <li><a href="#">menu3</a></li> </ul> </nav> <!-- bars icon --> <div class="bars" id="spNavToggle"><i class="fas fa-bars"></i></div> </body> </html>css@charset "UTF-8"; /* reset */ *{ margin: 0; padding: 0; font-family: 'Noto Sans JP', sans-serif; line-height: 1; } ul{ list-style: none; } a{ text-decoration: none; } /* header */ header{ background: #000000; color: #ffffff; padding: 10px; margin-bottom: 20px; } /* navigation for pc */ nav.pc-nav{ max-width: 960px; margin: 0 auto; } nav.pc-nav ul{ display: flex; } nav.pc-nav li{ width: 100%; border-right: 1px solid #ffffff; } nav a{ display: block; line-height: 44px; text-align: center; width: 100%; background: #000000; color: #ffffff; } /* navigation for sp */ nav.sp-nav{ /* 768px以上では非表示にする。 */ display: none; } nav.sp-nav li{ border-top: 1px solid #ffffff; transition: 0.3s; /* デフォルトでは高さを0。そして0からはみ出た分を非表示にする。 */ height: 0; overflow: hidden; } nav.sp-nav li.active{ /* JSで表示させるときのCSS。overflowを初期値のvisibleに書き換える。 */ height: 44px; overflow: visible; } /* bars icon */ .bars{ /* 768px以上では非表示にする。 */ display: none; width: 50px; height: 50px; border: 2px solid #ffffff; border-radius: 5px; color: #ffffff; text-align: center; font-size: 35px; /* positionでbodyの右上に配置*/ position: absolute; top: 10px; right: 10px; } .bars i{ /* アイコンを縦の真ん中に配置 */ line-height: 50px; } /* under 767px size */ @media screen and (max-width: 767px){ header{ margin: 0; } /* ipad以下ではpc版のnavを非表示。sp版のnavとbarsボタンを表示させる。 */ nav.pc-nav{ display: none; } nav.sp-nav{ display: block; } .bars{ display: block; } }jswindow.onload = function(){ // 変数宣言 const spNavToggle = document.getElementById('spNavToggle'); const spNavLi = document.querySelector('.sp-nav').querySelectorAll('li'); //.sp-nav内のliを全て取得し、配列化。 // クリックイベント spNavToggle.onclick = function(){ // 配列をアイテム1つずつ処理。liにactiveクラスを付与している。 spNavLi.forEach((liTag) => { liTag.classList.toggle('active'); }) } }ポイント
html
・PC版とSP版でnavを2つ書いてます。
→この方がコード量は多少増えますが、メンテが楽です。css
・上記理由でnavが2つあるので、出来るだけ共通のプロパティはまとめ、それ以外は
nav.pc-nav
,nav.sp-nav
と使い分けてCSSを適用しています。
・アコーディオンメニューの肝であるnav.sp-nav li
のheight: 0;
,overflow: hidden;
→これがメインの部分です。初期値は非表示にしたいのですが、display:none;
ではなく、アコーディオンメニューの演出の都合上、上記のような書き方になっています。その後ここにactive
クラスが追加されることでheight: 44px;
,overflow: visible;
が適用され、アコーディオンのように徐々に膨らむような動きになります。JS
ここは特に、難しいことは無いのですが、
forEach
で繰り返し処理をしたいので、配列として扱えるquerySelector
を使っています。最後に
改めてpureなJSってコード書くのめんどいなって思いました。でもプログラミングしてるなって感覚になって出来ると楽しいですねw
今後もこう言った小ネタ的なものをガンガン上げていきたいと思います。お疲れ様でした。