20210110のHTMLに関する記事は13件です。

CSSアニメーションを使って、Webブラウザに流れ星を流したい

tl;dr(Too Long, Don't Read)

  1. HTML/CSSを使って、Webブラウザに流れ星を流してみました
    1. 完全に再現はできないので、過度な期待はしないでください笑
    2. スクリーンショット 2021-01-10 21.12.44.png
  2. 成果物は以下の通りです
    1. https://boring-swartz-8cf676.netlify.app/
  3. ソースコードはこちらから確認できます
  4. 主に以下の4点のCSSの機能を用いて流れ星を実装しました
    1. CSS Animation/keyframesで「流れ星の動き」を表現
    2. linear-gradientを使って、「流れ星のしっぽ」を表現
    3. opacityで「流れ星が消える様」を表現
    4. transform: rotateを使って「流れる向き」を表現

はじめに

趣味で宇宙開発を行う団体「リーマンサット・プロジェクト」がお送りする新春アドベントカレンダーです。私はRSP-01という超小型人工衛星の、地上局運用システムの開発を担当しています。

今回は、Webブラウザに流れ星を流したかったので、HTML,CSSの基本的な技術を用いて流れ星を表現してみました。

流れ星とは?

流れ星を見たことがないという人は、Youtubeに動画が投稿されているので、見て頂くと良いと思います。

また「流れ星って何が流れているの?星なの?」など、流れ星が流れる仕組みを知りたい方は、以下のサイトが参考になります。

方針

  • HTML, CSS JavaScriptを使って表現する

実装

実装に関して、主に以下の4点を説明します。

  1. CSSアニメーションを使って、流れ星の動きを表現する
  2. linear-gradientを使って、流れ星のしっぽを表現する
  3. opacityを使って消える動きを表現
  4. transform: rotateを使って流れる向きを表現

1. CSSアニメーションを使って、流れ星の動きを表現する

まず、流れ星の動きを表現します。そのために、CSSアニメーションを利用します。
CSSアニメーションとは、CSSの記述だけで、HTML要素に動き(アニメーション)を持たせる機能です。

今回はCSSアニメーションの中で、CSS Animationを使ったアニメーションを利用して、流れ星の動きを表現してみます。
まずは、簡単に白い線を引くアニメーションを作ってみます。実際のコードは以下の通りです。

<div class="star"></div>
.star {
  height: 0;
  width: 2px;
  background: white;
  animation-name: shooting;
  animation-duration: 0.8s;
  animation-timing-function: linear;
}

@keyframes shooting {
  0% {
    height: 0;
  }

  100% {
    height: 80px;
  }
}

上のコードをWebに表示すると以下のようなアニメーションが実行されます。

  • animation1_2.gif

今回のポイントとしてはCSS Animationの設定項目と、keyframesです。

CSS Animationではいろいろな設定項目があるのですが、今回はanimation-nameanimation-duration, そしてanimation-timing-functionの3つです。

  • animation-name
    • keyframesの名前を指定します。
  • animation-duration
    • 指定されたアニメーションの開始から終了までの時間
    • 今回は0.8s=0.8秒かけてアニメーションを実行します
  • animation-timing-function
    • アニメーションの進行方法
    • 今回は指定したアニメーションの各ステップを等しいスピードで進めるlinearを指定

次にkeyframesは実際のアニメーションの動きを指定します。0%が開始時のスタイル、100%が終了時のスタイルを指定することで、開始から終了までの動きを表現できます。今回はheight0px -> 80pxになるような指定をしています。

2. linear-gradientを使って、流れ星のしっぽを表現する

先ほどのCSSアニメーションで流れ星の流れを表現できました。ただ、これでは単なる白い棒が伸びているだけで、流れ星とは呼べません。
流れ星といったら、流れに沿って見えてくるしっぽの部分が必要です。

この流れ星の尻尾を表現するためにlinear-gradientを利用します。

linear-gradientとは色の指定方法の1つですが、その特徴は色を連続的に変えて濃淡を表現できる点です。このlinear-gradientを使って、流れ星の尻尾を表現すると、以下のようになります。

css
.star {
  height: 0;
  width: 2px;
-  background: white;
+  background: linear-gradient(transparent, rgb(255, 255, 255));
  animation-name: shooting;
  animation-duration: 0.8s;
  animation-timing-function: linear;
}

@keyframes shooting {
  0% {
    height: 0;
  }

  100% {
    height: 80px;
  }
}

上述のコードをWeb上で確認すると以下のように表現されます。流れ星の先から尻尾までに濃淡が表現されており、流れ星ぽく見えるかと思います。
- animation2.gif

linear-gradientの解説ですが、今回は2つの色(透明:transparent, 色:rgb(255, 255, 255))を指定してます。これによって、透明→白への濃淡が表現できました。

{
  background: linear-gradient(transparent, rgb(255, 255, 255));
}

3. opacityを使って消える動きを表現

だんだん流れ星っぽくなってきました。

次は、流れ星が消える表現を追加します。現状は、一瞬で消える動きになっていますが、フワッと消える動きにしてみたいと思います。

そのためにopacityを使います。opacityは透明度を表すCSSです。では、フワッと消える表現をopacityを使って表現すると以下のようになります。

.star {
  height: 0;
  width: 2px;
  background: linear-gradient(transparent, rgb(255, 255, 255));
  animation-name: shooting;
  animation-duration: 0.8s;
  animation-timing-function: linear;
}

@keyframes shooting {
  0% {
    height: 0;
+    opacity: 50%;
  }

+
+  50% {
+    height: 60px;
+    opacity: 100%;
+  }

  100% {
    height: 80px;
+    opacity: 0;
  }
}

変更した点は2つです。

1つ目はkeyframesに50%のステップを追加。そして、2つ目はopacityを使い、keyframesの50%をピークに透明度の上下を追加しました。

これにより流れ星が流れるに従って色が濃くなり、ピークを過ぎるとだんだん薄くなりながら消えていく表現ができました。

以下が、実際の表示です。

  • animation3.gif

4. transform: rotateを使って流れる向きを表現

最後に、流れ星の流れる向きを変えられるようにします。

現状は上から下へしか流れません。この流れる向きをtrasnform: rotateを使って変えられるようにします。

transfrom rotateは、指定の要素の向きを回転させるCSSです。

要素の向きを回転させることで流れ星の流れる向きを変えてしまおうというのが、今回の実装の意図です。実際のコードが以下の通りです。

<div class="star-box">
  <div class="star">
</div>
+
+.star-box {
+  height: 100px;
+  width: 100px;
+  transform: rotateZ(45deg);
+}

.star {
  height: 0;
  width: 2px;
  background: linear-gradient(transparent, rgb(255, 255, 255));
  animation-name: shooting;
  animation-duration: 0.8s;
  animation-timing-function: linear;
}

今回はstar-boxという流れ星要素の上に新しく要素を追加しています。また、その要素にtransform: rotationを指定しています。

ポイントとしてはtransform: rotationを流れ星の要素(star)ではなく、一つ上の要素(star-box)に指定する点です。transform: rotationを流れ星の要素(star)に指定すると、CSSアニメーションによって自身の大きさが変化するにつれて全体の位置が動いてしまいます。先ほどは上から下へ流れるため高さしか変化しませんでしたが、向きを変化させることで横幅も変化してしまうことが位置がずれの原因です。

そのため、一つ上に縦横の長さを固定した要素(star-box)を作り、それを回転させることで、上述の位置ズレを回避しています。

上述のコードをWeb上で確認すると、以下のようになります。

  • animation4.gif

完成

上述のコードで流れ星は完成です。

実際の成果物はnetlifyにデプロイしました。

実際のソースコードでは、ボタンを用意し、流れ星が流れる頻度を変えられるボタンを追加しています。また、ランダムに流れ星の表示位置を計算しています。表示位置については、流れ星が中心から同心円状に流れるように計算しています。これについては今回は説明を割愛します。

詰まった点

今回紹介した当初はnuxt.jsで実装していました(以下、該当のリポジトリ)
- https://github.com/Ushinji/shooting_star_simulator

ただ、SSGでビルドしてnetlifyにデプロイすると、css animationがうまく機能しなかったので断念しました。

おわりに

今回はCSSアニメーションを使って流れ星をWeb上に表現する実装を説明しました。

実際の流れ星はもっと綺麗なので(笑)、流れ星に興味を持った方は、実際に流星群の時期に夜空を見上げてもらえればと思います。以下に、日本での流星群の時期の一覧が紹介されているWebサイトを記載しておきます。

最後に

明日は @ukisoft さんの「firebase storage のサイズが大きくなったのでオラったらやらかしちゃった話」です。

また、リーマンサット・プロジェクトは「普通の人が集まって宇宙開発しよう」を合言葉に活動をしている民間団体です。
興味を持たれた方は https://www.rymansat.com/join からお気軽にどうぞ。

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者でもわかる】CSS1行で2段や3段の多段リスト(マルチカラム)を作る

どうも7noteです。逆N字順のように以下のような縦向きに順番で並んでいるが、横に複数列に分けられるような多段リストの作り方

――――――
1 4 7
2 5 8
3 6 9
―――――― 

見本

sample.png

作り方:column-countを使って多段リスト(マルチカラム)を作る

index.html
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
</ul>
style.css
ul {
  column-count: 3;        /* 列数を3列に指定 */
}

結果

sample.png

このようにCSS1行で実装することができます。
個数が半端になってしまう場合でも自動的にいい感じに配置してくれます。

-2列の場合-

sample2.png


<+α技> 段同士の幅を調節することも可能!(IE非対応)

style.css
ul {
  column-count: 3;        /* 列数を3列に指定 */
  column-gap: 20px;       /* 各列の間隔を調整する */
}
ul li {
  border: 1px solid #000; /* 分かりやすいように線を引く */
}

結果
sample3.png

このように段同士の間隔を調整することも可能です。


<+α技> <li>の下にpaddingを取ると2列目以降が崩れるときの対処方法

崩れてしまう例

sample4.png

下方向にmarginpaddingを入れてこのようにくずれてしまう場合は以下のように対応することで対策が可能です!

style.css
ul li {
  width: 100%;            /* 幅を100%にする */
  margin: 0 0 20px;       /* 下方向に20pxの余白 */
  box-sizing: border-box; /* 線幅やpaddingも含めて幅100%にするため */
  display: inline-block;  /* インラインブロック要素にする */
  border: 1px solid #000; /* 分かりやすいように線を引く *
}

結果

sample5.png

まとめ

動的に吐き出す箇所だったり、個数が未定のところにはとても使いやすい方法です。
ただちょっとだけ使い方に癖があったり、枠がないものを並べたときに右側が空いて見えてしまうのでそのあたりは工夫が必要なところもあります。

でも短いCSSで簡単に実装できるので、とても便利ですね!
これ以外の方法でやろうとすると、どうしても段数分のdivを作る必要が出たり、順番が横方向になってしまうなどの点があるので。

参考:
http://www.htmq.com/css/column-count.shtml
https://www.bricoleur.co.jp/blog/archives/4336

おそまつ!

~ Qiitaで毎日投稿中!! ~
【初心者向け】WEB制作のちょいテク詰め合わせ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

jquery(private, publicプロパティ)

初めに

 ジャバスクリプトのprivate, publicプロパティがあります。

private, publicプロパティに対して

①クラスを定義する
②private プロパティ、public プロパティを定義する
③ボタンをクリックすると、クラスのインスタンスを生成し、public プロパティをよぶ

①HTML分に以下のHTMLソースを追加する

<html>

  <head>
    <title>Hoge</title>
  </head>

  <body id="main-id">
  </body>

</html>

②JQUERYを選択してから、JAVASRIPT分に以下のソースを追加する

// マインオブジェクト
var $main  = $("#main-id");

// クラス定義
var Hoge = function() {

  // private プロパティ
  var privateString = "サンプルテキスト";

  // public プロパティの場合、 thisを使う
  this.privateString = privateString;
};

// ボタンオブジェクト
var $button = $("<button>").html("hoge");

// ボタンクリックイベント
$button.click(function() {

   // インスタンス作成
   var hoge = new Hoge();

   // public プロパティを呼ぶ
   alert(hoge.privateString);
});

//親オブジェクトに子オブジェクトを追加
$main.append($button);

実行
スクリーンショット 2020-12-23 13.31.10.png

private, public関数に対して

①クラスを定義する
②private 関数、public 関数を定義する
③ボタンをクリックすると、クラスのインスタンスを生成し、public 関数をよぶ

①HTML分に以下のHTMLソースを追加する

<html>

  <head>
    <title>Hoge</title>
  </head>

  <body id="main-id">
  </body>

</html>

②JQUERYを選択してから、JAVASRIPT分に以下のソースを追加する

// マインオブジェクト
var $main  = $("#main-id");

// クラス定義
var Hoge = function() {

  // private プロパティ
  var privateString = "サンプルテキスト";

  // public プロパティの場合、 thisを使う
  this.privateString = privateString;

  // private 関数
  var show = function() {
    alert(privateString);
  };

  // public 関数の場合、thisを使う
  this.show = function() {
      return show();
  }
};

// ボタンオブジェクト
var $button = $("<button>").html("hoge");

// ボタンクリックイベント
$button.click(function() {

   // インスタンス作成
   var hoge = new Hoge();

   // public 関数を呼ぶ
   hoge.show();
});

//親オブジェクトに子オブジェクトを追加
$main.append($button);

実行
スクリーンショット 2020-12-23 13.35.56.png

public関数に対してprototypeもできます。

例)

