- 投稿日:2020-10-11T16:46:55+09:00
【javascript】ハンバーガーメニュー作成(メニュー外のクリック動作)
目標
Xボタンだけでなく、右側の表示領域をクリックしても、
ハンバーガーメニューが閉じるようにします。
開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina前提
【Javascript】ハンバーガーメニュー作成(左、上、右から表示)
今回は上記記事の補足になります。実際のコード
html<div id="box"></div> <!-- 追加 --> <nav id="nav"> <ul> <li><a href="#">リンク1</a></li> <li><a href="#">リンク2</a></li> <li><a href="#">リンク3</a></li> </ul> </nav> <div id="hamburger"> <span class="inner_line" id="line1"></span> <span class="inner_line" id="line2"></span> <span class="inner_line" id="line3"></span> </div> <style> body{ background-color: rgba(0,0,0,0.2); } #nav{ position: absolute; height: 100vh; width: 40%; left: -40%; top: 0; background: #ffffff; transition: .7s; } #nav ul{ padding-top: 80px; } #nav ul li{ list-style-type: none; } #hamburger { display: none; position: absolute; top: 20px; left: 30px; width: 50px; height: 44px; transition: 1s; } .inner_line { display: block; position: absolute; left: 0; width: 50px; height: 3px; background-color: #000000; transition: 1s; border-radius: 4px; } #line1 { top: 0; } #line2 { top: 20px; } #line3 { bottom: 0px; } .in{ transform: translateX(100%); } .line_1,.line_2,.line_3{ background: #000000; } .line_1 { transform: translateY(20px) rotate(-45deg); top: 0; } .line_2 { opacity: 0; } .line_3 { transform: translateY(-20px) rotate(45deg); bottom: 0; } /* ここから*/ #box{ position: absolute; height: 100vh; width: 100%; left: -100%; top: 0; background: rgba(0,0,0,0.8); } .back{ transform: translateX(100%); } /* ここまで追加*/ @media (max-width: 1200px) { #hamburger { display: block; } } </style> <script> function hamburger(){ document.getElementById('line1').classList.toggle('line_1'); document.getElementById('line2').classList.toggle('line_2'); document.getElementById('line3').classList.toggle('line_3'); document.getElementById('nav').classList.toggle('in'); document.getElementById('box').classList.toggle('back'); // 追加 }; document.getElementById('hamburger').addEventListener('click',function(){ hamburger(); }); // ここから document.getElementById('box').addEventListener('click',function(){ hamburger(); }); // ここまで追加 </script>追加項目
追加箇所-html<div id="box"></div>追加箇所-css#box{ position: absolute; height: 100vh; width: 100%; left: -100%; top: 0; background: rgba(0,0,0,0.8); } .back{ transform: translateX(100%); }追加箇所-jsdocument.getElementById('box').classList.toggle('back'); document.getElementById('box').addEventListener('click',function(){ hamburger(); });まとめ
方法としては前提記事同様、画面外に表示させておき、
classList.toggle('back')でbackクラスを付与して表示させています。
アニメーションもつけることはできますが、
一緒に出てくると少し違和感があったので、アニメーションはつけていません。もしスクロールアウトしてもハンバーガーメニューを表示させたい場合は、
#nav
,#hamburger
,#box
のposition: absolute;
をposition: fixed;
に変更すれば可能です。またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら https://twitter.com/japwork
- 投稿日:2020-10-11T16:27:15+09:00
はじめてのCSS設計の記録【決定編】
はじめに
この記事ははじめてのCSS設計の記録【検討編】からの続きとなっています。
初めてCSSの設計を行った記録になります。改善できる部分はまだまだあるかと思いますので、都度振り返りを行い定期的にアップデートをしていきたいと思います。はじめてのCSS設計
基本設計:PRECSS
命名規則:MindBEMdingMindBEMding(マインドベムディング)とは
BEMをCSSのクラス名に適用するために作られた規則のことです。CSSの話をしている時はMindBEMdingがBEMと呼ばれることが多いそうです。つまり、「CSSはBEMを使おう」→「CSSのクラス名はBEMのMindBEMdingに従って命名しよう」と変換することができます。
CSSのカテゴライズ
- ベース
- レイアウト
- モジュール
- ユニーク
- ヘルパー
- プログラム
基本的にはPRECSSの設計をそのまま使用しています。各グループをそれぞれファイルに分けて管理しています。公式との差異は①モジュールに接頭辞をつけないこと、②モジュールをブロックとエレメントにファイル単位で分割しないことの2点です。
1. ベース
配置内容:HTML要素、標準スタイル、リセットCSSなど
接頭辞:なしベースにはプロジェクトの標準となるスタイルや、リセットCSSを配置します。ほとんどをHTML要素に対してスタイリングしています。今回、リセットCSSにはブラウザ間の統一は図るけど要素の役割の全てを壊したくないという考えからNormalize.cssを適用しました。
更に細かく分けて管理したい場合、PRECSSではオリジナルのグループを作成することができる柔軟な設計になっているので、リセットCSSを新規のグループに分けて配置するのがいいでしょう。2. レイアウト
配置内容:ヘッダー、メインエリアなどの大きなレイアウトを形成する要素
接頭辞:ly_レイアウトにはヘッダー、メインエリア、フッターなどの要素を配置します。メインエリアの中が2カラムであれば、更にコンテンツエリアとサイドエリアなどに分けていきます。画面ごとにレイアウトが異なる場合はその都度枠組みとなるスタイルを追加していく必要があるでしょう。
他の開発者がHTMLを見た時、ly
の接頭辞がついているクラス名をみて、このクラスがレイアウトを形成しているから自分が今から開発しようとしている画面にも適用しよう、という風に判別がつきやすくなっています。3. モジュール
配置内容:再利用性のあるコンテンツ
接頭辞:なしモジュールには再利用性のあるスタイルを配置します。モジュールとは、コンポーネントとも言い換えることができ、
特定のエリアに依存せずどこでも使用が可能なもの
となっています。特定のエリアに依存せず、とはモジュールが他のスタイルが適用されている要素下でもデザインの崩れがない状態を指します。
PRECSSのモジュールにはブロックモジュール
とエレメントモジュール
に分けられていますが、BEMを使用したいと思い今回は統一しています。
更に、接頭辞がありませんが、これは接頭辞なしのクラス名はモジュールグループと判断することができ、あまりクラス名が長くならないようにと考え、つけない方針にしました。モジュールにはBEMの命名規則を適用します。
BEMとはBlock
、Element
、Modifier
の略で、それぞれ以下のように定義されています。Block:どこでも使い回せるパーツ
Element:Blockの構成要素、Blockの中でしか機能しないもの
Modifier:BlockやElementの修飾を定義するもの記法は以下のようになっており、Elementはアンダースコア2つ(__)、Modifierはハイフン2つ(--)で連結するようにします。
block block__element block__element--modifier block--modifier block--modifier__elementエレメントの下層にエレメントが来るパターンもあるかと思いますが、その場合もエレメントを2つ繋げずに、
block__element
の記法で問題ありません。ブロックが一意になっている想定なので、エレメントを重ねて命名する必要がないためです。
ElementやModifierを定義するとき必ず先頭にBlockになりクラス名が長くなりがちですが、これはどのブロックに対してなのかがわかる
やみだりに影響範囲を広げない
といった目的があります。BEMを適用する際、後述するSass
を使用することで効率よく開発することができますのでぜひ取り入れましょう。4. ユニーク
配置内容:ある特定の場所でしか使用していないスタイル
接頭辞:un_特定の場所でしか使用していないので、影響範囲がなく後からの修正が容易です。ただ、あまり乱用すると再利用性がなくなってしまうので、ユニークに配置するときはモジュールに配置できないか一旦検討してみるのがいいと思います。
ユニークグループに配置したスタイルには、どの画面で使用しているかそれぞれコメントを残すようにします。5. ヘルパー
配置内容:単一のスタイルなど
接頭辞:hp_marginやpaddingなど、ある部分だけを調節したいとなった場合に適用するスタイルを配置します。BootStrapの
mt-0
のようなクラスを定義するイメージです。6. プログラム
配置内容:JSなどでHTML要素を取得する際にセレクタとなるクラス、状態を管理するクラスなど
接頭辞:js_ または is_JSで要素に対して何か操作をする際に、接頭辞の「js_」を付けたクラスをセレクタとして扱います。また、状態の管理は接頭辞「is_」を使用し、例えば
is_active
というクラスにdisplay: block
などを当てる、といったようにスタイルを適用します。開発手順
【使用するもの】
- Fractal:スタイルガイドジェネレーターの1つ。プロジェクト内のモジュールを一元管理することができる(公式サイト)
- Sass(LibSass):CSSメタ言語。今回はnode-sassライブラリでSassを使用する(公式サイト)
- gulp:様々な処理を自動化するツール。Sassのコンパイル時に使用する(公式サイト)
開発において使用するツールや言語です。
詳しい説明はそれぞれ公式サイトをご確認ください。【事前準備】
- fractal.config.jsがあるディレクトリで
fractal start --sync
→command not foundの場合
../node_module/.bin/fractal start --sync
またはnpm i -g @frctl/fractal && fractal start --sync
- gulpfile.jsがあるディレクトリで
gulp sass:watch
→command not foundの場合
node_module/.bin/gulp sass:watch
またはnpm i -g gulp-cli && gulp sass:watch
開発の前に2つのコマンドを入力しそれぞれ起動させておいてください。
fractalの方はfractal.config.jsを配置しているディレクトリ内のドキュメントやコンポーネントが保存された時、gulpの方はscssファイルが保存された時、それぞれ自動で更新がかかるようになっています。【手順】
- Fractal上で利用できそうなモジュールを検索する
- 該当するモジュールが存在する場合はそのまま使用する
- 存在しない場合はFractalにモジュールのHTML側を作成する
- Sassでスタイリングする
- gulpでscssファイルをコンパイルする
- Fractalでモジュールの確認をする
- 実際のHTMLファイルにモジュールを適用する
1. Fractal上で利用できそうなモジュールを検索する
Fractalはスタイルガイドジェネレーターの1つです。スタイルガイドとはUIパーツやプロジェクト内のテーマをまとめておき、デザインの現物をそのまま確認することできるので、他の開発者が後から見た時に自分の使うべきクラスの見通しが立ちやすくなります。
まずはこのFractal上で、自分が利用したいモジュールがないか確認します。
2. 該当するモジュールが存在する場合はそのまま使用する
利用できそうなモジュールがあった場合は、下の
HTML
タブで適用されているクラス名を確認して実際のHTMLファイルに記述します。
例でいうと、標準ボタン
モジュールを使用したいので、HTML
タブを見てbtn
クラスを確認し、HTMLファイルに適用する、といった流れになります。3. 存在しない場合はFractalにモジュールのHTML側を作成する
利用できそうなモジュールがない場合は自分で新規作成する必要があります。このとき、後のこと考えてまずはFractal上でモジュールを作成していきます。
以下は、Fractalのディレクトリ構成となっています。
styleguide
という名前でなくても問題ありません。components:各モジュールを配置します
docs:ドキュメントを配置します
fractal.config.js:fractalの設定ファイルです
components
ディレクトリにはHTML側を実装していきます。初期設定ではhandlebars
になっていますが、今回はpug
を使用します。pugに変更する場合はfractal.config.js
で設定することができます。
components
ディレクトリには更にディレクトリを切っていますが、これはなくても問題ありません。一応大きなコンポーネントの括りで分けています。以下の例では、
Button
のディレクトリの中にDefault
とOutline
が存在しています。これは
styleguide
ディレクトリでbutton
ディレクトリを切ったからではありません。ファイル名によってこうしたディレクトリ構成になっています。このように、
button.pug
とModifierであるbutton--outline.pug
がありますが、Fractalではハイフン2つを連結させることで、そのファイルをデフォルトのモジュールに対しての変化系として認識させることができます。
ちょうどBEMのModifierと同じ命名方法だったのでそのまま使用することにしました。長くなりましたが、最後にbutton.pugの中身を見てみましょう。
button.puga.btn(href='#') 標準ボタン hr a.btn(href='#') テキストが長い場合は折り返される標準ボタン hr .btn divタグの標準ボタンボタンモジュールなのでとても単純なので、複合モジュールのようなエレメントがたくさん入れ子になっているものだともっと複雑なものになるかと思います。
今回button.pugとしては1行目のコードだけで十分だったのですが、念の為Modifierまではいかないけど、そのモジュールの変化型をまとめておきたいと思い、hr
タグの線で区切って複数パターンを表示させています。他の開発者がFractalを使ってモジュールを見た時、このHTML要素で
.btn
クラスを使用すれば画面に表示されているボタンが使用できることを認識でき、再利用されてコードの重複を抑えることに繋がります。4. Sassでスタイリングする
先程のボタンモジュールには
.btn
クラスを当てていました。このクラスに対してSassを使用してCSSの実装を行います。なぜSassを使用するのかというと、PRECSSの6つのグループごとにファイルを分けたかったというのが理由になります。
CSSのままファイルを分けてしまうと、全てのファイルを1つずつ読み込む必要があり、微小ながらパフォーマンスに影響が出てしまいます。
Sassはコンパイルする時に複数のscssファイルを1つのCSSファイルにまとめることができ、読み込みも1つのファイルで済むことができます。ディレクトリ構成は以下のようになっています。
sass
ディレクトリ直下にstyle.scss
、_utiles.scss
、categories
ディレクトリが配置されています。
categories
にはPRECSSの6つのグループがファイルごとに分けられています。
style.scss
以外のファイル名の先頭にアンダースコアが付いていますが、これはコンパイル時にファイルが生成されないようにするためです。では、そのファイルの中身はどのようにCSSとして出力されるかというと、style.scss
の中身を見ることでわかります。style.scss@import 'categories/base'; @import 'categories/layout'; @import 'categories/module'; @import 'categories/unique'; @import 'categories/helper'; @import 'categories/program';ファイル名にアンダースコアが付いたCSSファイルを出力しないscssファイルをパーシャルファイルと言いますが、このパーシャルファイルを
style.scss
で全てインポートすることで内容を一つにまとめ、style.css
として出力することができます。
この時、インポートしたファイルの順番通りにCSSの中身も出力されるので、下の方にインポートしたscssファイル程優先度が高くなります。なので、自分は上書きが起きてほしいグループ程下にインポートするようにしているので、この辺は特にオリジナルグループを作成した時は、各自調整してみてください。またまた長くなりましたが、最後に
.btn
のスタイリングですが、今回は_module.scss
ファイルに記述していきます。_module.scss.btn { display: inline-block; width: 300px; max-width: 100%; padding: 6px 10px; background-color: #004E98; border: 2px solid transparent; border-radius: 5px; box-shadow: 0 3px 6px rgba(0, 0, 0, .16); color: #fff; font-size: 1.125rem; text-align: center; text-decoration: none; transition: .25s; &:focus, &:hover { background-color: #fff; border-color: currentColor; color: #004E98; } &--outline { background-color: #fff; border-color: #004E98; color: #004E98; &:focus, &:hover { background-color: #004E98; border-color: transparent; color: #fff; } } }5. gulpでscssファイルをコンパイルする
今回はgulpの設定で、ファイルを保存するとコンパイルしてくれるようにしています。
以下は出力されたCSSです。style.css.btn { display:inline-block; width:300px; max-width:100%; padding:6px 10px; background-color:#004e98; border:2px solid transparent; border-radius:5px; box-shadow:0 3px 6px rgba(0,0,0,.16); color:#fff; font-size:1.125rem; text-align:center; text-decoration:none; transition:.25s } .btn:focus, .btn:hover { background-color:#fff; border-color:currentColor; color:#004e98 } .btn--outline { background-color:#fff; border-color:#004e98; color:#004e98 } .btn--outline:focus, .btn--outline:hover { background-color:#004e98; border-color:transparent; color:#fff }
.btn
に対して.btn--outline
という枠線のみのボタンを表示させるModifierを用意しました。
SassはBEMととても相性が良く、scssの記述量が少なく済んでいるのが出力結果からわかるかと思います。スタイリングが完了しましたので、後はFractalで実際のデザインを確認し、HTMLファイルへの方へ反映させて一連の流れが完了となります。
普通にCSSを書いて実装するより、時間が多少かかるかと思いますが、管理や他の開発者への共有のことを考えると時間をかけるべき工程だと思っています。
以上となります。
ありがとうございました。参考
2018年の終わりに改めてgulpでsass(scss)をコンパイルする【決定版】
fractal のテンプレートをpugにする
Fractalを使ったスタイルガイドの作成(中級編)
- 投稿日:2020-10-11T16:26:21+09:00
はじめてのCSS設計の記録【検討編】
はじめに
自社のCSS設計を検討しました。
内容ははじめてのCSS設計の記録【決定編】に載せようと思いますが、そこに至った経緯や取り入れた様々な設計手法の概要をまとめましたので、興味があれば順番に読み進めてください。今回はCSS設計完全ガイド ~詳細解説+実践的モジュール集を参考にさせて頂きました。とても良書でしたのでぜひ購入して読んでみてください。
CSS設計の8つの指標
CSS設計には目指すべき4つのゴールがあります。
他の言語にも言えることだと思いますが。・予測できる
・再利用できる
・保守できる
・拡張できるこの「目指すべき4つのゴールが満たされる」==「よいCSSである」、ということになります。
そして、CSS設計の4つのゴールを実現するために8つの指標があり、BEMやSMACSSなどの設計手法では、8つの指標のいずれかに該当します。下記の表は8つの指標とその指標を採用している設計手法(OOCSS, SMACSS, BEM, PRECSS)、自分たちのチームで採用・意識しているかの現状をまとめたものになります。
8つの指標 設計手法 評価 チームの現状 1.特性に応じてCSSを分類する SMACSS, PRECSS × 意識していない 2.HTMLとスタイリングが疎結合 SMACSS, BEM
△ HTML要素をセレクタに
している時がある3.影響範囲が広すぎない SMACSS, BEM
PRECSS△ 重複が起きそうなclass名
を使用している時がある4.特定のコンテキストに
依存していないALL × 影響範囲を絞るために
コンテキストに依存している5.詳細度がみだりに高くない BEM × かなり詳細度が高い 6.クラス名から
影響範囲が想像できるSMACSS, BEM
PRECSS△ クラス名に画面名を含めたり
しているが全てではない7.クラス名から
見た目・機能・役割が想像できるBEM, PRECSS △ 想像できるものもあるが
全てではない8.拡張しやすい OOCSS, SMACSS
PRECSS× 基本的に自作のスタイルは
シングルクラス設計になっている△の偶にできているところも、明確なルール決めをしているわけではないので開発者によってバラバラになってしまっています。現状、少なくとも「よいCSS」ではないことがわかります。
そこで、8つの指標を取り入れているCSSの設計手法を導入したいと考えています。設計手法検討
導入するCSS設計を検討したいと思います。
現在、OOCSS単体で開発することは少なく、他の設計手法に思想が取り入れられているため、SMACSSとBEM、PRECSSの3つの手法で検討したいと思います。ある程度学習した後に3つの手法を完全にではありませんが組み込んで、トライ&エラーで開発をしてみました。
以下の表は、3つの手法の完全に個人的な主観に基づいた比較なので、ご了承ください。
SMACSS BEM PRECSS 厳格性 △ ◎ ◯ 柔軟性 ◯ △ ◎ 学習コスト ◯ × ◯ ドキュメント ◯ ◯ △ SMACSS(スマックス)
【特徴】
* 拡張可能でモジュール的なCSS設計(Scalable and Modular Architecture for CSS)のこと
* CSSのコードを役割に応じて5つのカテゴリ分けしている
* 規則を厳格にするために、OOCSSやBEMの一部を取り入れたりすることもあるSMACSSはCSSのコードを役割に応じて、
ベース
、レイアウト
、モジュール
、ステート
、テーマ
というカテゴリに分けています。こうすることで管理がとてもしやすいです。柔軟かつある程度の規約があるので、初めてCSS設計手法を取り入れたとしても簡単に書くことができ、統一感のあるコードになるかと思います。
しかし、特徴の最後にある通り、ある程度規模が大きくなってくると規則を厳格にする必要が生じ、他の設計手法を取り入れる方法が採用されるそうです。実際に自分もSMACSSだけど自由に書けすぎてしまうと思い、SMACSS+何かで検討したいと思いました。
BEM(ベム)
【特徴】
* Block、Element、Modifierの略
* OOCSSのように基本的にはモジュールベースで実装する
* 他の設計手法に比べて厳格/強力である
* BEMはカバーする範囲がCSSに留まらず、学習コストが比較的高いBEMはCSSだけでなくファイルの出力方法やファイル構成なども厳格に定められている手法で、学習コストが他の設計手法に比べ高いですがその分強力に働きます。
今までCSS設計を導入したことがない場合、初めてがBEMだともしかしたら難しいかもしれません。ただ、BEMの命名規則は比較的導入しやすいと感じました。厳格であり、一発でスタイルを適用させることができるのでパフォーマンス的にも良いです。
PRECSS(プレックス)
【特徴】
* 接頭辞付きのCSS(prefixed CSS)
* CSSを役割に応じて6つのグループに分類し、それぞれに規則を設けている
* グループごとに2文字の接頭辞をクラス名に付けており、開発要件に合わせて独自のグループを作成することも可能
* 命名規則がどのグループのものかわかりやすく、ある程度柔軟かつ厳格に定義することができるPRECSSは名前の通り、CSSを役割に応じて6つに分け、それぞれのグループのクラス名に2文字の接頭辞を付けるようにしています。こうすることで、そのクラスがどのようなスタイリングをするか想像しやすくなり、使いまわしたり管理しやすくなります。
また開発要件に合わせ、オリジナルのグループも作成することができるので、柔軟かつある程度のルール化ができるので、導入がしやすいと感じました。
OOCSS、SMACSS、BEMに強く影響を受けており、それぞれのいいトコ取りをしていて、他の設計手法に馴染みがある人も導入のハードルが低いと思います。
結論
「導入しやすいものをそれぞれ取り入れて組み合わせる」
それぞれの設計手法はCSS設計の4つのゴールを満たすために考えられてますので、どれか1つに決めて構築していくでももちろん良いと思いますが、かゆい所に届かなかったり、学習コストが高く他の開発メンバーの導入が難しかったり、という懸念もあります。
なので、それぞれの良い点、導入しやすい点を組み合わせたものを自分たちのCSS設計としたいと思います。
大事なのは、これが完成版ではないということで、定期的な振り返りを行いアップデートを重ねて、より自分たちに適したCSS設計を目指していきましょう。
- 投稿日:2020-10-11T15:40:38+09:00
CSSでポップアップを表示させる方法
こんにちは!!
今回は、CSSのアニメーションを使ってポップアップの表示を実装してみました
サイトに遷移したときに出てくるキャンペーンのクーポンなどはこうやって作れるのかと分かりました1.index.html内に記述
index.html<div class="message">Hello!</div>2.cssへの記述
styles.css.message { width: 300px; height: 50px; border-radius: 4px; padding: 8px 16px; box-shadow: 0 2px 4px rgba(0, 0, 0, .2); background: #0f35e2; color: #ddd; position: fixed; top: 32px; right: 32px;
このような画像を作ることが出来ました
この記述にアニメーションをつけることでフェードインさせていきます3.アニメーションの記述
styles.css@keyframes popup { 0% { transform: translateY(20px); opacity: 0; animation-timing-function: ease-out; } 20%, 80% { transform: none; opacity: 1; } 100% { transform: translateY(20px); opacity: 0; pointer-events: none; } }styles.css.message { width: 300px; height: 50px; : animation: popup 2s forwards; //ここの記述を足す }このようにフェードインさせることが出来ました!!
今後は、Javascriptを使い、スクロールしたときに発火させたりしたいなあと考えています!!
- 投稿日:2020-10-11T15:32:20+09:00
cssの@keyframesアニメーションでガタゴト進む車を実装する
完成版デモ
See the Pen ガタゴト進む車 by kuma-onigiri (@kuma-onigiri) on CodePen.
実装イメージ
アニメーションは
@keyframes
を使います
1、車の画像を配置する
2、斜めに動くアニメーションをつける
3、上下にガタゴト動くアニメーションをつける車を用意する
ベースのHTMLとCSS
index.html<div class="move-animation"> <div class="gata-gata-animation"> <img class="car" src="車の画像のパス"> </div> </div>main.css.car { width: 75px; /* 車のサイズは適当に幅75pxくらい */ }
@keyframes
は、1つの要素に複数のアニメーションをつけることはできないので、2段構えでつけています。
上下に揺れる用のgata-gata-animation
クラスをつけた要素を、さらに<div>
で囲って、動くアニメーション用のmove-animation
クラスをつけてあげるのがポイントです。斜めに動くアニメーションをつける
main.css.move-animation { transform: translate(250px, 0px); animation: move 16s linear infinite; } @keyframes move { to { transform: translate(0px, 250px); } }初期位置は
translate
で右に250pxくらいずらした状態にしておきます。
そこから左下に動いていくアニメーションをつけます。時間は適当に16秒くらいにしてます。上下にガタゴトうごくアニメーションをつける
main.css.gata-gata-animation { animation: gata-goto .3s infinite; } @keyframes gata-goto { 20% { transform: translateY(-2px); animation-timing-function: cubic-bezier(0.4, 0, 1, 1.3); } 25% { transform: translateY(0px); } 55% { transform: translateY(-1px); animation-timing-function: cubic-bezier(0.4, 0, 1, 1.3); } 60% { transform: translateY(0px); } }
transform
で上下に2回動くのを作り、それをinfinite
で延々と繰り返しています。
ちょっとバウンドする感じにしたいのでanimation-timing-function
をcubic-bezier(0.4, 0, 1, 1.3)
にしています。ここはブラウザの開発者ツールで調整できるのですが、
左の赤丸のところのマークをクリックするとベジエ曲線のグラフが出てくるので、ハンドルを動かして好きな動きにできます。
右の赤丸のところを上に盛り上がるようにすると、ぼよんって感じの動きになります。
おわり
アニメーションを2段構えにするのがポイントでした。
これを応用すれば、ぴょんぴょん動くアニメーションとかもできますね。
- 投稿日:2020-10-11T14:40:35+09:00
【jQuery】【ancestry】を使用した、多階層ツリーメニューの実装
経緯
現在絶賛作成中のポートフォリオで、フリマアプリのラクマのような多階層ツリーメニューを実装したいと思い作成。振り返ってみればさほど難しくはなかったけれども、色々躓いたので記載しておこうと思います。
環境
ruby 2.6.5
Rails 6.0.3.2
haml使用完成図
親のカテゴリー(第1階層)をクリックすると、子のカテゴリー(第2階層)のサブメニューが現れるという仕組み。手順
1、ancestryの導入
2、HTMLで多階層の形を実装
3、jQuery(JavaScript)で、第1階層のカテゴリーをクリックすると、第2階層のサブメニューが表示されるイベントを記載する※CSSは今回は記載しません、ごめんなさい
ancestryの導入
余談ですが、ancestryを導入しなくても、HTMLに記載すれば多階層ツリーメニューの実装自体は出来ます。只、第2階層のサブメニューのカテゴリをクリックして、そのカテゴリの商品一覧を表示させたいとなるとancestryを導入は必須になります。
余計な余談になりましたが、早速ancestryを導入していきましょう!
Gemfile.#追記(一番下が好ましい) gem 'ancestry'記載が終了したら、
ターミナルで% bundle install
して% rails s
忘れずに行いましょう。
続いてcategoryモデルの作成です。ターミナル.$ rails g model categoryこの時点で、マイグレーションファイルは作成されていますので、
マイグレーションファイルを編集しましょう。2020xxxxxxxx_create_categories.rbclass CreateCategories < ActiveRecord::Migration[6.0] def change create_table :categories do |t| t.string :name, null: false #これを追記 t.timestamps end end endターミナルで
rails db:migrate
さらに、categoryモデルにancestryのカラムを追加したいのでターミナルで以下のコマンドを入力
ターミナル.% rails g migration AddAncestryToCategory ancestry:string:indexターミナルで
rails db:migrate
続いて、seedにデータ作成をします。
詳しくはこちらの記事を見てみてください。
分かりやすく書いてくれている記事なので、親カテゴリー、子カテゴリーなどの意味が理解出来ると思います。
【フリマアプリ】ancestryを用いたseedデーター作成について
seeds.rb
にデータを記載していくんですが、今回は僕が作ったものを貼り付けておきますので参考にして見てください。と言ってもメチャクチャ使い回しなんですけど・・・・
大事なのは、name:xxxxx
のxxxxxの部分なので、ここの名前を実装したいものと、照らし合わせて変更してください。db/seed.rb# パーツ lady = Category.create(name: "パーツ") lady_1 = lady.children.create(name: "パーツすべて") lady_2 = lady.children.create(name: "マフラー") lady_3 = lady.children.create(name: "エンジン/冷却装置") lady_4 = lady.children.create(name: "ホイール") lady_5 = lady.children.create(name: "タイヤ") lady_6 = lady.children.create(name: "ハンドル") lady_7 = lady.children.create(name: "ブレーキ") lady_8 = lady.children.create(name: "外装") lady_9 = lady.children.create(name: "駆動系") lady_10 = lady.children.create(name: "電装形") lady_11 = lady.children.create(name: "その他") # アクセサリ men = Category.create(name: "アクセサリ") men_1 = men.children.create(name: "アクセサリすべて") men_2 = men.children.create(name: "バイクカバー") men_3 = men.children.create(name: "ステッカー/デカール") men_4 = men.children.create(name: "タンクバック") men_5 = men.children.create(name: "サドルバッグ/サイドバック") men_6 = men.children.create(name: "シートバック") men_7 = men.children.create(name: "ツーリングネット/ロープ") men_8 = men.children.create(name: "鍵/ロック") men_9 = men.children.create(name: "エアバック") men_10 = men.children.create(name: "ETC") men_11 = men.children.create(name: "ナビ") men_12 = men.children.create(name: "オーディオ") men_13 = men.children.create(name: "その他") # バイクウェア baby_kids = Category.create(name: "バイクウェア") baby_kids_1 = baby_kids.children.create(name: "バイクウェアすべて") baby_kids_2 = baby_kids.children.create(name: "ヘルメット/シールド") baby_kids_3 = baby_kids.children.create(name: "ゴーグル") baby_kids_4 = baby_kids.children.create(name: "グローブ") baby_kids_5 = baby_kids.children.create(name: "プロテクター") baby_kids_6 = baby_kids.children.create(name: "ジャケット") baby_kids_7 = baby_kids.children.create(name: "革ツナギ") baby_kids_8 = baby_kids.children.create(name: "雨具") baby_kids_9 = baby_kids.children.create(name: "靴") baby_kids_10 = baby_kids.children.create(name: "バック") baby_kids_11 = baby_kids.children.create(name: "パンツ") baby_kids_12 = baby_kids.children.create(name: "シャツ") baby_kids_13 = baby_kids.children.create(name: "フェイスマスク/ネックウォーマー") baby_kids_14 = baby_kids.children.create(name: "その他") # メンテナンス interior_residence_accessory = Category.create(name: "メンテナンス") interior_residence_accessory_1 = interior_residence_accessory.children.create(name: "メンテナンスすべて") interior_residence_accessory_2 = interior_residence_accessory.children.create(name: "バッテリー") interior_residence_accessory_3 = interior_residence_accessory.children.create(name: "オイル") interior_residence_accessory_4 = interior_residence_accessory.children.create(name: "フィルター") interior_residence_accessory_5 = interior_residence_accessory.children.create(name: "スタンド") interior_residence_accessory_6 = interior_residence_accessory.children.create(name: "工具") interior_residence_accessory_7 = interior_residence_accessory.children.create(name: "その他") # その他 book_music_game = Category.create(name: "その他") book_music_game_1 = book_music_game.children.create(name: "すべて") book_music_game_2 = book_music_game.children.create(name: "ファッション") book_music_game_3 = book_music_game.children.create(name: "グッズ") book_music_game_4 = book_music_game.children.create(name: "カタログ") book_music_game_5 = book_music_game.children.create(name: "マニュアル") book_music_game_6 = book_music_game.children.create(name: "本/雑誌") book_music_game_7 = book_music_game.children.create(name: "その他")ターミナルで
% rails db:seed
でこのデータを反映させます。Sequel pro(ホットケーキがアイコンのもの)をインストールしている方は、それにデータがちゃんと反映されているか確認して見て下さい。
ちゃんと反映されていたら下記の画像のようになります。
ancestry カラムのデータ中の NULL の所が親カテゴリーです
コントローラーの入力の所で必要な知識になるので覚えて置いてください。ちなみに、上記の記事を参考にして貰えば分かりますが、
lady = Category.create(name: "パーツ")
←この形の記載が親のカテゴリー(第1階層)
baby_kids_1 = baby_kids.children.create(name: "バイクウェアすべて")
←この形の記載が子カテゴリー(第2階層)の記載になります。もし入力するカラム名などに不備があった場合は以下のコマンドを入力してseed.rbを修正しましょう。
% rails db:migrate:reset
修正してもう一度rails db:seed
% rails db:seed
最後に、categoryモデルで ancestryを使用できるようにモデルに下記を記載します。
category.rbhas_ancestry
以上で、ancestryの導入は終了です!
HTMLで多階層の形を実装
続いては、HTMLで多階層の形を実装していきます。
下記のものが、コードになります。index.html.haml.categories .categories--contents .categories--title カテゴリから探す %ul.category__parent - @parents.each do |parent| .category-box{id: "parent_category#{parent.id}"} %p.parent_category{id: "parent#{parent.id}"} = "#{parent.name}" %i.fas.fa-angle-down %ul.category__child{id: "parent_list#{parent.id}"} - parent.children.each do |child| .category-box{id: "parent_category#{child.id}"} = link_to "#{child.name}", "#", class: "parent_category",id: "child#{child.id}" %i.fas.fa-angle-right
続いて、コントローラーの記載です。
xxxxx_controller.rbdef index @parents = Category.where(ancestry: nil) end先ずは、HTMLでも使っているので、コントローラーの変数の説明から
これは、Categoryテーブルの ancestryカラムの nilのデータ、
要は上記のSequel proの画像を見て貰えればと思いますが、NULLと書かれたデータを
取り出して、parentsという変数に代入しています。
つまり、親カテゴリーのデータを取り出しているという事ですね。
続いてHTMLの説明ですが、
- @parents.each do |parent|
コントローラーで作った変数parents と eachメソッドを使って、
親カテゴリー(第1階層)のデータを抽出します。
- parent.children.each do |child|
これも同様に eachメソッドを使って、
子カテゴリー(第2階層)のデータを抽出します(理屈よりもこの形で覚えた方が早いと思います)いくつかある
id:"xxxxx"
の部分は、jQueryのイベントの際に、またCSSでのコーティングの際に必要になるので、わざわざidを振っています。このままでは、子カテゴリー(第2階層)が見えたままなので、display: noneで消しましょう。
xxxxx.css.category__child{ display: none; }これで、HTMLで多階層の形を実装は終了です!
最後に、jQueryの実装です。
jQuery(JavaScript)で、第1階層のカテゴリーをクリックすると、第2階層のサブメニューが表示されるイベントを記載する
それでは、最後にイベントを発火させるjQueryの記載をしましょう。
下記のものが、コードになります。$(function(){ $('#parent_category1').click(function(){ $("#parent_list1").slideToggle('1000'); }); $('#parent_category13').click( function(){ $("#parent_list13").slideToggle('1000'); }); $('#parent_category27').click(function(){ $("#parent_list27").slideToggle('1000'); }); $('#parent_category42').click(function(){ $("#parent_list42").slideToggle('1000'); }); $('#parent_category50').click(function(){ $("#parent_list50").slideToggle('1000'); }); });ここで注意なのですが、コード自体はそれ程難しいものではないと思うのですが、
parent_category"1" parent_list"1" などの数字の部分に注意が必要です。上記の seed.rb をそのままコピペした方は特に問題ないと思いますが、
自分で作成したという方は、恐らくここの数字が変わってくると思いますので、
大変恐縮ですが、ご自身で検証画面を見て、この数字の部分を確認してみてください。
コードの説明ですが、とても簡単です。
parent_category1(親カテゴリー)の階層をクリックしたら、parent_list1(子カテゴリー)が
表示されるというシンプルなものになっています。この実装にはslideToggleメソッドを使用しています。
このメソッドは、指定された要素が表示されている時はslideUpで非表示にし、非表示になっている時はslideDownで表示するというメソッドになります。ちなみに、格好の中の数字〔slideToggle('1000')〕は、スライドのスピードです。このメソッドについて詳しく知りたい方はこちらの記事を参照ください。
slideToggle()メソッドについて
これで、全ての実装が完了です!
実装出来なかったなどの不備が有ればご連絡ください!ありがとうございました。
- 投稿日:2020-10-11T11:03:20+09:00
よく使うCSSのカラーコードについて
■ はじめに
普段、何気なく使っているCSSのカラーコードについて、記事にしましたのでご覧下さい。
この記事について得られる事は以下の通りです。・カラーコードの構成・仕組み
・カラーコードの記述(短縮方法)■ 16進数のカラーコード構成
.test { color: #112233; } 最初の2桁(11):赤 次の2桁(22):青 最後の2桁(33):緑 で構成し、16進数で表現されている 16進数 → 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f・何故、10進数ではないのか
→ 10進数では色の情報量が不足し色を表現しきれない為。
10進数 → 10*10*10*10*10*10 = 1,000,000
16進数 → 16*16*16*16*16*16 = 16,777,216■ 色の指定方法について
- 16進数 #112233 → 最も使用頻度が高い - 16進数の短縮した書き方 #ffffff → #fff #112233 → #123 #ff0000 → #f00 → 赤青緑の2桁が同じであれば短縮できる - キーワードで指定する red → 要素に色をつけて分かりやすくする等。一時的に使用するコードを短縮することで、素早くスッキリした形で書けて修正も簡単。
但し、会社やチーム等で指定がある場合は指示に従う。ただ、16進数とキーワードは混同させず、どちらを使うか事前に決めておいた方が良い。
チーム開発で書いたコードを後から見直すと、ごっちゃになっていました。他にもRGBやHSLといった、色の他に透過度も指定した方法もありますが、ここでは割愛します。
- 投稿日:2020-10-11T10:29:18+09:00
【初心者でもわかる】CSSで半円を作る方法
どうも7noteです。今回は半円の作り方
正円や楕円形はよく使われるので情報が多いのですが、
意外と使われない半円の作り方を紹介。作り方
div { width: 200px; /* 直径の長さ */ height: 100px; /* 半径の長さ */ border-top: 100px solid #000; /* 半径の長さ */ border-radius: 100%; /* 角丸100%を指定 */ }これだけで、半円を作れます。
補足
上半分にする時は
border-top
。下半分のときはborder-bottom
。
このときはheightを半径の長さにしてください。逆に左右に作るときはwidthを半径の長さにして、heightを直径の長さに指定します。
transformも使うと、回転できるので好きな角度の半円を作れますね。おそまつ!
~ Qiitaで毎日投稿中!! ~
【初心者向け】HTML・CSSのちょいテク詰め合わせ