- 投稿日:2019-12-18T23:25:27+09:00
Railsで特定のURLからのリクエストを許可してiframeを表示させたい、、、
やりたいこと
Railsでiframeからのリクエストを許可して外部のサイトで表示させたい、、、
でもすべて許可するとなにかと怖いので特定のURLに絞りたい、、、ということで
Railsでは
response.headers['X-Frame-Options'] = 'SAMEORIGIN'が設定されていて自身のドメインしかiframeで表示出来ないそう
今回は特定のURLのみ許可したいので以下のように実装
class HogeController < ApplicationController after_action :allow_iframe, only: [:hoge] def hoge render "hoges/index", layout: false end private def allow_iframe url = "https://hoge.com" response.headers['X-Frame-Options'] = "ALLOW-FROM #{url}" response.headers['Content-Security-Policy'] = "frame-ancestors #{url}" end end注意点
なんと皆がよく使ってるであろうChrome、Safariなど多くのブラウザが
X-Frame-Options ALLOW-FROM
に対応していません1なので合わせて
Content-Security-Policy frame-ancestors
も記述してやりましょう2調べてみた感じIE以外対応してたので安心です3
効いてるか確認
Chrome DevToolsの
Network
パネルで確認できます
X-Frame-Options ALLOW-FROM
だけ設定してしまうと未対応ブラウザですべてのURLを許可する状態になってしまいます ↩
- 投稿日:2019-12-18T20:47:22+09:00
初心者によるプログラミング学習ログ 187日目
100日チャレンジの187日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
187日目は
おはようございます
— ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) December 17, 2019
187日目
webサイトコーディング課題
udemyでvue.jsをさらっと復習
いちおう形にはなったので、メンターさんに提出してみました。#100DaysOfCode #駆け出しエンジニアとつながりたい #早起きチャレンジ
- 投稿日:2019-12-18T20:25:29+09:00
<input type="file">をカスタマイズ
<input type="file">
を頑張ってカスタマイズしました。See the Pen form_file by d0ne1s (@d0ne1s) on CodePen.
ポイント
<input type="file">
のデザインは変更できないので、display: none
で非表示にしています。- 代わりに
label
とlabel:after
で、ボタンと「選択されていません」の文字列を表現しています。- ファイルが選択された時、
label:after
を非表示にし、代わりに<span>ファイル名</span>
を表示するようなjqueryを書きました。- 同一ページ内に複数あっても動くようになってるはずです。
その他
- こういうテンプレートを増やして、いい感じのデザインをパパッと作れるようになりたいです。
- 今回の書き方だとjqueryに依存しているので、時間がある時に生のJavascriptでもかいてみようと思います。
参考
- 投稿日:2019-12-18T18:47:50+09:00
WordpressのDBから自作SQLを使ってアイキャッチ画像を取得した結果わかったこと
1はじめに
Wordpressを勉強する人が最初にやることは、環境構築と管理画面の使い方だと思いますが!私はなんとデータベースから入りまして、管理画面⇒フォルダ構成と、なぜか逆走しながらWordpressを勉強中。今回は自作SQLを使ってアイキャッチ画像を取得したときのアハ体験をまとめました。
Wordpressのデータの全ては
WP_POSTS
が握っている!?Wordpressの便利なところは、ネットで検索すればなんでも出てくるところ。それだけユーザが多く、みんな困ったことを共有しているからなのでしょう。
Wordpressのデータベース(以下、DB)は、全部で12テーブルしかないとてもシンプルなもの。こんなにいろいろ出来るのに、12テーブルしか持ってないことに驚きを隠せないのですが、本当すごいですね…。(※でもこの後、データベースの構造的には否定的な見解になってきたのでそれはまた後日。)
Wordpressの主となるデータは全てWP_POSTS
にあると言ってもいいくらい、このテーブルはとっても重要なテーブルです。固定ページ・記事ページ・画像など、画面で見えるページのほとんどをこのテーブルで管理しています。※参考:Wordpress Codex 日本語版(データベース構造)
http://wpdocs.osdn.jp/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E6%A7%8B%E9%80%A0記事とアイキャッチ画像の紐づけは
WP_POSTMETA
で管理!今回、記事に使われているアイキャッチ画像のURLを取得するためネットで調べていたのですが、どのサイトもPHPの処理ありきで書いてあるではありませんか。いやいや、私はSQL1本でとってきたいのです。だって、PHP分かんないんだもん(´;ω;`)
でも、どの方法を見てもWP_POSTMETA
のmeta_key="_thumnail"
を条件に何かをみているではありませんか!(そういうのは分かる。笑)
どうやら、記事に使われているアイキャッチ画像の居場所を教えてくれているみたい…。ってか!数字しか書いてない!!どゆこと?と思ったら、どうやらその数字は、WP_POSTS
のID情報だということが分かりました。(さすが!すべてを握っているテーブル!!)アイキャッチ画像自体の情報はやっぱり
WP_POSTS
にある!さっそくアイキャッチ画像のIDを指定して表示したところ、見事!
WP_POSTS
のguid
にアイキャッチ画像のURLが格納されていました。神!これで、記事に使われているアイキャッチ画像の保存先を特定することが出来ました。アイキャッチ画像取得のために作成した鬼SQLがこちら↓↓↓
下記に記載するSQLは、アイキャッチ画像を取得するためだけのSQLではなく、「現在公開中の記事&ある特定のタグが付いている記事」という条件も追加しているSQLになっています。なので、途中ごちゃごちゃやっててすみません。
※[xxxxx]
のところは、限定したいタグのタグIDを記載するところなので、このまま実行しても動かないのでご注意ください。select post_list.id, post_list.term_id, post_list.name, post_list.post_title, post_list.post_date, img_list.guid from (select post.meta_id, post.id, tag.term_id, tag.name, post.post_title, post.post_date from (select wp_postmeta.meta_id, wp_posts.ID, wp_posts.post_title, wp_posts.post_date from wp_postmeta left join wp_posts on wp_postmeta.post_id = wp_posts.id where wp_postmeta.meta_key = '_thumbnail_id' ) as post left join (select wp_posts.id, wp_terms.term_id, wp_terms.name from wp_posts left join wp_term_relationships on wp_posts.ID = wp_term_relationships.object_id left join wp_term_taxonomy on wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id left join wp_terms on wp_term_taxonomy.term_id = wp_terms.term_id where wp_posts.post_status = 'publish' and wp_term_taxonomy.taxonomy = 'post_tag' ) as tag on post.id = tag.id ) as post_list left join (select wp_postmeta.meta_id, wp_postmeta.meta_value, wp_posts.guid from wp_postmeta left join wp_posts on wp_postmeta.meta_value = wp_posts.id where wp_postmeta.meta_key = '_thumbnail_id' ) as img_list on post_list.meta_id = img_list.meta_id where post_list.term_id = '[xxxxx]' order by post_list.post_date DESC;「長くて読む気にならん…汗」と近くに座っている人に言われたのですが(笑)、
WP_POSTS
が記事ページやら画像情報やらを全部レコード単位で保持しているのでややこしいだけで、実は結構考え方は簡単です。
上記SQLでは大きく分けて、post_list
という私が勝手に名前を付けたSQL内のテーブルと、img_list
というこれまた私が勝手に名前を付けたSQL内のテーブルが結合されています。それぞれのテーブルは、どちらもWP_POSTS
から必要なデータを取得しています。つまり!WP_POSTS
テーブル同士を結合させ、記事とアイキャッチ画像を紐づけているWP_POSTMETA
で繋いでいる、そんなイメージで作成しました。(何言ってるか分からなかったらすみません…。)
WP_POSTS
にあるpost_parent
に騙されてはいけない!はい、ここが今回のアハ体験によって声を大にして言いたいところです!!!
アイキャッチ画像のレコードを眺めていると、WP_POSTS
のpost_parent
に設定されている記事のIDが記載されているではありませんか!おお!WP_POSTMETA
で確認しなくても、ここで見ればええやん!って早とちりしてまんまとハマりました。
このpost_paret
には、確かにアイキャッチ画像を設定した記事IDが入ることもあるのですが、100%アイキャッチ画像として設定されている記事IDがセットされているわけではないのです。アイキャッチ画像の場合、
WP_POSTS
のpost_parent
の格納IDは管理画面の操作によって異なる今となってはちょっとずつ理解できているのでなんとなく分かることも多いですが、これを調べていた時の私はWordpress Codexの各テーブルのフィールド解説を読んでもチンプンカン。親ってなんや!添付ファイルが所属する記事IDってなんや!何がどう違うんやっ!!!ってほぼほぼ半泣き。笑
アイキャッチ画像の登録をいろいろな方法で試してみた結果、post_parent
に格納されるIDが3パターン存在することが分かりました。パターン1:記事編集画面にあるところからアイキャッチ画像を新規登録
⇒この場合は記事IDが格納されます。パターン2:メディアに新規登録したあと、記事編集画面からアイキャッチ画像を登録
⇒この場合は記事に依存しない画像という扱いになるので、一律ゼロが格納されます。パターン3:他の記事で使用・登録された画像を作成中記事のアイキャッチ画像として使う
⇒この場合、流用元の記事IDが格納されます。まとめ
WordpressはDBやプログラムが分からなくても簡単にWebサイトが作成出来るのが売りなのに、完全無視してDBを穴が開くほど見た結果、ちょっと楽しくなってきちゃいました。(今となっては前職の経験に感謝!笑)おそらく需要はないと思いますが、まだまだ同じようなアハ体験がけっこうあるので、ちょこちょこまとめて行きたいと思います。
おまけ
現在、絶賛中途採用募集中です!
もしご興味ありましたら、中途採用ページよりご応募ください。
※小声)一生懸命、中途採用ページをリニューアルしたので見に来てください!笑■株式会社サンシーア@上野(最寄り駅:銀座線 稲荷町駅)
https://www.sunseer.co.jp/recruit/careers/position.html
- 投稿日:2019-12-18T18:35:00+09:00
@contentを使って、@mixinにスタイルセットを渡す
@mixin
(ミックスイン)おさらいMixin(ミックスイン)は関数に近く、
CSSスニペットに名前を付けていつでもどこでも呼び出せるというイメージ。
mix
の呼び出しは@include
で呼び出す。app.css/* ミックスイン よく使うものをスニペットとして保存しておこう */ /* ミックスインの作り方 頭に@mixinを付ける @mixin 名前($変数1,$変数2,...){ プロパティ1:$変数1; プロパティ2:$変数2; プロパティ3:$変数1 $変数2 ...; } */ /* ミックスインの使い方 頭に@includeを付ける @include 名前(値1,値2,...); */ (例) @mixin btn() { display: block; padding: 20px 30px; color: #fff; border-radius: 6px; cursor: pointer; background-color: #20aee5; text: { decoration: none; align: center; } } .footer__sns__btn { @include btn(); // 『@include class名()』で呼び出し }
@content
の使い方・
@mixin
の中で@content;
と記述するとコンテントブロックを渡すことができる
・ これにより1つのmixinで呼び出し側に合わせた処理が可能例えば、
mixin,scss
というscssファイルに
スマートフォンでのレスポンシブを@mixin
似て呼び出せるようにしておきます。mixin.scss@mixin sp { @media screen and (max-width: 767px) { @content; } }例.scss.p-top-training { margin: 60px auto; padding-bottom: 98px; position: reltive; @include sp { margin-top: .8rem; padding: 0 .2rem .6rem 0; } &-content { background: url(/xxx/xxx.jpg) no-repeat center/cover; width: 1120px; height: 600px; padding: 100px 100px 155px 420px; @include sp { background: url(/xxx/xxx.jpg) no-repeat center/content; height: 5rem; padding: .6rem .4rem .8rem; width: 355px; } } &-background { background: url(/xxx/xxx.png) no-repeat center/contain; width: 1276px; height: 240px; position: absolute; right: 0; bottom: -29px; z-index: -5; } &-title { font-size: 60px; letter-spacing: 6px; color: #fff; text-align: center; @include sp { font-size: .4rem; letter-spacing: .04rem; } }こうすることによって各クラスに対して記述した
@include sp {}
の部分が@content
の部分に挿入されて行きます。
レスポンシブ対応などは、下にまとめて記述するより、タブレットごとの相違が一目瞭然になるのでわかりやすくなります。
- 投稿日:2019-12-18T14:41:38+09:00
オリジナルWebサービス -Lunches- (フルスクラッチ開発)
はじめに
フロントエンジニアを目指してプログラミング学習をしている小林と申します。
本記事ではオリジナルWebサービス「Lunches」の概要や制作過程について説明します。URL
リンク:Lunches
目的
- フルスクラッチ開発でPHP、SQLの言語理解を深める
- Webサービスの基本的な構成、動作を把握する
スペック
プログラミング言語:HTML5/ CSS3 / Javascript / PHP
データベース言語:MySQL
開発環境:macOS Catalina 10.15.1
バージョン管理:SourceTree
本番環境:さくらサーバー
機能
ユーザー管理機能
・ユーザー登録
・ログイン
・プロフィール編集
・ユーザー削除機能
・退会イベント機能(メインサービス)
・イベント投稿
・イベント詳細
・イベント一覧(ページネーション)
・カテゴリー検索、日付検索サービス概要
「Lunches」はランチタイムに恋愛やビジネス、友達作りなどもイベントを気軽に開催することができる
Webサービスです。
インターネットを通じて人との交流を活性化させることを目的として制作しました。開発手順
1.ワイヤーフレーム作成
7つブラウザ画面をノートに手書きでワイヤーフレームを作成しました。
2.テーブル設計
実装させたい機能から必要な情報を洗い出し、それに応じてテーブルを作成しました。
作成したテーブルは以下の3つです。3.画面モック作成
ワイヤーフレームを元にHTML・CSSでコーディングを行い画面モックを作成しました。
セキュリティ
バリデーションチェック
・未入力チェック
・Email型式チェック(正規表現)
・Email重複チェック
・最大、最小文字数チェック
・半角英数字チェック
・同値チェック例外処理
DBへ接続する際にはエラーで接続できない可能性を考慮して「try」「catch」で例外処理を行っています。
セッションIDの再生成
セッションハイジャックによって第三者による乗っ取りを防ぐためにsession_regenerate_idを使用
この関数をコールすることで現在のセッションデータを保持したまま、セッションIDを新しくすることができる。
パスワードハッシュ
DB側でユーザーのパスワードが漏れないようにパスワードをpassword_hashでセキュリティを高めています。ログイン時にはpassword_verifyを使用してハッシュ化されたパスワードと照合しています。
このとき第一引数である$passにはフォームからpostされたパスワード
そして、第二引数にはDBから配列形式で取り出した情報を$resultに詰め
array_shiftを使って先頭のパスワードを取り出しています。SQLインジェクション対策
DB接続時にはプレースホルダーを使用し、SQL文を作成。
値をバインドすることでSQLインジェクション対策を行っています。
Lunchesの使い方
①イベントの登録・ プロフィール編集
イベント投稿、プロフィール編集の画像登録ではjQueryを使用し、ドラック&ドロップでファイルをinputすることができます。②イベント一覧・検索機能
イベント一覧ページではGETパラメータを使用して、ページネーションと検索機能を実装しています。
検索機能はカテゴリー検索、投稿日時のソート順検索ができます。今後の課題
・スマートフォンにも対応したレスポンシブデザイン
・オブジェクト指向に基づく、保守性の高いコード設計
・FLOCSSをベースとしたCSS設計主に以上の3点です。
特に様々なデバイスからアクセスされるユーザーを想定したレスポンシブデザインでの設計は
現在のWebサービスでは必要不可欠な物だと思いました。
- 投稿日:2019-12-18T10:42:19+09:00
フィーリングでHTMLとCSSを書いていた新卒が模写コーディングをやった話
Ateam Lifestyle Advent Calendar 2019の21日目は
株式会社エイチームライフスタイル @kmfjが担当します!
初めての投稿で至らぬ点もありますがよろしくお願いします。はじめに
新卒でwebデザイナーをやっています。
普段はビジュアル〜マークアップ領域までを業務として行なっています。きっかけ
一からサイトを作った経験はあるものの独学で生き抜いてきたため、入社前までは
- コピペで組み立て
- コードの意味はなんとなく理解
- 見た目を見ながら無理やり調整
のパワー型脳筋コーディングでなんとか組み立てていました。
なんとなくは理解しているため、ProgateのHTML、CSSコースなどは問題なくクリアできました。
ですが、いざ実務レベルでコーディングとなると「どう構造化して実装したら良いか」がわかりませんでした。
その対策として取り組んだ模写コーディングが勉強になったと思っているので、どのように行なって、何がよかったかを記載したいと思います。やったこと
行ったことは以下の通りです。
1. 模写するサイトを選ぶ
選んだ基準としては、サイト構造が自社のサイトに近く、今後活かせそうなものを選びました。デザインが好みのサイトなど、自分が楽しんでできるサイトなどでもいいそうです。
2. 同じ見た目になるよう自分なりにコードを書く
どうしたら同じようになるか考えながらHTMLとCSSでコードを書いていきます。
3. 本物のサイトと比較する
Chromeの検証機能などを活用して、自分が書いたコードとどこが違うか?違う場合はどうして違うか?を考えます。
気をつけた点
模写元のコードは基本的に見ない
自分で構成することを身に付けることが目的なので、極力コードは見ないようにしました。ですが、画像やカラーコードなど考えても意味のないものはコピペしたり省略したりしました。
px単位での正確性は追求しない
見た目からコードに落とし込むことが重要なので、サイズや余白などは全体レイアウトが合っていれば問題ないと思います。
「良いレイアウトを学ぶこと」や「デザインに対して完璧なコードを書くこと」が目的であればもちろんpx単位で合わせるべきですが、今回の目的とはズレるためこのルールを設定しています。よかったこと
見た目からHTMLの組み立て方がわかってくる
ここはこういう構造にするとうまくいきそう、という勘所がわかってきます。
単純に実装パターンの幅が広がる
これが表現したい時はこうすればいいのか、が調べながら制作するうちにわかってきました。
学んだこと
上記に書いた「よかったこと」以外にも、自分で書いたコードと模写元のコードを比較すると気づくことも多かったです。大きく感じた差異は以下の2点です。
意味を考えてタグを選ぶこと
意味に合わせてタグを選ぶことで、共同作業者も理解しやすく、機械も理解しやすいコードになるのだと分かりました。
例えば、似たようなリンク要素が並んでいるコードに以下のような違いがありました。私の書いたコード<div class="p-content__list"> <a href="/" class="p-card"> <img src="images/xx.png" alt="ほげ" class="p-card__img" /> <div class="p-card__caption"> <span class="c-textS">ほげ</span> </div> </a> <a href="/" class="p-card"> <img src="images/yy.png" alt="ほげほげ" class="p-card__img" /> <div class="p-card__caption"> <span class="c-textS">ほげほげ</span> </div> </a> </div>模写したサイトのコード<ul> <li> <div class="category"> <a href="/" class="item"> <p class="thumb"> <img src="images/xx.png" alt="ほげ"> </p> <div class="categoryLabel"> <span>ほげ</span> </div> </a> </div> </li> <li> <div class="category"> <a href="/" class="item"> <p class="thumb"> <img src="images/yy.png" alt="ほげほげ"> </p> <div class="categoryLabel"> <span>ほげほげ</span> </div> </a> </div> </li> </ul>※内容を変更しています
いくつか異なる点がありますが、例えば複数の要素が並列で並んでいる場合、私は単純に
<div>
で囲んでいましたが、模写元のサイトでは<ul>
要素で囲んでいました。意味を考えると、<ul>
要素でくくるべきだと思います。要素が単体で存在できるような記述
長期的に運用していく場合は、要素が入れ替わったり、無くなったりしても崩れないコードが理想だと思います。現在利用されているサイトでは、そういった今後の運用を見越した実装になっていると思いました。
例えば私が書いたコードは周りを囲う要素にpaddingを持たせていましたが、模写元は要素それぞれにpaddingを持たせていました。要素が入れ替わる可能性のある場合、そちらの方がいいかもしれません。
それ以外にも、コーディングだけでなくレイアウトや命名の仕方で学ぶ点も多々ありました。
まとめ
部分部分でのコードはかけるけど、一から作ることが苦手な人にとっては、組み立て方を学ぶいい手段になると思います。
また、実際に利用されているサイトのコードと比較することで、気づかされることも多くあると思いました。最後に
ここまで読んでいただきありがとうございました!
Ateam Lifestyle Advent Calendar 2019の22日目は、@hytkgamiがお送りします!
"挑戦"を大事にするエイチームグループでは、一緒に働けるチャレンジ精神旺盛な仲間を募集しています。興味を持たれた方はぜひエイチームグループ採用サイトを御覧ください。
https://www.a-tm.co.jp/recruit/
- 投稿日:2019-12-18T08:43:47+09:00
HTML/CSS復習 marginの相殺及びmarginの無効化について
はじめに
現在自分はHTMLとCSSをもう一度復習しようと思い、HTML・CSSのモダンコーディングという技術書で復習をしています。
今回は、その復習途中で出会った、新しく覚えたことや重要な部分をまとめていきたいと思います。marginの相殺
marginとは、borderの外側の余白のことを言い、上下のmarginが隣接する別のmarginと重なってしまった場合、marginの総裁が起きてしまいます。
marginの無効化
今まで気づかなかったのですが、小要素の上下のmarginは無効化されてしまいます。
その解決策としては、親要素にborderプロパティで明確なborderを作ることや、小要素に実際にmarginを設定するのではなく親要素のpaddingを設定することで解決することができます。
- 投稿日:2019-12-18T02:20:57+09:00
エヴァ感のあるエラー画面をCSSアニメーションで作った話
ブラウザで表示するページを作るとき、つい作り込むのが面倒でサボりがちなのが 「エラーが発生した際にユーザに通知する画面表示」
特に私はインフラエンジニアなので、普段CLI経由での操作が多いため、ちょっとしたコードのエラーハンドリングなどは 「最悪コンソールに表示すればいいや」 くらいの感覚であまり「エラーをユーザに通知する部分」の実装に力を入れた経験がありませんでした
この記事ではこちらで紹介したOSSに「サーバで実行したShellScriptと、その実行結果をブラウザに表示する」という機能を追加する際に「ShellScriptがエラー終了したときの画面」を作る必要があったので、その実装方法を紹介します
実際の画面
まずは実際に作った画面を見てみましょう
背景には実際にエラーが発生した際に
catch
されるオブジェクトをJSONに変換して表示しています画面の中央で点滅しているのがエヴァ感を演出するメッセージになります
エラーメッセージが英語なので「警告」の文字だけ日本語にするのも統一感がないかと思い、英語でERRORと表示することにしました
エヴァ感について
エラー画面を作る際に、デザインの経験が全くない私が「エラーのような異常事態が発生したときに表示される画面」で、最初に思いついたのが、エヴァの「警告」画面でした
丸パクりするわけにはいかないので、エヴァのあの画面の「警告」感とは、いったいどういった要素で構成されているのか、というのを私なりに考え、以下のポイントをおさえて実装するようにしました
- 赤or黄のような警戒色 + 黒で画面を埋める
- 文字(メッセージ)が際立つようになっている(ここでは太くした)
- 点滅などの比較的動きが早く、注意を引くアニメーションがある
実際の HTML / CSS を見てみる
HTMLタグは単に
div
要素を使っています。内側の文字はh2
p
ですerror.html<div id="error_baner"> <h2>ERROR</h2> <p>Something wrong occurred</p> </div>cssは少し長いです。
flex-box
で文字をレイアウトしていますが、CSSアニメーションとはあまり関係ないので、説明は割愛しますerror.css<style> #error_baner { display: flex; flex-direction: column; justify-content: center; align-items: center; position: fixed; padding: 17px 17px 17px 17px; border-style: solid; border-width: 4px; border-color: rgba(255,0,0,1.0); border-radius: 17px 17px 17px 17px; background-color: rgba(0,0,0,1.0); ...(続く)...ここからが
CSSアニメーション
にかかわる部分ですerror.css...(続く)... animation: flicker 0.85s linear 0s infinite alternate none running; } @keyframes flicker { 0% { opacity: 0.0; } 50% { opacity: 0.34; } 100% { opacity: 0.85; } } #error h2 { font-size: 34px; } #error p { font-size: 17px; }
@keyframe flicker
の中で時間変化(%で表現)にともなってopacity (要素の不透明度)
を変化させるように定義しておいて、それを実際の要素に適用するときにはanimation: flicker ...
と指定しますそしてアニメーションのスピードや開始時間の遅延などをのパラメータを設定すれば、完成です
CSSアニメーションの使い方の説明は、探せばより詳しい記事が出てきますので、こちらでは簡単に説明します
animation: <animation-name アニメーションの名前(@keyframesで指定した名前)> <animation-duration アニメーション開始から終了までの時間> <animation-delay アニメーション開始までの遅延時間> <animation-iteration-count アニメーションを繰り返す回数> <animation-direction アニメーションの再生方向(0% -> 100%, 100% -> 0%など)> <animation-timing-function アニメーションの緩急の付け方> <animation-fill-mode アニメーション終了後にもcssを適用したままにするか> <animation-play-state アニメーションを実行するか>おわりに
CSSアニメーションが登場したおかげで、デザイナーでもフロントエンドエンジニアでもない私でも、JavaScriptをこねくり回すことも無く、凝った表現を実現する敷居がかなり下がったように思います
今後エラー画面を実装する方に、何らかのインスピレーションになればと思います