// クラス定義
var Hoge = function() {

  // private プロパティ
  var privateString = "サンプルテキスト";

  // publicの場合、 thisを使う
  this.privateString = privateString;


  // private 関数
  var show = function() {
    alert(privateString);
  };

  // public 関数の場合、thisを使う
  this.show = function() {
      return show();
  }
};

↓ 上の方法の代わりに、prototypeもできます

// クラス定義
var Hoge = function() {

  // private プロパティ
  var privateString = "サンプルテキスト";

  // public プロパティの場合、 thisを使う
  this.privateString = privateString;
};

// public 関数の場合
Hoge.prototype.show = function() {
    alert(this.privateString);
};

結果
スクリーンショット 2020-12-24 16.22.53.png

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

jqueryのタグまとめ

初めに

jQueryを使う上で最低限知ってないと読めない知識の寄せ集めです。
HTMLの代わりに、 jQueryオブジェクトが反映される

html要素・jQueryの指定

① (div)ディブオブジェクト

html要素)

<div>
    <p>サンプルテキスト</p>
    <div>ディブ</div>
</div>

↓ jQueryオブジェクトに変換する

//divオブジェクトに変換する
var $divParent = $("<div>"); 

//pオブジェクトに変換する
var $p = $("<p>").html("サンプルテキスト");

//divオブジェクトに変換する
var $divChild = $("<div>").html("ディブ");

//親オブジェクトに子オブジェクトを追加
$divParent.append($p).append($divChild);

結果
スクリーンショット 2020-12-24 8.37.34.png

②(input)インプットオブジェクト

html要素)

<div>
    <p>サンプルテキスト1</p>
    <span>サンプルテキスト2</span>
    <input type="text" />
</div>

↓ jQueryオブジェクトに変換する

//divオブジェクトに変換する
var $div = $("<div>");  

//pオブジェクトに変換する
var $p = $("<p>").html("サンプルテキスト1");

//spanオブジェクトに変換する
var $span = $("<span>").html("サンプルテキスト2");

//inputオブジェクトに変換する
var $input= $("<input>");

//親オブジェクトに子オブジェクトを追加
$div.append($p).append($span).append($input);

結果
スクリーンショット 2020-12-24 8.42.00.png

③(link)リンクオブジェクト

html要素)

<div>
    <h1>タイトル</h1>
    <p>サンプルテキスト</p>
    <a href="#">リンク</a>
</div>

↓ jQueryオブジェクトに変換する

//divオブジェクトに変換する
var $div = $("<div>");

//h1オブジェクトに変換する
var $h1 = $("<h1>").html("タイトル");

//pオブジェクトに変換する
var $p = $("<p>").html("サンプルテキスト");

//inputオブジェクトに変換する
var $a = $("<a href='#'>").html("リンク");

//親オブジェクトに子オブジェクトを追加
$div.append($h1).append($p).append($a);

結果
スクリーンショット 2020-12-24 8.44.48.png

④( table)テーブルオブジェクト

html要素)

<div>
    <table>
        <tr>
            <td>
                 サンプルテキスト
            </td>
        <tr>
    </table>
</div>

↓ jQueryオブジェクトに変換する

//divオブジェクトに変換する
var $div = $("<div>");

//tableオブジェクトに変換する
var $table = $("<table>");

//trオブジェクトに変換する
var $tr = $("<tr>");

//tdオブジェクトに変換する
var $td = $("<td>").html("サンプルテキスト");

//親オブジェクトに子オブジェクトを追加
$div.append($table.append($tr.append($td)));

結果
スクリーンショット 2020-12-24 8.48.22.png

⑤ ulオブジェクト

html要素)

<div>
    <ul>
        <li>サンプルテキスト1</li>
        <li>サンプルテキスト2</li>
    </ul>
</div>

↓ jQueryオブジェクトに変換する

//divオブジェクトに変換する
var $div = $("<div>");

//ulオブジェクトに変換する
var $ul = $("<ul>");

//liオブジェクトに変換する
var $li1 = $("<li>").html("サンプルテキスト1");

//liオブジェクトに変換する
var $li2 = $("<li>").html("サンプルテキスト2");

//親オブジェクトに子オブジェクトを追加
$div.append($ul.append($li1).append($li2));

結果
スクリーンショット 2020-12-24 8.50.32.png

⑥(combobox)選択ボックスオブジェクト

html要素)

<div>
   <select class="select">
       <option>サンプルテキスト1</option>
       <option>サンプルテキスト2</option>
   </select>
</div>

↓ jQueryオブジェクトに変換する

//divオブジェクトに変換する
var $div = $("<div>");  

//selectオブジェクトに変換する
var $select = $("<select>").addClass("select");

//optionオブジェクトに変換する
var $option1 = $("<option>").html("サンプルテキスト1");

//optionオブジェクトに変換する
var $option2 = $("<option>").html("サンプルテキスト2");

//親オブジェクトに子オブジェクトを追加
$div.append($select.append($option1).append($option2));

結果
スクリーンショット 2020-12-24 8.52.58.png

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

aタグでPOST送信したい

背景

次のページにページングした際に、
ソートで並び替えたコンテンツがデフォルトのソート設定に戻ってしまう現象を解決したかった。
(例:1ページ目では更新順に並び替えたが、2ページ目ではデフォルトの新着順に並び変わっている)

解決方

javascriptを用いて$sortの値をPOST送信した。

  <form method="post" name="form2" action="./list.php?category=<?=$category_id?>&page=<?=$page+1?>">
    <input type="hidden" name="sort" value=<?=$sort?>>
    <a href="javascript:form2.submit()">次へ</a>
  </form>

以上。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsチュートリアルで作ったサンプルアプリの「ファイルを選択」ボタンをかっこよくしてみた

環境

  • Windows10 Home ver.2004
  • ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x64-mingw32]
  • Rails 6.1.0

はじめに

 Railsチュートリアルの13.4.1章では、サンプルアプリに画像付きマイクロポスト投稿機能を追加するのだが、デフォルトだと画像を選ぶ際にクリックする「ファイルを選択」ボタンがダサい他のボタンとの統一感のなさのせいで目立ってしまう。
スクリーンショット 2021-01-09 155648.png
 この状況をなんとかしたいと思い、色々試してみた。

結果

 デフォルトのボタンを非表示にした上で別のボタン「Choose an image」を用意し、そのボタン経由でデフォルトのボタンを押させることによって、機能を損なわずに見た目に統一感を出すことができた。
スクリーンショット 2021-01-09 174852.png
 マウスオーバー処理も含め、下の「Post」ボタンのデザインをできる限り忠実に再現した。
スクリーンショット 2021-01-09 174923.png
 もちろん、デフォルトの動作と同様に、画像を選択した場合はそのファイル名が表示される。
スクリーンショット 2021-01-09 174947.png

 変更・追加したコードは次の通り。なお、今回は勉強のためにBootstrap用のクラスはあえて使わずに実装してみた。

app\views\shared\_micropost_form.html.erb
・
・
・
  <button type="button" class="general_button" onclick="document.getElementById('micropost_image').click()">
    Choose an image
  </button>
  <div id="image_name">No image is chosen...</div>
・
・
・
<script type="text/javascript">
  $("#micropost_image").bind("change", function() {
    let chosen_image = this.files[0];
    if (chosen_image.size/1024/1024 > 5) {
      alert("Maximum file size is 5MB. Please choose a smaller file.");
      $("#micropost_image").val("");
      document.getElementById('image_name').innerHTML = "No image is chosen...";
    }
    else {
      document.getElementById('image_name').innerHTML = "Chosen image: " + chosen_image.name;
    }
  });
</script>
app\assets\stylesheets\custom.scss
.general_button{
    color: white;
    background-color: $blue-for-button; // #337ab7
    border: 0.5px solid $blue-for-button-border; // #2e6da4
    border-radius: 3.5px;
    padding-top: 6.5px; padding-bottom: 6.5px;
    padding-right: 10px; padding-left: 10px;
    &:hover {
        background-color: $dark-blue-for-button; // #285f90
        border-color: $dark-blue-for-button-border; // #204d74
    }
}

#image_name {
    margin-top: 1px;
    margin-left: 1px;
    margin-bottom: 9px;
}

#micropost_image{
    visibility: hidden;
}

結果までの流れ

1.

 適当なキーワードで検索したらいくつか参考にできそうな記事12がヒットしたが、それらをそのまま自分の状況に適用するのは難しそうなので、具体的なコードの書き方は自分で考えてみることにした。

2.

 あるオブジェクトがクリックされたことをトリガーとして別のオブジェクトのイベントを作動させるという処理を実現するコードの書き方を調べるため、「javascript html ボタン 押させる」などのキーワードで検索したら、「JavaScriptでボタンを押すアクションを起こす | forWEB屋」がヒットした。
 このサイトを基に、デフォルトの「ファイルを選択」ボタンのクリックイベントを作動させるための別のボタン「Choose an image」を作った(_micropost_form.html.erb内参照)。

3.

 続いて、ユーザーが選択した画像ファイル名をどうやって表示しようかと考えた結果、Railsチュートリアル内のリスト13.67に書かれていた、選択された画像のファイルサイズが5MBより大きかった場合にアラートを出すJavaScriptコードを改造することにした(_micropost_form.html.erb内参照)。
 途中でf.file_fieldに独自のidを追加したらアラートを出すJavaScriptが動作しなくなるトラブルが起こったが、JavaScriptコードを読んで既にidとしてmicropost_imageが設定されていることに気付き、独自のidを削除したら再び動作するようになった。

4.

 これまでで動作に関する部分の実装は概ね終わっていたので、「CSSリファレンス - とほほのWWW入門」を参考に、時には画像編集ソフトのスポイト機能を使ってスクリーンショットから色の情報を取ったりしつつcustom.scssを編集した。

以上


  1. [Rails][file_field]画像のアップロードのボタンデザインを変更する - Qiita(https://qiita.com/Yukina_28/items/4a8332354f6cb7c7a6f6

  2. railsのfile_fieldで画像クリックによりアップロード - Qiita(https://qiita.com/zukakosan/items/41ed95fea2323cf458a9

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby On Rails / HTML】ウェブページ表示時、カーソル(キャレット)を適当な場所へ合わせ表示する方法

備忘録です。

カーソルとキャレットとは

スクリーンショット 2021-01-10 15.31.03.png

キャレット≒カーソル
マウスカーソルなどと区別したい場合にキャレットという言葉が用いられます。

本題

カーソルを適当な場所へフォーカスするには、autofocusを使います。
Rubyでは、次のような書き方をします

autofocus: true

それでは、Deviseの新規登録画面に"Nickname"という項目を設けた場合で見ていきます。
まずは"Nickname"にautofocusを使わない場合はどのように表示されるでしょうか。

①"Nickname"にautofocusなし

new.html.erb
<h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= render "devise/shared/error_messages", resource: resource %>

  <div class="field">
    <%= f.label :nickname, "Nickname" %><br />
    <%= f.text_field :nickname %>
  </div>

  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
  </div>

(後略)

スクリーンショット 2021-01-10 15.39.34.png

上記の場合、新規登録のウェブページを開いてみると、Nicknameではなく、Emailにカーソルがフォーカスされています。

次に、<%= f.text_field :nickname %>にautofocusを付与して、Nicknameにカーソルの焦点を当てた状態で見ていきます。

②"Nickname"にautofocusあり

new.html.erb
<h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= render "devise/shared/error_messages", resource: resource %>

  <div class="field">
    <%= f.label :nickname, "Nickname" %><br />
    <%= f.text_field :nickname, autofocus: true %>
  </div>

  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
  </div>

(後略)

スクリーンショット 2021-01-10 15.47.50.png

このようにautofocusを"Nickname"に付与してあげることで、自動的に一番最初にカーソルが当てられる場所がNicknameとなりました。

参考記事

https://www.sophia-it.com/content/%E3%82%AD%E3%83%A3%E3%83%AC%E3%83%83%E3%83%88
http://www.htmq.com/html5/input_autofocus.shtml

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScriptで画像を表示する方法

JavaScript初心者のメモとして「JavaScriptで画像を表示する方法」を残します。
今まではホームページの作成にHTMLのみで画像を表示していましたが、せっかくJavaScriptを学習しているのでJavaScriptでも表示したいと思ってやってみました。

画像を表示する方法

1.HTMLで表示する方法

1枚だけ画像を画面に表示するためのHTMLです。(コピーすれば何枚でも表示できます)
imgタグにより画像を表示しています。
まずはhtmlの全体です。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>HTMLで画像を表示する方法</title>
</head>
<body>
  <img src='images/image000.jpg'>
</body>
</html

次にimgタグだけみてみます。

  <img src='images/image000.jpg'>

imgタグのsrcの部分は画像がhtmlに対してどのこフォルダーに入っているかを表しています。
この場合だとimagesフォルダーの下にimage000.jpgという画像ファイルが入っています。
imagesフォルダーはhtmlと同じ階層(フォルダー内)にあります。
これでhtmlのみで画面上に画像を表示できます。

2.JavaScriptで表示する方法

ではこれからJavaScriptで画像を表示してみましょう

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>HTMLで画像を表示する方法</title>
</head>
<body>
  <img src='images/image000.jpg'>
  <script src="main.js"></script>
</body>
</html
main.js
'use strict';
{
document.write('<img id="carousel__main" src="images/image000.jpg">');
}

上記がJavaScriptで画像を表示するためのコードです。

以下説明します。
HTMLにJavaScriptを読み込ませるためにスクリプトタグを追加しています。

<script src="main.js"></script>

画面に出力する時は以下のコードを使用します。

document.write
//画面に出力するコマンド

を使用して画面に出力することができます。
文字を表示する時は以下のように書きます。

main.js
'use strict';
{
document.write('JavaScriptで画像を表示する');
}

同じ容量で画像を出力してみます。

main.js
'use strict';
{
document.write('<img src="images/image000.jpg">');
}

以上の方法でJavaScriptで画像を画面に表示することができます。
ちなみに以下のように「'」ではなく「"」で書くと文字の区切る場所が異なり(青の文字部分)
エラーとなります。

main.js
'use strict';
{
document.write("<img src="images/image000.jpg">");
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Progate<HTML&CSS道場コース初級編>コードと一言メモ

初めて記事を投稿します。

といっても現段階ではプロゲートでHTML&CSSの学習・道場コース初級編を1周終えただけですが。

道場コースやってみたら、なかなか正解にたどり着かなかったので、復習もかねて自分が書いたコードをここに載せていこうと思います。

一応正解が出たコードなので、道場コースで躓いている方の手助けになればと思います。

①ヘッダー作成

~HTML①~

qiita.html①
  <body>
    <!-- ここからHTMLを書き始めてください -->
    ★<div class="header">
      〇<div class="header-logo">
      Progate  
      </div>〇
      ◆<div class="header-list">
        △<ul>
          <li>プログラミングとは</li>
          <li>学べるレッスン</li>
          <li>お問い合わせ</li>
        </ul>△
      </div>◆

    </div>★
  </body>

<解説>
①全体をheaderクラスで囲む(★)
②headerクラスの中にheader-logoクラス(〇)を設定。
③header-listクラス(◆)を作成。その中に親要素ulで囲った子要素liを3つ設定(△)。

ここは難なく行けると思います。フッターも同じ要領で作成するので覚えておきましょう。

~CSS~

qiita.css①
/* ここからCSSを記述してください */
.header{
  background-color:#26d0c9;
  color:#fff;
  height:90px;
}
.header-logo{
  font-size:36px;
  float:left;
  padding:20px 40px;
}

.header-list li{
  float:left;
 padding:33px 20px;  
}

<解説>
htmlでクラスで囲ったものには全て”.”を冒頭につけて何をどうしたいかを仕様書を見ながら書いていきましょう。ここも難なくクリアできると思います。

②トップ部分の作成

いよいよメインの作成にとりかかります。3段階に分けて作成していきますが、最初にメインの大枠をdiv化してmainというクラスを設定し(★)、その中に色々な要素を足していく感じです。

~HTML~

qiita.html②
 ★<div class="main">
    〇<div class="copy-container">
      <h1>HELLO WORLD<span>.</span></h1>
      <h2>プログラミングの世界へようこそ</h2>
    </div>〇  

    </div>★

<解説>
mainの中にcopy-containerというクラスを作成し(〇)、その中に大きい方から順に、h1やh2というタグを使って文字を書いていきます。仕様書では、"HELLO WORLD.”のドット部分が別の色になっているので、spanというタグでドットを囲むことを忘れずに。

~CSS~

qitta.css②
.main{
  padding:100px 80px;
}
.copy-container h1{
  font-size:140px;
}

.copy-container span{
  color:#ff4a4a;
}
.copy-container h2{
  font-size:60px;
}

<解説>
この段階では、copy-container部分だけの仕様書のみですが、コンテンツ部分やお問い合わせフォームを作成すしていくにつれて、mainのpaddingは上下100px、左右80pxで統一されてると分かります。私も最初はcopy-containerでpaddingを設定していましたが、後の過程でcopy-containerからmainに変更しました。ここでは変更後のものを載せておきますが、この段階ではcopy-containerで設定しても正解にはなります。

copy-container h1とh2は分けてCSSを書くこと、spanを書く場合には.copy-container spanとセットで書くことを忘れずに。

③コンテンツ部分の作成

HTML

qiita.html③
★<div class="contents">
      ◆<h3 class="section-title">学べるレッスン</h3>◆

      〇<div class="contents-item">
        <img src="https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/html/study/html.svg">
        <p>HTML & CSS</p>
      </div>〇

      〇<div class="contents-item">
        <img src="https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/html/study/php.svg">
        <p>PHP</p>
      </div>〇

      〇<div class="contents-item">
        <img src="https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/html/study/ruby.svg">
        <p>Ruby</p>
      </div>〇

      〇<div class="contents-item">
        <img src="https://s3-ap-northeast-1.amazonaws.com/progate/shared/images/lesson/html/study/swift.svg">
        <p>Swift</p>
      </div>〇

      </div>★

<解説>
⑴contentsでコンテンツ部分の大枠を囲む()。
⑵h3を装飾するので、h3にクラスタグをつける。ここではsebtion-titleというタイトルをつけています(◆)。
⑶画像挿入にcontents-itemというクラスを作成(〇)、その中にimgタグとpタグを入れる。これを4つ作る。
⑷⑶で作ったimgタグに画像のURL(ヒントをクリックするとそれぞれの画像のurlが出てきます)を入れ、pタグに文字を入力。4回繰り返す。

~CSS~

qiita.css③
.contents{
  height:500px;
  margin-top:100px;
}
.section-title{
  font-size:28px;
  border-bottom:2px solid #dee7ec;
  padding-bottom:15px;
  margin:50px;
}

.contents-item{
  float:left;
  margin-right:40px;
}

.contents-item p{
  margin-top:30px;
  font-size:24px;
}

<解説>
marginとpaddingの概念がややこしくて苦手ですが、、、。
margin…ボーダー(枠線)外側の余白の大きさ
padding…ボーダー(枠線)内側の余白の大きさ
ざっとこういう理解をしてます。
トップを作っていた時に、mainのpaddingは定義しましたが、copy-containerとcontentsの余白の大きさを定義していませんので、ここでmargin-topを使って定義します。contents全体を枠線で囲ってみると、paddingではなくてmarginを使うということが分かります。
h3の装飾はhtmlで定義した.sebtion-titleを使ってやっていきます。htmlで.section-titleを定義せず、「.contents h3」としてCSSで装飾をしても良いですが、お問い合わせフォームのh3でも同じことをCSSでやらないといけないので、労力を省くためにsection-titleを使います(、と勝手に解釈してます)

④お問い合わせフォーム作成

~HTML~

qiita.html④
★<div class="contact-form">
        ◆<h3 class="section-title">お問い合わせ</h3>◆
        <p>メールアドレス(必須)</p>
        □<input>□
        <p>お問い合わせ内容(必須)</p>
        ■<textarea></textarea>■
        <p>※必須項目は必ずご入力ください</p>
        ☆<input type="submit" value="送信" class="submit-button">☆
      </div>★

<解説>
⑴contact-formというクラスで全体を囲む(★)
⑵h3の装飾はcontentsのh3と同じなので、h3にsection-titleというクラスをつける(◆)。
⑶inputは1行入力を受け取るための要素(□)。textareaは複数行入力を受け取るための要素(■)。それぞれを作れたらpタグで文章を補充する。inputは終了タグがいらないことに注意。
⑷送信ボタンもinputタグで作成(☆)。
=inputにはtype属性を指定することが出来る。input type="submit"とすることで、「送信ボタン」と定義できる。
=value属性を付けることでそのボタンの表示名を指定できる(今回は「送信」と指定)。
=CSSで装飾が必要なのでClass属性を追加、今回は”submit-button”という名前を付ける。

CSS

qiita.CSS④
.contact-form{
  margin-top:100px;
}

input,textarea{
  border:1px solid #dee7ec;
  width:400px;
  padding:20px;
  margin-top:10px;
  margin-bottom:30px;
  font-size:18px;

}

.submit-button{
  background-color:#dee7ec;
  color:#889ebc;
}

<解説>
contact-formとcontentsの余白はmargin‐topで指定。ここ指定しないと最後のフッター作成で正解にならなかった、、、。
input,textareaなど、コンマで区切ることで同じCSSを適用できるので覚えておくと便利。
あと、htmlでsubnit-bottonなどクラスを設定しないとボタンの色が変わらない。

⑤フッター作成

~html~

qiita.html⑤
★<div class="footer">
      ◇<div class="footer-logo">
        Progate
      </div>◇
      ◆<div class="footer-list">
        <ul>
          <li>会社概要</li>
          <li>採用</li>
          <li>お問い合わせ</li>
        </ul>
      </div>◆
    </div>★

ヘッダーと同じ要領で作れると思います。

CSS

qiita.css⑤
.footer{
  background-color:#2f5167;
  color:#fff;
  height:120px;
  padding:40px;
}
.footer-logo{
  font-size:32px;
  float:left;
}
.footer-list{
  float:right;
}
.footer-list li{
  margin-bottom:20px;
}

<解説>
footerは枠線の内側に40pxの余白があるので、paddingを設定。footer-logoは左側に、footer-listは右側に置きたいのでfloatを指定する。

⑥道場コース初級を終えてみての感想

・1つ1つの要素をこなすだけでなく、完成図全体を見ないといけない。
・paddingとmarginで迷ったら枠線を引いてみる。枠線の内側がpadding、外側がmargin。
・正解にたどり着けなかったらどこかしら間違いがあるので、はじめから見直してみる。

以上、備忘録として投稿しておきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTML/CSSに関するメモ

はじめに

HTML/CSSについて、調べる度毎回内容を忘れてしまうので内容を備忘録としてまとめておく。

HTMLタグについて

色々なタグがあって覚えきれないが、分からなくなったら以下のページを参照する。
HTMLクリックリファレンス

class/idについて

参考記事:

classはHTMLタグに対して付与できる「グループ分けのための名前」みたいなもの。
CSSでスタイルを指定する時に、class名を指定して適用させる。

idもHTMLタグに付与できる名前であるが、classとidの違いとしては

  • id:同一ページ内で1回しか使えない
  • class:同一ページ内で何回でも使える

である。

また、CSS適用の優先順位は

  • id > class >HTMLタグ

となる。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

jqueryプラグインの導入からオプションの設定方法まで。

自分への備忘録としてbxsliderとlightboxの導入からオプション設定までをまとめてみました。
おまけでドロワーメニューも書いてます。是非参考に。

準備

当たり前ですが、以下の一次ソースは必須です。
lightbox公式HP
bxslider公式HP

今回はCDN方式で使うので以下も使用します。
cdnjs

画像を使うので以下に貼っておきます。ご自由にお使いください。
modal1.jpg
modal2.jpg
modal3.jpg
slider1.jpg
slider2.jpg
slider3.jpg

ベースコードとフォルダ階層

【フォルダ階層】
フォルダ階層.png

【ファイル構成】
ファイル構成.png

【ベースコード】

html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Template</title>
  <!-- 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">
</head>
<body>

  <!-- JQuery CDN -->
  <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
  <!-- JS -->
  <script src="./js/main.js"></script> 
</body>
</html>
css
@charset "UTF-8";
/* reset */
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Noto Sans JP', sans-serif;
  line-height: 1;
}
ul{
  list-style: none;
}
a{
  text-decoration: none;
}
img{
  max-width: 100%;
  height: auto;
  border: none;
  vertical-align: bottom;
}
/* common
----------------------------------- */
.container{
  max-width: 1230px;
  margin: 0 auto;
  padding: 0 10px;
}
/* media query
----------------------------------- */
@media screen and (max-width: 767px){
}
@media screen and (max-width: 629px){
}
js
$(function(){
  console.log('OK');
});

bxSlider

スクリーンショット 2021-01-10 0.21.08.png

スクリーンショット 2021-01-10 0.25.27.png

これでコピーできたのでHTMLのscriptタグsrc内に貼り付け。
※JQuery CDNの下かつ、オリジナルのJSの上に記載する事。

同様にCSSも貼り付けていきます。

スクリーンショット 2021-01-10 0.34.09.png

この時点でのコードは以下です。
※なんのCDNなのか、コメント付けておくとわかりやすいですよ。

html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Template</title>
  <!-- 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">
  <!-- bxslider -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.15/jquery.bxslider.min.css">
  <!-- CSS -->
  <link rel="stylesheet" href="./css/style.css">
</head>
<body>

  <!-- JQuery CDN -->
  <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
  <!-- bxslider -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.15/jquery.bxslider.min.js"></script>
  <!-- JS -->
  <script src="./js/main.js"></script> 
</body>
</html>

早速スライダー実装します。
公式HPに飛びましょう。トップページから「Examples」に飛ぶと例が書いてあるので参考にしましょう。
コードは以下になります。

html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Template</title>
  <!-- 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">
  <!-- bxslider -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.15/jquery.bxslider.min.css">
  <!-- CSS -->
  <link rel="stylesheet" href="./css/style.css">
</head>
<body>

  <!-- bxslider -->
  <ul class="bxslider">
    <li><img src="./img/slider1.jpg"></li>
    <li><img src="./img/slider2.jpg"></li>
    <li><img src="./img/slider3.jpg"></li>
  </ul>

  <!-- JQuery CDN -->
  <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
  <!-- bxslider -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.15/jquery.bxslider.min.js"></script>
  <!-- JS -->
  <script src="./js/main.js"></script> 
</body>
</html>
js
$(function(){
  // bxslider
  $(document).ready(function(){
    $('.bxslider').bxSlider();
  });
});

画面は以下です。

スクリーンショット 2021-01-10 0.49.32.png

この時点では、自動実行されないただのスライダーなのでオプションを書いていきます。
その他使いそうなオプションも追加してます。

js
$(function(){
  // bxslider
  $(document).ready(function(){
    $('.bxslider').bxSlider({
      auto: true, // オートスライド
      mode: 'fade', // horizontal / vertical / fade 
      speed: 3000, // 遷移スピード
      pause: 10000, // スライド間隔
    });
  });
});

今回の場合以下のようにゆーっくり自動実行されればOKです。

8f55dd89fbb821efd004e6c7533f95ff.gif

次にCSSのオプションも書いていきます。
実はよーく見ると周りに5pxの余白とborder、shadowがかかってます。
実際にデベロッパーで見るとわかります。
なのでこれを解除するコードを書いていきます。

css
@charset "UTF-8";
/* reset */
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Noto Sans JP', sans-serif;
  line-height: 1;
}
ul{
  list-style: none;
}
a{
  text-decoration: none;
}
img{
  max-width: 100%;
  height: auto;
  border: none;
  vertical-align: bottom;
}
/* common
----------------------------------- */
.container{
  max-width: 1230px;
  margin: 0 auto;
  padding: 0 10px;
}
/* bxslider
------------------------------------ */
/* スライダーの枠線を消す */
.bx-wrapper {
  background-color: transparent;
  margin: 0px auto 50px;
  border: none;
  box-shadow: none;
}
.bx-wrapper img {
  display: block;
  margin: 0px auto;
}
/* media query
----------------------------------- */
@media screen and (max-width: 767px){
}
@media screen and (max-width: 629px){
}

これで画面いっぱいいっぱいになったはずです。

スクリーンショット 2021-01-10 1.03.22.png

こんな感じで、元々かかってるCSSを後から上書きできます。

lightBox

bxSlider同様、cdnjsからCDNをコピペしましょう。検索キーワードはlightBoxでOKです。
最終的なコードは以下になります。

html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Template</title>
  <!-- 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">
  <!-- bxslider -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.15/jquery.bxslider.min.css">
  <!-- lightBox -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.3/css/lightbox.min.css">
  <!-- CSS -->
  <link rel="stylesheet" href="./css/style.css">
</head>
<body>

  <!-- bxslider -->
  <ul class="bxslider">
    <li><img src="./img/slider1.jpg"></li>
    <li><img src="./img/slider2.jpg"></li>
    <li><img src="./img/slider3.jpg"></li>
  </ul>

  <!-- JQuery CDN -->
  <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
  <!-- bxslider -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.15/jquery.bxslider.min.js"></script>
  <!-- lightBox -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.3/js/lightbox.min.js"></script>
  <!-- JS -->
  <script src="./js/main.js"></script> 
</body>
</html>

こちらも公式を参考にしましょう。
「INITIALIZE WITH HTML」の部分にサンプルがあるので自分用のコードに変換して使います。

html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Template</title>
  <!-- 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">
  <!-- bxslider -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.15/jquery.bxslider.min.css">
  <!-- lightBox -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.3/css/lightbox.min.css">
  <!-- CSS -->
  <link rel="stylesheet" href="./css/style.css">
</head>
<body>

  <!-- bxslider -->
  <ul class="bxslider">
    <li><img src="./img/slider1.jpg"></li>
    <li><img src="./img/slider2.jpg"></li>
    <li><img src="./img/slider3.jpg"></li>
  </ul>

  <!-- main -->
  <main>
    <div class="container">
      <!-- thumbnail -->
      <div class="box"><a href="img/modal1.jpg" data-lightbox="img1" data-title="サムネイル1"><img src="./img/modal1.jpg"></a></div>
      <div class="box"><a href="img/modal2.jpg" data-lightbox="img1" data-title="サムネイル2"><img src="./img/modal2.jpg"></a></div>
      <div class="box"><a href="img/modal3.jpg" data-lightbox="img1" data-title="サムネイル3"><img src="./img/modal3.jpg"></a></div>
    </div>
  </main><!-- /main -->

  <!-- JQuery CDN -->
  <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
  <!-- bxslider -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.15/jquery.bxslider.min.js"></script>
  <!-- lightBox -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.3/js/lightbox.min.js"></script>
  <!-- JS -->
  <script src="./js/main.js"></script> 
</body>
</html>

補足としてdata-lightboxでグループ分けできます。=以降に同じ名前を設定しておくと、モーダル上でスライドが可能になります。
今回は全部グループ化したので、実際に画面でみていきます。

acb323f9e118ad3afa851be9994a296f.gif

CSSでレイアウト整える前に、JSのオプションを書いていきます。
現状モーダル出現時にスクロールが可能になっているのですが、基本的にはモーダルウインドウはスクロールしないのが多いのでその設定をします。
ついでにモーダルの出現時間などもちょっと変えていきます。

js
$(function(){
  // bxslider
  $(document).ready(function(){
    $('.bxslider').bxSlider({
      auto: true, // オートスライド
      mode: 'fade', // horizontal / vertical / fade 
      speed: 3000, // 遷移スピード
      pause: 10000, // スライド間隔
    });
  });
  // lightBox
  lightbox.option({
    disableScrolling: true, // モーダルアクティブ時はスクロール禁止
    fadeDuration: 100, // 背景フェードの時間、デフォは600
    imageFadeDuration: 3000, // 画像フェードの時間、デフォは600
  })
});

これでスクロールできなくなって、画面の出現時間も気持ち遅くなりました。
今度はCSSのオプションを書いていきます。
現状真っ黒な背景になっているので、色を変えます。

css
@charset "UTF-8";
/* reset */
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Noto Sans JP', sans-serif;
  line-height: 1;
}
ul{
  list-style: none;
}
a{
  text-decoration: none;
}
img{
  max-width: 100%;
  height: auto;
  border: none;
  vertical-align: bottom;
}
/* common
----------------------------------- */
.container{
  max-width: 1230px;
  margin: 0 auto;
  padding: 0 10px;
}
/* bxslider
------------------------------------ */
/* スライダーの枠線を消す */
.bx-wrapper {
  background-color: transparent;
  margin: 0px auto 50px;
  border: none;
  box-shadow: none;
}
.bx-wrapper img {
  display: block;
  margin: 0px auto;
}
/* lightBox
------------------------------------ */
.lightboxOverlay{
  background: linear-gradient(45deg, red, blue, green, yellow, orange);
  opacity: 0.5;
}
/* media query
----------------------------------- */
@media screen and (max-width: 767px){
}
@media screen and (max-width: 629px){
}

53f8953f7866683610f4ea103319289f.gif

このように背景色が変わればOKです。

最後に

今回はJQのプラグイン2つの導入からオプションまでを紹介しました。
最後におまけとして、ドロワーメニューを含めた完成形のコードを載せときますので是非参考にしてください。

html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Template</title>
  <!-- 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">
  <!-- lightBox -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.3/css/lightbox.min.css">
  <!-- bxslider -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.15/jquery.bxslider.min.css">
  <!-- CSS -->
  <link rel="stylesheet" href="./css/style.css">
</head>
<body>
  <!-- header -->
  <header>
    <div class="container">
      <h1>HEADER</h1>
      <div class="spbtn"><p>MENU</p></div>
    </div>
  </header><!-- /header -->
  <!-- navigation -->
  <nav>
    <ul class="container">
      <li><a href="#">menu1</a></li>
      <li><a href="#">menu2</a></li>
      <li><a href="#">menu3</a></li>
      <li><a href="#">menu4</a></li>
      <li><a href="#">menu5</a></li>
    </ul>
  </nav>
  <!-- slider -->
  <div class="container">
    <ul class="bxslider">
      <li><img src="./img/slider1.jpg"></li>
      <li><img src="./img/slider2.jpg"></li>
      <li><img src="./img/slider3.jpg"></li>
    </ul>
  </div><!-- slider -->
  <!-- main -->
  <main>
    <div class="container">
      <!-- thumbnail -->
      <div class="box"><a href="img/modal1.jpg" data-lightbox="img1" data-title="サムネイル1"><img src="./img/modal1.jpg"></a></div>
      <div class="box"><a href="img/modal2.jpg" data-lightbox="img1" data-title="サムネイル2"><img src="./img/modal2.jpg"></a></div>
      <div class="box"><a href="img/modal3.jpg" data-lightbox="img1" data-title="サムネイル3"><img src="./img/modal3.jpg"></a></div>
    </div>
  </main><!-- /main -->
  <!-- footer -->
  <footer>
    <div class="container">
      <p>FOTTER</p>
    </div>
  </footer><!-- /footer -->
  <!-- JQuery CDN -->
  <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
  <!-- lightBox -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.3/js/lightbox.min.js"></script>
  <!-- bxslider -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.15/jquery.bxslider.min.js"></script>
  <!-- JS -->
  <script src="./js/main.js"></script> 
</body>
</html>
css

@charset "UTF-8";
/* reset */
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Noto Sans JP', sans-serif;
  line-height: 1;
}
ul{
  list-style: none;
}
a{
  text-decoration: none;
}
img{
  max-width: 100%;
  height: auto;
  border: none;
  vertical-align: bottom;
}
/* common
----------------------------------- */
.container{
  max-width: 1230px;
  margin: 0 auto;
}
/* header
----------------------------------- */
header, footer{
  padding: 10px;
  background: #ff8383;
  color: #fff;
  text-align: center;
}
.spbtn{
  display: none;
  width: 50px;
  height: 50px;
  border: 1px solid #fff;
  border-radius: 3px;
  transition: .5s;
  position: absolute;
  right: 10px;
  top: 5px;
}
.spbtn p{
  font-size: 16px;
  text-align: center;
  line-height: 48px;
}
.spbtn:hover{
  cursor: pointer;
  background: rgba(255, 255, 255, 0.8);
  color: #ff8383;
}
.spbtn.open{
  background: rgba(255, 255, 255, 0.8);
  color: #ff8383;
}
@media screen and (max-width: 767px){
  header{
    text-align: left;
  }
  .spbtn{
    display: block;
  }
}
/* navigation
----------------------------------- */
nav{
  background: #ffc14d;
}
nav ul{
  display: flex;
  justify-content: space-between;
}
nav li{
  width: 100%;
  border-right: 1px solid #fff;
}
nav li:first-child{
  border-left: 1px solid #fff;
}
nav a{
  display: block;
  line-height: 50px;
  text-align: center;
  color: #fff;
}
@media screen and (max-width: 767px){
  nav{
    position: relative;
    /* bxSliderが9999のため */
    z-index: 10000;
  }
  nav ul{
    display: block;
    position: fixed;
    left: 100%;
    z-index: 10000;
    width: 100%;
    transition: .5s;
  }
  nav ul.open{
    left: 0;
  }
  nav ul.container{
    padding: 0;
  }
  nav li{
    border: none;
    border-bottom: 1px solid #fff;
    background: #ffc14d;
  }
}
/* main
----------------------------------- */
main{
  padding: 50px 10px;
  background: #ffffb8;
}
main .container{
  display: flex;
}
/* thumbnail */
div.box{
  margin-right: 10px;
}
@media screen and (min-width: 768px){
  div.box:last-child{
    margin-right: 0;
  }
}
div.box img{
  box-shadow: 5px 5px 5px #999;
}
@media screen and (min-width: 630px) and (max-width: 767px){
  main .container{
    flex-wrap: wrap;
  }
  div.box{
    width: calc(50% - 5px);
    margin-bottom: 10px;
  }
  div.box:nth-child(2n){
    margin-right: 0;
  }
}
@media screen and (max-width: 629px){
  main .container{
    display: block;
  }
  div.box{
    width: 300px;
    margin: 0 auto 10px;
  }
}
/* bxslider
------------------------------------ */
/* スライダーの枠線を消す */
.bx-wrapper {
  background-color: transparent;
  margin: 0px auto 50px;
  border: none;
  box-shadow: none;
}
.bx-wrapper img {
  display: block;
  margin: 0px auto;
}
/* lightBox
------------------------------------ */
.lightboxOverlay{
  background: linear-gradient(45deg,red, blue, green, yellow, orange);
  opacity: 0.5;
}
js
$(function(){
  // bxslider
  $(document).ready(function(){
    $('.bxslider').bxSlider({
      auto: true, // オートスライド
      mode: 'fade', // horizontal / vertical / fade 
      speed: 3000, // 遷移スピード
      pause: 10000, // スライド感覚
    });
  });
  // lightBox
  lightbox.option({
    disableScrolling: true, // モーダルアクティブ時はスクロール禁止
    fadeDuration: 100, // 背景フェードの時間、デフォは600
    imageFadeDuration: 3000, // 画像フェードの時間、デフォは600
  })
  // spbtn click event
  $('.spbtn').on('touchstart', function(){
    let opCls = 'open';
    $(this).toggleClass(opCls);
    if($(this).hasClass(opCls)){
      $(this).find('p').text('OPEN');
    } else {
      $(this).find('p').text('MENU');
    }
    $('nav ul.container').toggleClass(opCls);
  });
});
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【HTML設計思想 / クラス命名】最高に楽なわたし的BEM

はじめに

爆速コーディングの記事で HTML の設計を楽にするため・HTML をブロック管理する感覚を掴むためにに BEM を取り入れることをおすすめしました。
Block, Element, Modifier という設計概念を持つ BEM の中でも、さらに様々な BEM 命名規則が存在するようですが(これらを今回は「BEM 系」とします。)、私が上記記事で BEM と指したのは BEM の中でもMindBEMdingというもので、現在「BEM 系」の中で最もポピュラーなものです。「BEM」と呼んだら多くはMindBEMdingを指します。

しかし私が実際に HTML/CSS 設計に取り入れているのはMindBEMdingではありません。(オススメしておいて・・・)

一貫性をもって管理しやすいMindBEMdingにもデメリットと思われる点があり、そこを解消したのが現在私が取り入れている命名規則です。
Block, Element, Modifier の設計思想には変わりがありません。命名規則だけが変わります。

BEM設計はブロック(モジュール)管理ができる考え方として良い設計だと思っていたため、シンプルで管理しやすい命名規則を求め、BEMをもとにした命名規則は色々試しました。
様々なプロジェクトで試してPDCAを回して、やっと現在の命名規則に落ち着きました。
自信を持っておすすめできる命名規則ですので、命名に悩む方にはぜひお試し頂きたいです!

BEM の設計概念をある程度理解した上であれば取り入れやすい命名規則なので、ぜひ本記事を参考にして頂けたら幸いです。

広まれ〜〜!

まとめへショートカット

わたし的BEM命名規則まとめ

ちなみに、私の命名規則ってこれと同じじゃん!と思える既存の命名規則見つけて喜んでいたのですが、本記事を書くにあたって、よく説明を確認したらちょっと違いました。
一緒だと思っていたので、本記事はもともとそちらの紹介にするつもりだったのですが。。
仕方がないので、「わたし的BEM」に改めました。

ここまで出来たら良いよね・・・でもめっちゃクラス名長くなるなあっていう Chainable BEM Modifiers。
Chainable BEM

ああ、私のクラス命名もChainable BEMと呼びたかった。

MindBEMding の復習

BEM の基礎を復習したい方へ
前回 BEM の概要をご説明しました!

MindBEMdingは長いクラス名になってしまうため、コードが読みづらくなるのがデメリットだと言われています。

わたし的 BEM の命名規則

Block, Element はMindBEMdingと異なる点はありません。全てが同じです!
Modifire だけ異なります。

MindBEMdingとコードを比べながらご説明出来ればと思います。

たとえばこのようなボタンのパターンがあった場合
example_button.png

BEM の設計概念上では、ボタンという要素を Block とし、そのボタンのバリエーション・パターンとして存在する「青背景」を Modifier とします。

この BEM 設計の上、MindBEMdingだと以下の様にクラス命名・スタイル管理ができます。

MindBEMding

index.html
<button class="button">標準ボタン</button>
<button class="button button--blue">青ボタン</button>
style.scss
.button {
  width: 100px;
  padding-top: 8px;
  padding-bottom: 8px;
  border: none;
  background-color: grey;
  color: #fff;
}

.button--blue {
  background-color: blue;
}

クラス名に着目して、「button」も「blue」も文字数が少ないため今回は気になりませんが
これが「main-visual」と「registerer」だったら・・・
(例えで作りましたが、会員登録者にのみ見えるメインビジュアルを実装したい場合にありそうなクラス名です。)

<div class="main-visual main-visual--registerer">

となりますし、ここに Element まであると

<div class="main-visual__text main-visual__text--registerer">

こんなにタグが長くなっちゃうんです!
こんなのがたくさんあったら、コードが冗長に見えますよね。そのため嫌煙されることがあるのです。

わたし的 BEM はこの冗長化を解決しています。
先程のボタンは以下の様にクラス命名・スタイル管理ができます。

わたし的 BEM

index.html
<button class="button">標準ボタン</button>
<button class="button --blue">青ボタン</button>
style.scss
.button {
  width: 100px;
  padding-top: 8px;
  padding-bottom: 8px;
  border: none;
  background-color: grey;
  color: #fff;

  &.--blue {
    background-color: blue;
  }
}

// アンチパターン: 一見Modifierは汎用的に使えそうなクラスに見えるが、`.button--blue`の設計を保つべき。
// よって汎用的なクラスにはせず、あえて`.button`のサブクラスとして置かれた場合のみにスタイルが聞くようにセレクタを指定する。
// .--blue {
//  background-color: blue;
// }

Modifier が.block--modifireではなく、.--modifireのみになってすっきりしました。
Element がある場合も.block__element--modifier.modifierになります。

またコードにはアンチパターンも記載しています。
MindBEMdingから命名規則が変わったことで汎用的な.--blueクラスとしてもスタイル指定が出来ますが、あえて「ボタンの青背景パターン」としてしか使えないようにセレクタを限定することが BEM 設計を保つために重要なポイントです。

これで先程は冗長だったコードも短く出来ます!

index.html
<div class="main-visual main-visual--registerer"></div>
<p class="main-visual__text main-visual__text--registerer"></p>

=>

<div class="main-visual --registerer"></div>
<p class="main-visual__text --registerer"></p>

文字数が減ったことはもちろんですが、ぱっとタグを見たときも見やすくなったと思います。
MindBEMdingから比べても Modifier のみの違いなので、地味な変化ではありますがこれがファイル全体への変更となると大きく変わってきます。

まとめ

最後にわたし的BEM命名規則のまとめです。

  • Blockクラスは.blockMindBEMdingと同じ)
  • Elementクラスは.block__elementであり、親Blockの中でのみ存在できる。(MindBEMdingと同じ)
  • Modifireクラスは.--modifier
  • セレクタとしては、.--modifierに直接スタイルを付けることはしない。汎用的なクラスとはせず、Blockクラスまたは、Elementクラスと共に用いられたときのみにスタイルが効くように指定する。
  • Block, Element, Modifier それぞれ複数単語から成るときにはケバブケース(全て小文字&単語をハイフンで繋ぐ)を用いる。(MindBEMdingと同じ)

ちなみに、一時期.--modifier.-modifierにしていたこともありました。
ハイフンを1つにしていたんですが、そうするとファイル内でModifier名を検索する際に-modifierと検索して、BlockやElementクラス内でハイフンで繋いでいた同単語にも引っかかってしまいます。
このようにModifire以外も検索に引っかかる可能性が出てしまうため、現在は.--modifierと、ハイフンを2連続にしています。
検索性も大事ということ!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【HTML設計思想 / クラス命名】最高に管理が楽なわたし的BEM

はじめに

爆速コーディングの記事で HTML の設計を楽にするため・HTML をブロック管理する感覚を掴むためにに BEM を取り入れることをおすすめしました。
Block, Element, Modifier という設計概念を持つ BEM の中でも、さらに様々な BEM 命名規則が存在するようですが(これらを今回は「BEM 系」とします。)、私が上記記事で BEM と指したのは BEM の中でもMindBEMdingというもので、現在「BEM 系」の中で最もポピュラーなものです。「BEM」と呼んだら多くはMindBEMdingを指します。

しかし私が実際に HTML/CSS 設計に取り入れているのはMindBEMdingではありません。(オススメしておいて・・・)

一貫性をもって管理しやすいMindBEMdingにもデメリットと思われる点があり、そこを解消したのが現在私が取り入れている命名規則です。
Block, Element, Modifier の設計思想には変わりがありません。命名規則だけが変わります。

BEM設計はブロック(モジュール)管理ができる考え方として良い設計だと思っていたため、シンプルで管理しやすい = 楽な命名規則を求め、BEMをもとにした命名規則は色々試しました。
様々なプロジェクトで試してPDCAを回して、やっと現在の命名規則に落ち着きました。
自信を持っておすすめできる命名規則ですので、命名に悩む方にはぜひお試し頂きたいです!

BEM の設計概念をある程度理解した上であれば取り入れやすい命名規則なので、ぜひ本記事を参考にして頂けたら幸いです。

広まれ〜〜!

まとめへショートカット

わたし的BEM命名規則まとめ

ちなみに、私の命名規則ってこれと同じじゃん!と思える既存の命名規則見つけて喜んでいたのですが、本記事を書くにあたって、よく説明を確認したらちょっと違いました。
一緒だと思っていたので、本記事はもともとそちらの紹介にするつもりだったのですが。。
仕方がないので、「わたし的BEM」に改めました。

ここまで出来たら良いよね・・・でもめっちゃクラス名長くなるなあっていう Chainable BEM Modifiers。
Chainable BEM

ああ、私のクラス命名もChainable BEMと呼びたかった。

MindBEMding の復習

BEM の基礎を復習したい方へ
前回 BEM の概要をご説明しました!

MindBEMdingは長いクラス名になってしまうため、コードが読みづらくなるのがデメリットだと言われています。

わたし的 BEM の命名規則

Block, Element はMindBEMdingと異なる点はありません。全てが同じです!
Modifire だけ異なります。

MindBEMdingとコードを比べながらご説明出来ればと思います。

たとえばこのようなボタンのパターンがあった場合
example_button.png

BEM の設計概念上では、ボタンという要素を Block とし、そのボタンのバリエーション・パターンとして存在する「青背景」を Modifier とします。

この BEM 設計の上、MindBEMdingだと以下の様にクラス命名・スタイル管理ができます。

MindBEMding

index.html
<button class="button">標準ボタン</button>
<button class="button button--blue">青ボタン</button>
style.scss
.button {
  width: 100px;
  padding-top: 8px;
  padding-bottom: 8px;
  border: none;
  background-color: grey;
  color: #fff;
}

.button--blue {
  background-color: blue;
}

クラス名に着目して、「button」も「blue」も文字数が少ないため今回は気になりませんが
これが「main-visual」と「registerer」だったら・・・
(例えで作りましたが、会員登録者にのみ見えるメインビジュアルを実装したい場合にありそうなクラス名です。)

<div class="main-visual main-visual--registerer">

となりますし、ここに Element まであると

<div class="main-visual__text main-visual__text--registerer">

こんなにタグが長くなっちゃうんです!
こんなのがたくさんあったら、コードが冗長に見えますよね。そのため嫌煙されることがあるのです。

わたし的 BEM はこの冗長化を解決しています。
先程のボタンは以下の様にクラス命名・スタイル管理ができます。

わたし的 BEM

index.html
<button class="button">標準ボタン</button>
<button class="button --blue">青ボタン</button>
style.scss
.button {
  width: 100px;
  padding-top: 8px;
  padding-bottom: 8px;
  border: none;
  background-color: grey;
  color: #fff;

  &.--blue {
    background-color: blue;
  }
}

// アンチパターン: 一見Modifierは汎用的に使えそうなクラスに見えるが、`.button--blue`の設計を保つべき。
// よって汎用的なクラスにはせず、あえて`.button`のサブクラスとして置かれた場合のみにスタイルが聞くようにセレクタを指定する。
// .--blue {
//  background-color: blue;
// }

Modifier が.block--modifireではなく、.--modifireのみになってすっきりしました。
Element がある場合も.block__element--modifier.modifierになります。

またコードにはアンチパターンも記載しています。
MindBEMdingから命名規則が変わったことで汎用的な.--blueクラスとしてもスタイル指定が出来ますが、あえて「ボタンの青背景パターン」としてしか使えないようにセレクタを限定することが BEM 設計を保つために重要なポイントです。

これで先程は冗長だったコードも短く出来ます!

index.html
<div class="main-visual main-visual--registerer"></div>
<p class="main-visual__text main-visual__text--registerer"></p>

=>

<div class="main-visual --registerer"></div>
<p class="main-visual__text --registerer"></p>

文字数が減ったことはもちろんですが、ぱっとタグを見たときも見やすくなったと思います。
読みやすさ = 管理しやすさ・触りやすさです。とっても大事!
MindBEMdingから比べても Modifier のみの違いなので、地味な変化ではありますがこれがファイル全体への変更となると大きく変わってきます。

まとめ

最後にわたし的BEM命名規則のまとめです。

  • Blockクラスは.blockMindBEMdingと同じ)
  • Elementクラスは.block__elementであり、親Blockの中でのみ存在できる。(MindBEMdingと同じ)
  • Modifireクラスは.--modifier
  • セレクタとしては、.--modifierに直接スタイルを付けることはしない。汎用的なクラスとはせず、Blockクラスまたは、Elementクラスと共に用いられたときのみにスタイルが効くように指定する。
  • Block, Element, Modifier それぞれ複数単語から成るときにはケバブケース(全て小文字&単語をハイフンで繋ぐ)を用いる。(MindBEMdingと同じ)

ちなみに、一時期.--modifier.-modifierにしていたこともありました。
ハイフンを1つにしていたんですが、そうするとファイル内でModifier名を検索する際に-modifierと検索して、BlockやElementクラス内でハイフンで繋いでいた同単語にも引っかかってしまいます。
このようにModifire以外も検索に引っかかる可能性が出てしまうため、現在は.--modifierと、ハイフンを2連続にしています。
検索性も大事ということ!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む