Quantcast
Channel: CSSタグが付けられた新着記事 - Qiita
Viewing all 8767 articles
Browse latest View live

エンジニアだけどポートフォリオサイト作ってみた話

$
0
0

ポートフォリオサイトを作ってみた

こんにちは、ntakahashiと言います。エンジニアですがポートフォリオサイトを作って公開してみました。HTML、CSSは初心者のためまだまだ作りは荒いですが今後改良していこうと思っています。こうした方がいいよとか、このブラウザだと見にくいとかありましたらコメントいただければ幸いです。

ntakahashi's Portfolio

転職活動のためいろいろ調べていたところ、エンジニアもポートフォリオとして自分の作成物を公開したほうが良さそうと思ったので自分も作ってみることにしました。実際に転職活動のために使うことはありませんでしたが、フロントエンドの技術の習得や趣味で作ったプログラムの紹介などしたいと思っていたのでいい機会になりました。

使用技術

  • HTML5
  • CSS
  • bootstrap
  • Git
  • GitHub
  • GitHubPages

参考にしたページ


CSSのアウトプット

$
0
0

cssについて学んだことまとめ

初学者がCSSを学ぶ上で、最初に使い方を悩むであろうものについてまとめてみる

aタグ、buttonタグで使われる状態を表現するCSS

:link
:visited
:hover
:active
:focus

LVHAFの順番で記述の優先度を覚える
:link-:visited-:hover-:active-:focus

:link
通常の状態での表現

:visited
既にクリックされている(訪問されている)リンクの状態

:hover
カーソルをリンクの上に置いた時の状態

:active
ボタンが押されている間だけの状態
第1ボタン、つまり右手用のマウスではふつう一番左のボタンにのみ適用すべき

:focus
タッチデバイスでタップした時、tabキーで移動した時などの状態
基本的にはform関連、ユーザビリティ的にある方がよい

::before,::after

HTMLには書かれていない要素もどきをCSSで作ることができる

::beforeは要素の直前に要素もどきが入る

::afterは要素の直後に要素もどきが入る

具体的な使い方

出力結果:吾輩は、猫である

<h1>猫である</h1>

h1::before {
  content: ‘吾輩は、’;
}

メリット

・SEOを気にせずにユーザーのための自由な表現ができる
(UIに出したいけどSEOとして不要な要素をCSSから画面に当てる)
・アイコンやフォントを疑似要素で表示できる
・position: absoluteで絶対配置にして、自分の好きな位置に配置が可能

具体的な使い方

ブログとかのカード要素の右上のラベルとかに使われている
スクリーンショット 2019-12-29 12.46.31.png
ブログ:まじまじパーティーより引用

::backdrop-filter(IE未対応)

背景にfilterを使える

具体的な使い方

背景のすりガラスの表現等

使えるコード種類

コード意味
blurぼかし(pxで指定)
brightness明るさ(単位なし)
contrastコントラスト(%で指定)
grayscaleモノトーン(%で指定)
invert階調反転(%で指定)
hue-rotate色相(degで指定)
opacity不透明度(%で指定)
sepiaセピア調(%で指定)
saturate彩度(%で指定)
drop-shadowドロップシャドウ(pxで指定)

メリット

1つの画像の別々の部分に、別々のフィルターを使える(表現性が豊富)
内側の要素に影響がない
::filterとコーディング法は同じ

デメリット

対応ブラウザが少なく、実験状態

calc

css上で計算ができる

具体的な使い方

横幅が1/6になる

.hoge{
     width: calc(100% / 6);
}

メリット

calc() はマージン設定を持つボックス配置、フォーム要素のサイズ変更等

レスポンシブデザインに欠かせないメディアクエリについて整理する

$
0
0

はじめに

コーディングの勉強で色々なサイトを見ている時、実際に自分でコーディングする時、レビューをする時など、「ブレークポイントが768px以上の場合(※)はmin-width:768px;だっけ? いやmax-width:768px;か?」と一定の確率で迷うので、年末年始のお休みを使ってメディアクエリ周辺の知識を整理して、自分の頭をスッキリさせたいと思います。

min-width:767px;max-width:768px;のどちらかで、ウィンドウ幅768px以上を指定できます。どちらを選択するかは、他のCSSの記述方法によって変わってくると思います。

メディアクエリとは

メディアクエリとは、メディアの特性(ブラウザのウィンドウ幅や高さ、デバイスの向き)などに応じて適用するスタイルを切り替えることができるCSS3で追加された仕様の1つです。

今回はレスポンシブデザインに使う部分のみ紹介していきますが、もっとメディアクエリについて学びたい方はMDN Web Docsをご一読ください。

ブレークポイントとは

ブレークポイントとは、スタイルが切り替わる画面サイズのことを指します。
Web 1280 – 1.png

ブレークポイントの決め方

自分のサイトの用途やデザインに応じて細かく設定することも可能ですが、分岐が細かくなるほどその後の管理が煩雑になります。
だいたいはPC、タブレット、スマートフォンの3つのデバイスのサイズを想定し、ブレークポイントを2箇所(※)、もしくは1箇所(※)で設定しているのではないでしょうか。

画面サイズに関しては、それぞれ時代に応じたトレンドや自分のサイトの傾向があると思うので、適宜アナリティクスなどでデバイスシェアを調べて設定してみると良さそうです。

※ブレークポイントが2箇所:PC、タブレット、スマートフォンそれぞれで分岐
※ブレークポイントが1箇所:PC・タブレット合同、スマートフォンで分岐

メディアクエリを使ってCSSを書いてみる

ブレークポイントを768pxとして、メディアクエリを使って実際にCSSを書いていきましょう。

画面サイズが768px未満の場合

Web 1280 – 2.png

@media(max-width:767px){/* 画面サイズが768px未満の場合の設定 */}

max-widthでブレークポイントの最大値を指定。
(max-width: ●●px)●●px以下という設定になるので、未満で設定する時は1px小さい値で設定する必要があります。

画面サイズが768px以上の場合

Web 1280 – 3.png

@media(min-width:768px){/* 画面サイズが768px以上の場合の設定 */}

min-widthでブレークポイントの最小値を指定。

画面サイズが768px以上、960px未満の場合

Web 1280 – 4.png

ブレークポイントを2箇所設定する場合は、下記のような記述になります。
1箇所の時に比べて若干ややこしくなるので、私はこの記述方法にならないようにしています。

@media(min-width:768px)and(max-width:959px){/* 画面サイズが768px以上、960px未満の設定 */}

モバイルファーストインデックスに対応した書き方

cssのカスケーディングの特性を利用して、タブレットやPCの画面幅のスタイルを上書きしていきます。
下記画像のように上書きしていきます。
もし、スマートフォンと同じスタイルで問題ない場合は、上書きせずそのまま使用します。
Web 1280 – 5.png

See the Pen Media Queries by yamaking (@yamaki0405) on CodePen.

codepenで書いてみました。
ウィンドウ幅を伸縮させてどうなるかを実際に試してみていただけると嬉しいです。

まとめ

メディアクエリ意味結果
@media (max-width: 767px)ブレークポイントの最大値が767px画面サイズが768px未満の場合のスタイルが指定できる
@media (min-width: 768px)ブレークポイントの最小値が768px画面サイズが768px以上の場合のスタイルが指定できる
@media (min-width: 768px) and (max-width: 959px)ブレークポイントが768px〜959pxの間画面サイズが768px以上、960px未満

max-widthブレークポイントの最大値min-widthブレークポイントの最小値ということの設定ができる」ということを頭に入れておくと、迷わずにすみそうですね。



以上です。
最後までお読みいただき、ありがとうございました。


お世話になったサイト

Reactでcssをオブジェクトとして読み込む

$
0
0

cssファイルを読み込んだのに{styles.〇〇}で使えない

import React from "react";
import styles from "./styles.css";
このように読み込んだ。

className={styles.〇〇}で設定してもスタイルが適応されない!!
console.logで確認したらundifined。

ハマってしまったので備忘録

create-react-appで簡単にcss moduleが使えるようになってた。

↑ここが参考になった。

cssファイルを〇〇.css→〇〇.module.cssにする

import React from "react";
import styles from "./styles.module.css";
そしてこのように読み込んだ。

これだけで解決。
ちゃんとオブジェクトとして取り出せるようになった。

年末まで毎日webサイトを作り続ける大学生 〜72日目 Mouse Overと画像~

$
0
0

はじめに

こんにちは!@70days_jsです。
mouseoverで画像が少しずつ現れるサイトを作りました。(gif)↓

test3.gif

今日は72日目。(2019/12/29)
よろしくお願いします。

サイトURL

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

やったこと

mouseoverで画像が少しずつ現れるものを作りました。

今回JavaScriptとcssで作ったので、htmlは何も書いていません。

html↓

<body></body>

cssではあらかじめ画像を表示したり、スタイルを用意しています。

css↓

body{width:100vw;height:100vh;overflow:hidden;margin:0;background-image:url("day31_image/4.jpg");background-size:cover;}.oneBlock{background-color:white;position:absolute;border-right:solid2pxblack;border-bottom:solid2pxblack;display:flex;justify-content:center;align-items:center;}

JavaScript↓

letbodyWidth=window.innerWidth,bodyHeight=window.innerHeight,oneBlockWidth=bodyWidth/10,oneBlockHeight=bodyHeight/10,oneBlockList=[];for(vari=0;i<10;i++){for(varj=0;j<10;j++){letdiv=document.createElement("div");div.classList.add("oneBlock");div.style.width=oneBlockWidth-1+"px";div.style.height=oneBlockHeight-1+"px";div.style.top=oneBlockHeight*i+"px";div.style.left=oneBlockWidth*j+"px";letnumber=i*10+(j+1);div.setAttribute("id",number);div.innerHTML=number;oneBlockList.push(div);document.body.appendChild(div);}}for(vari=0;i<oneBlockList.length;i++){letoneBlock=oneBlockList[i];oneBlock.addEventListener("mouseover",function(){oneBlock.style.backgroundColor="rgba(0,0,0,0)";oneBlock.innerHTML="";});}

まず1~100のblockはdivで出来ていますが、これはfor文のネストで作っています。↓

for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
...
}
}

この段階で全てのdivのスタイル・idを設定し、全てのdivを1つの配列に格納しています。

oneBlockList.push(div);

その後、配列をfor文で回してイベントリスナーをつけています。↓

for (var i = 0; i < oneBlockList.length; i++) {
...
oneBlock.addEventListener("mouseover", function() {
...
}
}

わざわざ配列に入れずに初めのfor文に書いてもいいのですが、長くなりすぎるのを懸念して分けて書きました。
そう考えると、スタイルの付与等も役割別で分けてもよかったかもしれません。

感想

残りあと2日。頑張ろう

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

サーバーにアップしたCSSファイルが反映されない時の解決法

$
0
0

はじめに

以前Xserver(レンタルサーバー)に自作サービスをアップしたのですが、CSSファイルを修正して再度アップしてサービスにアクセスしてブラウザで表示したところ・・・

CSSが反映されない!!!!

ということでこの現象の解決方法について調べて試した結果、無事解決することができたので記事として残しておきます。

同じ現象で悩んでいる方の参考にされば幸いです。

対処法

僕が調べた限りでは、下記の通り3つの解決法があります。
(他の方法をご存知の方がいらっしゃいましたら是非コメント欄でコメントをお願いしますm(__)m)

1.ブラウザ側のキャッシュを削除する
2.サーバー側のキャッシュを削除する
3.Disable cacheにチェックを付けてリロードする

では1つずつ説明して行きます。

ちなみに僕は3.Disable cacheにチェックを付けてリロードするで解決しました。

そもそもキャッシュって?

キャッシュについてはサルワカさんのブログで以下の通り解説されています。

キャッシュとはパソコンやスマホに一時的にウェブページのデータを保存しておいて、次に同じページを開いたときに素早く表示させる仕組み。

サルワカさんのブログ「キャッシュとは?IT初心者でもわかるように解説」

1.ブラウザ側のキャッシュを削除する

これはご存知の方が多いと思います。

方法の順序としては、

①GoogleChromeのデベロッパーツールを開く

GoogleChrome上で表示された画面でoption+⌘command+Iを押すもしくは画面上で右クリック→検証をクリックすることでデベロッパーツールを起動できます。
(ご存知ですよね・・・)

スクリーンショット 2019-12-29 21.35.24.png

②リロードボタンを右クリックしてキャッシュの消去とハードの再読み込みをクリック

画面左上のリロードボタン(矢印が輪っか状になっているボタン)を右クリックしてキャッシュの消去とハードの再読み込みをクリックします。

スクリーンショット 2019-12-29 21.35.54.png

ちなみに、PHPファイルをブラウザだけで表示している場合に修正箇所が反映されないことがよくあるのですが、この方法で解決します。

2.サーバー側のキャッシュを削除する

これは僕は今回の現象が起こるまで1.ブラウザ側のキャッシュを削除するしか方法を知らなかったのですが、解決しなかったので調べて新しく知った方法です。

サーバーに公開しているサイト・サービスの場合はブラウザ側だけでなくサーバー側にキャッシュが残っている場合があるみたいなのでこれを削除する方法です。

僕はレンタルサーバーとしてXserverを使用しているのでここではXserverでのサーバー側のキャッシュを削除方法を説明します。

①Xserverのサーバーパネルにログインする
ここはXserverを触ったことのある方ならわかると思いますので割愛させていただきます。

②サーバーキャッシュ設定をクリックする
スクリーンショット 2019-12-29 22.12.39.png

③修正したいサイトのドメイン名を選択する
スクリーンショット 2019-12-29 22.14.08.png

④キャッシュを削除する
スクリーンショット 2019-12-29 22.14.20.png

これでサーバー側のキャッシュを削除することができます。
この方法で解決できる場合もあるみたいです。

3.Disable cacheにチェックを付けてリロードする

こちらも新しく知った方法です。
僕は今回はこちらの方法でCSSの反映に成功しました。では手順です。

①デベロッパーツールを起動する

先ほど説明したのと同じやり方でデベロッパーツールを起動します。

②NetWorkタブを選択してDisable cacheにチェックを入れる
スクリーンショット 2019-12-30 0.26.01.png

③ページをリロード
画面左上のリロードボタン(矢印が輪っか状になっているボタン)をクリックしてページをリロードします。
このとき、デベロッパーツールは閉じてはいけません!

この方法はキャッシュを削除するというよりは「キャッシュの使用を禁止する」という意味みたいです。
Disable cacheにチェックを入れた状態でページを再読み込みすると、キャッシュは使用せず、サーバーからファイルやデータを読み込むようになります。
よって、新しいCSSファイルの内容を読み込むことができたようです。
この機能はデベロッパーツールを起動させている間のみ有効です。

最後に

この記事ではサーバーにアップしたCSSファイルが反映されない時の解決法について紹介して行きました。

手順自体は簡単なので、比較的覚えやすいかなと思います。
同じような現象でお困りの方の参考になれば幸いです。

初心者によるプログラミング学習ログ 198日目

$
0
0

100日チャレンジの198日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

198日目は

プログラミング勉強

$
0
0

今日は基礎の二週目をスタートし、テストの復習を行う💻
頑張るぞ😉


最初のほうから始めるJavaScriptとVue.jsそして composition-api

$
0
0

目的

プログラミングはしたことあるけど、Web系はあまり経験していない。
Webプログラミングしたことあるけどググって何となくやっている。

上記のような人たちを対象に Vue.js でアプリケーションを書く利点を理解してもらう。
加えて composition-api を利用する利点を理解できるまでにしたい。

基本的な使い方やAPIなどは世の中に星の数ほどあるチュートリアル記事に任せるとして、ここでは、なぜ Vue をWeb開発に利用するのか?という点にフォーカスする。

注意

  • プログラミング経験自体はあることを前提とするので、基本的な制御構文や個別のAPIを掘り下げたり詳細な説明はしない。
  • 説明の順序的にHTMLなどの説明からすることになるが、個別のタグやCSSのプロパティについての説明もしない。
  • React などと比較して Vue を選択する動機などは説明しない。本文章の役割はその前段階にある。
    • React を勧めたい人はこの説明をそのまま React や Hooks に変えればよいのかもしれない
  • Vue.js にはカスタムコンポーネントの定義という強力な機能があるが、本文章ではそれに触れない。別途 WebComponents と比較した記事を書くことを予定している
  • インタラクティブなWebアプリケーションを作るときにVue.jsを利用する動機を理解してもらうことにフォーカスし、トピックを絞りたいのでモジュールバンドラーなどには触れない

本文章の構成

初めにHTML/CSSの簡単な説明をする。続いてインタラクティブなアプリケーションを実現するためにJavascriptが必要であることを示す。
その際にはいくつかのAPIを説明しつつ、どのようにインタラクティブなWebアプリケーションを作成するかの説明をする。

そのあとは、良いプログラムはどのようなものか?という点にフォーカスしていく。
なぜ、DOMエレメントの操作を中心としたプログラミングはつらくなるのか?どうすればその負担を軽減できるかを考える。
ここまでの操作中心のプログラミングに対する問題への一つの回答として、Vue.jsを紹介し宣言的にUIが記述できることの利点を示す。
実際に VanillaJS と Vue.js でアプリケーションを作成し、宣言的にUIが記述できることの強みを体感する。
最後は、テスタビリティなどの観点から Vue.js の object-based API の問題点を示す。そして composition-api がその問題点に対する一つの解決策であることを紹介する。

Webコンテンツと HTML / CSS について

HTMLとCSSに関する詳細な説明は以下を参照するとよい。

以下に比較的簡単な説明を記載する。

HTML

HTMLはHyperText Markup Languageを略した語。HyperText とは文書と文書をリンクする特徴を持った文書を指す。
Markup Languageとは、文書に対して意味を与えることを目的とした言語を指す。
例えば HTMLには文書の見出しを示す タグとして h1, h2, h3などがある。
これは <h1>文書の目的</h1>のように利用し、h1タグで囲まれたテキストがレベル1の見出しとして意味を持つことを表している。以降ではタグで囲んでいる領域を「要素」や「エレメント」と呼ぶ。例えばh1要素などと呼ぶ。

HyperText としての特徴である文書のリンクは aタグで実現する。

<ahref="google.com">Google.com へのリンク</a>

ここで、 hrefはタグの属性(attribute)を示している。
href属性はhypertext referenceを略したもの(諸説あるらしい)で設定された値はリンクする値を示す。
つまり、「Google.com へのリンク」というテキストは、"google.com"にある別のhypertextへのリンクであることを示す。

ブラウザー

HTMLは文書に意味付けをするが、そのまま読むのは難しい。ブラウザを利用することで意味に応じた見た目で文書を表示してくれる。
例えば h1 タグなどの見出しは他の文字よりも大きく・太く表示される。
a タグはマウスカーソルを合わせるとクリックできるような表示に変化する。クリックすることでリンク先の文書が表示される。
HTMLは意味づけされた文書だが、ブラウザーを通すことで(原始的だが)インタラクティブな体験ができる。

CSS

CSSはCascading Style Sheetsを略した語。ブラウザーの表示機能を上書きする機能をもつ。
このようにブラウザで定義されている基本的な表示(Style)を引き継ぎつつ部分的に上書きされていくさまからCascadingという語が与えられている。

CSSは以下のような基本構文を持つ。

<セレクター>{<プロパティ>:<値>}

セレクターはエレメントを指定する。プロパティは変更したいスタイルを示す。値はスタイルの値を示す。

例えば以下は p 要素の文字列を赤色にするルールを定義している。

p{color:red;}

セレクターにはタグ名を指定する以外にいくつか指定方法がある。
比較的単純な指定方法として id と class による指定を説明する。
これらはいずれもHTMLの属性として指定できる。

以下のHTMLに対して

<p>huga<p><pid="hoge">hoge</p><pclass="foo">foo</p><pclass="foo bar">foobar</p>

以下のCSSを設定したとき

#hoge{color:red;}.foo{font-weight:bold;}.bar{color:blue;}

以下のように表示される

  • hugaはそのまま
  • hogeは赤字
  • fooは太文字
  • foobarは太字で青文字

この章のまとめ

  • HTMLは文書に意味を設定するための言語
  • ブラウザで見ることでHTMLは意味に応じた表示になる
  • ブラウザを用いることでHTMLでインタラクティブな体験ができる
  • CSSはブラウザでの表示を変更することができる

プラクティス

  1. HTMLのタグを調べてHTML文書を作成し、ブラウザでその表示を確認せよ
  2. CSSのセレクターとプロパティについて調べ、1で作成した文書をスタイリングせよ

JavaScript

JavaScript はブラウザー上で動作するプログラミング言語。
他の言語と同様に一般的な計算などができる。
しかし、主な興味は静的な文書という性質のWebコンテンツをより動的でインタラクティブなアプリケーションへと引き上げることにある。

インタラクティブな体験に必要な要素は大きく分けて以下の二点となる。

  • ユーザの入力を受け付けること
  • 画面を更新すること

つまり、インタラクティブとは相互的であるということなので、ユーザの入力に応答して(前者)入力に対して応答すれば良い(後者)

本章の説明には以下のHTMLを利用する

<main><h1>Counter</h1><pid="count">Count = 0</p><buttonid="btn">Click</button></main>

DOM

WebのコンテンツはHTMLなので、動的なコンテンツとするためにはJavascriptでHTMLを操作できる必要がある。
HTML文書は要素をツリー状に表現したDOM (Document Object Model)、特にHTML DOMという仕様を利用してJavaScriptからHTMLを操作することができる。

https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model

ユーザの入力を受け付ける

ユーザの入力を受け付けるには JavaScriptを使ってHTMLの要素を取得する必要がある。
以下のようにしてDOM要素を取得できる。

constbtnElement=document.querySelector("#btn")

documentオブジェクトはブラウザ環境でグローバルに存在し、DOMにアクセスするためのAPIを提供している。
querySelectorメソッドは引数にCSSセレクターをうけとり、セレクターに合致する最初に見つかった要素を返す。
https://developer.mozilla.org/ja/docs/Web/API/Document/querySelector

ここでは、ユーザーからの入力として、ボタンへのクリックに応答するようにする。
クリックに限らず発生するイベントは addEventListnerメソッドで応答できる。
https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener

より正確に言えばには特定のイベントが発生したときに、実行してほしい処理を登録することができる。
以下のように処理を登録する。

btnElement.addEventListener('click',handlerFunction);

handlerFunctionは実行する処理が定義された関数を示している。
例えば以下のように定義する。
また、console.logはブラウザの開発者ツールに引数を表示するメソッド。

consthandlerFunction=()=>{console.log("hoge")}

ここでは定義した関数を変数handlerFunctionへ代入している。
ここで、JavaScriptにおいて関数は、文字列や数値と同様に扱うことができることに注意する。
このような特徴があるため、addEventListnerメソッドへの引数として handlerFunctionを渡すことができる。
ここまでで、以下のようなコードになっている。

See the Pen JS Step1 by sterashima78 (@sterashima78) on CodePen.

開発者ツールを開いてボタンをクリックするとhoge という文字が表示されることが確認できる。
Screenshot 2019-12-28 at 20.51.51.png

ここまでで、ユーザの入力に応答することができるようになった。

画面を更新する

ここまでに記載したように画面はHTMLとCSSで指定をもとにブラウザによって構成される。
したがって画面を更新するということはHTML (DOM) やCSSのスタイル定義をJavascriptで変更するということになる。
ここでは、ボタンをクリックしたら、これまでにクリックした回数を表示するように画面を更新させるように変更する。

まずは更新したいエレメントを取得する。

constcountElement=document.querySelector("#count")

innerText属性は、対象エレメントがマークアップしているテキストを有している。

// countTextには "Count = 0" が含まれるconstcountText=countElement.innerText;

この文字列から数値部分を抜き出して、1を加算し、innerText を更新すれば期待通りの動作をする。

// numberTextの中身は "0"constnumberText=countText.replace("Count = ","")// 文字列 "0" を数値に変換してconstcount=parseInt(numberText)// 先程得た数値に 1 加えた数と "Count = " という文字列を結合して、// "Count = 1" という文字列にしている// それを `innerText` 属性へ代入しているcountElement.innerText=`Count = ${count+1}`

ここまでが以下になる。


See the Pen
JS Step2
by sterashima78 (@sterashima78)
on CodePen.


ボタンをクリックすると数字部分がカウントアップされているのが確認できると思う。
今回は、テキスト属性であったが、同様にスタイルやその他の属性を操作するための方法や、別のDOMを追加・削除する方法が提供されており、それを利用することで画面の更新ができる。

まとめ

  • ブラウザでは HTML 文書は DOM として解釈・保持される
  • JavaScriptを利用することで DOM を操作することができる
  • DOM へのイベントに応答と、DOMの変更による画面の更新をJavaScriptで行うことでインタラクティブなWebアプリケーションが実現できる

プラクティス

  1. DOM で発生するイベントについて調べよ
  2. DOM の属性や、それを変更するAPIについて調べよ
  3. 1 で調べたイベントに応答し、2で調べたAPIを利用して任意のDOM属性が変更されるようなインタラクティブなアプリケーションを作れ

JavaScriptによるアプリケーション作成で発生する問題

前章までで、基本的なWebアプリケーションを作る仕組みを説明した。
本章では、前章までの延長線でアプリケーションを構築するとぶつかる問題点について考える。

この章では、以下のコードを例にする。

See the Pen JS Step3 by sterashima78 (@sterashima78) on CodePen.

このコードでは、ボタンのテキストにボタンをクリックした回数が表示され、クリックするごとに回数が増えていく。

問題点: 表示が「操作の積み重ね」によって決定される

大きな問題として、画面への表示が操作の積み重ねによって決定することが挙げられる。
このアプリケーションでいうと、ボタンのテキスト部分は「クリック」という操作によって決定する点。

もちろんこれぐらい小さなアプリケーションであれば、大きな問題にはならないことが多い。
ここでは、たくさんクリックをしたら表示が崩れる。という報告があったとする。

codepen.io_sterashima78_pen_PowKeQV.png

明らかに数字の桁数が長いことが問題なので、上限を決めるなりすれば良いことがわかる。
しかし、アプリケーションの複雑さによっては、どのような操作によってこの状況を再現できるかわからないこともある。そうなれば、たくさんクリックをするしかない。

改善の方針

堅牢なソフトウェア作るときに気をつけたら良いことに、「責任を適切に分ける」ことがある。
例えばこのアプリケーションには、以下のような責任の要素がある。

  • ボタンの表示 (見た目)
  • ボタンがクリックされた回数 (状態)
  • ボタンのクリック検知 (イベントへの応答)
  • クリック回数の更新 (状態の変更)
  • 表示の更新 (状態に基づく DOM の更新)

まずは、これらが HTML/CSS/JavaScript のうちどれの責任になっているか確認する。

  • ボタンの表示 (見た目) : HTML/CSS
  • ボタンがクリックされた回数 (状態): HTML
  • ボタンのクリック検知 (イベントへの応答): JavaScript
  • クリック回数の更新 (状態の変更): JavaScript
  • 表示の更新 (状態に基づく DOM の更新): JavaScript

「見た目」と「状態」の責任を HTML が担っていることが問題といえる。
つまり、アプリケーションの状態がその時の見た目としてだけ保持されているため、再現が難しくなる。
これは、先程提起した問題の直接的な原因のひとつ。

状態と表示の責任が分離してあり、状態によって表示が決定するようになっていれば、この問題は解決できる。
なぜなら、状態が適当であるのに、表示が崩れていればそれは「表示」の問題とわかる(スタイルの誤りなど)。逆に状態で不適当であれば、「状態の変更」に問題があるとわかる(意図していない値を設定してしまうなど)。

改善のために、まず、これらの責任を適切な言語に分けることが必要。
加えて、プログラムコード上でもさらに責任を分離することで検証などがやりやすくなる。

改善の実施

この章のはじめに記載したコードからスタートし、段階的にすすめる。


See the Pen
JS Step3
by sterashima78 (@sterashima78)
on CodePen.


状態を定義する

表示である、DOMから値の取得・変更を直接することをやめる。
代わりにJavaScriptに状態を定義し、これを変更し、この値をDOMへ反映させるようにする。
以下のように修正した。

See the Pen JS Step3-1 by sterashima78 (@sterashima78) on CodePen.

状態の変更を分離する

状態を変更する処理を分離する。
例えば以下のようになる。

See the Pen JS Step3-2 by sterashima78 (@sterashima78) on CodePen.

状態の変更を分離することには大きなメリットがある。
それは動作の検証がしやすくなることだ。

特に、今回作成したコードでは変更関数が依存している状態を、関数の引数として注入するようにしている。
これによって、検証プログラムでは任意の値を注入することができる。

たとえば、バグ報告を受けて、1000000 以上にはインクリメントできない(増えない)ような仕様が追加されたとしよう。

これを検証するためのコードは以下のように記述できる。

/**
 * インクリメントされる (1 -> 2)
 */conststate1={count:1}mutator.increment(state1)if(state1.count==2){counsole.log("OK: test increment1")}else{thrownewError("Fail: test increment1");}/**
 * インクリメントされない (1 -> 2)
 */conststate999999={count:999999}mutator.increment(state999999)if(state999999.count==999999){counsole.log("OK: test increment999999")}else{thrownewError("Fail: test increment999999");}

表示の更新を分離する

表示の更新も同じ要領で分離する。
状態の変更のときは依存している状態を引数で注入できるようにしたので、
ここでは、更新のもととなる状態と、更新対象のDOMを注入する。

例えば以下のようになる。

See the Pen JS Step3-3 by sterashima78 (@sterashima78) on CodePen.

こちらも同様に、責任を単一にし、依存を注入することで検証がやりやすくなる。

イベントの登録を分離する

考え方はここまでと同じなので、完成したものを見てもらえば、理解できると思う。

See the Pen JS Step3-4 by sterashima78 (@sterashima78) on CodePen.

再利用性

ここまで、責任を分離することに注力してきたが、これによって更に良いことがある。
それは、再利用ができる小さな機能の集合でアプリケーションが構成されたことだ。

例えば、状態が分離されたことで、新しい状態を用意すれば簡単に別のカウンターボタンを用意できる。

See the Pen JS Step3-5 by sterashima78 (@sterashima78) on CodePen.

render を変更すれば表示のされ方を変えることができる。

See the Pen JS Step3-6 by sterashima78 (@sterashima78) on CodePen.

まとめ

  • DOM の変更をベース作成したアプリケーションが「表示」と「状態」の責任が分離できず、問題の切り分けなどがしにくい
  • 責任を分離したコードは再利用性が高く、テストがしやすい

プラクティス

  • 前章で作成したアプリケーションを本章の方針に沿ってリファクタリングせよ

宣言的なプログラミング

プログラミングのスタイルには大きく分けて命令的なものと宣言的なものがある。
この章では、まず命令的なスタイルと宣言的なスタイルについて説明する。
その上で、Webアプリケーションの構築において宣言的なスタイルが有効であることを示し、Vue.js を利用することでこれが実現できることを示す。

「命令的」と「宣言的」

ここでは、命令的のことを、ある目的を実現するための処理を逐次的に記述するスタイルのことを指す。
その一方で、宣言的のことは、ある目的のあるべき状態を記述するスタイルのことを指す。

具体的な例を出すと、HTML/CSS は宣言的。

赤文字で、文字サイズが 15px の文章、「赤文字テキストです。」を表示したいとする。
以下のように、表示したい文言や、そのスタイルを記述することで実現できる。

<pstyle="color:red;font-size:15px;">赤文字テキストです。</p>

これと同等なことが JavaScript でもできる。

まず、document.createElemntという API で DOM が作れる。
そして、document.createTextNodeという API で文字列を表す DOM の要素が作れる。
加えて <DOMElement>.appendChildという API を利用すると、 <DOMElement>の小要素として、別の DOMElement を追加できる。
最後にスタイル属性は styleというプロパティで DOM は有している。

上記を踏まえると、以下のように処理を記述することで同等な表示に相当するDOMを得ることができる。

// 文章を表す要素を作成するconstp=document.createElemnt("p")// テキスト要素を作るconsttext=document.createTextNode("赤文字テキストです。")// テキスト要素を文章要素に挿入するp.appendChild(text)// スタイル属性を設定するp.style["font-size"]="15px"p.style["color"]="red"

この例では、JavaScript はDOMを直接操作している一方で、HTMLの例ではブラウザーがDOMを組み立ててくれている。HTMLは宣言的にどのような構造の文書であるかをそのまま記述すればいい。
HTMLのような、宣言的スタイルは誤りが起こりにくい。

JavaScript でも宣言的なスタイルでプログラミングはできる。
以下で簡単な例を示す。

1から5までが入った配列の各要素を二乗にした配列を作成したいとする。

はじめに、手続き的な例を示す。

// もとの配列constquery=[1,2,3,4,5]// 結果の配列constsquared=[]// 1つ目の要素を二乗にするsquared[0]=query[0]*query[0]// 2つ目の要素を二乗にするsquared[1]=query[1]*query[1]// 3つ目の要素を二乗にするsquared[2]=query[2]*query[2]// 4つ目の要素を二乗にするsquared[3]=query[3]*query[3]// 5つ目の要素を二乗にするsquared[4]=query[4]*query[4]

上記の例は冗長な記述であるから手続き的であるという言うわけではない。
以下のように記述しても一つづつ要素を二乗し、新しい配列に詰めていくという命令を記述していることに変わりない。

// もとの配列constquery=[1,2,3,4,5]// 結果の配列constsquared=[]for(iteminquery){squared.push(item*item)}

宣言的な記述にすると以下のようになる。

// もとの配列constquery=[1,2,3,4,5]// 二乗を定義constsquare=(item)=>{returnitem*item}// squared は query の square (二乗) であるという宣言constsquared=query.map(square)

上記の例では、まず『二乗自体の定義』を行っている。
次に、『squaredはqueryの各要素を二乗にしたもの』という宣言をしている。

これまでの説明に出てきたような『操作の積み重ね』によって結果が得られる命令的なスタイルは、「どうやって値を得るか」を記述するが、この例のような宣言的なスタイルは「どんな値か」に注目して記述するため理解しやすく間違いが起きにくい。

Vue.js

Vue.js (https://jp.vuejs.org/index.html) は Webアプリケーションにおいて View に相当するレイヤーを担当するライブラリー。
前の章で、責任の分離の例を示したが、そこにおける表示の更新などをやってくれる。
この仕組みを利用することで、開発者は状態の変更などのロジックに集中できる。

簡単な例を示すために前の章で作成したカウンターボタンを Vue.js を使って記述してみる。

See the Pen JS Step3-4-Vue by sterashima78 (@sterashima78) on CodePen.

HTMLに特別な属性を付与することで状態と表示やイベントと処理の関連付けができる。
ここでは v-text@clickと使っている。
v-textは状態を対象DOMのテキストの表示に関連付けしている。状態が変われば Vue によって表示の更新をしてくれる。
@clickはクリックイベントと処理を関連付けしている。ここでは、クリックをすれば incrementが呼ばれて状態が更新される。
このようにHTMLでの宣言によってイベントの登録・UI更新が実現できる。

他にも Vue には宣言的にプログラミングをするための機能がある。
例えば、ボタンに表示するテキストを 「3 回」のような文言に変更したいとする。
Vue.js の機能を効果的に使うと以下のように修正して実現できる。

See the Pen JS Step3-4-Vue-1 by sterashima78 (@sterashima78) on CodePen.

computedという新しい属性が追加されている。computeddataつまり、アプリケーションの状態から算出される別の値を定義する。
ここでは、アプリケーションの状態である countから算出されるボタンに表示するテキスト btnLabelを定義している。この値は countが更新されると自動的に更新される。

開発者は btnLabelとはどのような値かを宣言するだけでよく、値や表示の更新などを考慮しなくていい。

まとめ

  • 命令的なスタイルは結果が「操作の積み重ね」によって得られるので比較的誤りが発生しやすい
  • 宣言的なスタイルはある値の定義を中心に記述するため比較的誤りが発生しにくい
  • Vue.js は状態の変更に伴う表示の更新を行ってくれる
  • Vue.js は状態から算出される別の値を定義することで、それらの更新を自動で行ってくれる。これを利用することで宣言的なプログラミングがしやすくなる

プラクティス

  • 前章で作成したサンプルアプリケーションを Vue.js を用いて実装せよ

サンプルアプリケーションの作成・比較

ここまで、Webアプリケーションを構築する上で、状態と表示を分離させることや、宣言的なプログラミングスタイルが有効であることを説明してきた。
そして Vue.js がこれらを考える上で有効であることを紹介した。
ここでは、以下の三種類の簡単なTODOアプリケーションを示す。

  • 責任が分離できてないアプリケーション
  • 責任を分離したアプリケーション
  • Vue.jsを用いて責任を分離したアプリケーション

これらの例を比較することで、ここまで説明したことの効果を実感するとともに Vue.js を利用することで比較的簡単に実現できることを示す。

責任の分離を意識しない例

仕様を考えながら作っているとこんな感じになりがちなのではないか。
これくらいのサイズであれば、上から順番に読んで行けばわからないこともないがそれなりにストレスが貯まると思う。
余力があれば章末の「プラクティス」を実施し、この状態のコードの拡張を試みてほしい。
(レガシーなシステムであれば平気でこれくらいのコードが製品として今も可動していることも多い)

See the Pen 責任分離をしないTODO by sterashima78 (@sterashima78) on CodePen.

責任の分離を意識した例

責任の分離を意識した例を以下に示す。
ただし、パフォーマンスなどの面で問題があるため、プロダクトコードとしては利用を避けるのが無難と考えられる。
パフォーマンスについて、ここでは説明しない。

見通しの良さなどもあるが、単体テストを書こうとしたときの書きやすさが段違いに変わってくるので、そのあたりも考えてみてほしい。

See the Pen 責任分離をしたTODO by sterashima78 (@sterashima78) on CodePen.

責任の分離を意識しVue.jsを用いた例

記述がより簡潔になったことが理解できると思う。
これは、値の監視と状態の更新、そして、状態の更新と表示の更新を Vue が吸収してくれているため。
なお、Vue.js の機能を利用すればより簡潔な記述も可能だが、あえて対比しやすい記述にしている。

See the Pen 責任分離をして Vue.js を使った TODO by sterashima78 (@sterashima78) on CodePen.

まとめ

  • ある程度複雑なアプリケーションでも責任の分離を意識することでより保守性の高いソフトウェアになる
    • この点については、何を使うかではなく、どう考え、どう作るかが大切
  • Vue.js を利用することで、値の更新など命令的に記述しなくてはならない箇所が吸収され、より宣言的にプログラミングができる

プラクティス

  • 「責任の分離を意識しない例」, 「責任の分離を意識した例」, 「責任の分離を意識しVue.jsを用いた例」 それぞれに対して以下の機能を追加し、拡張の容易性などを比較せよ
    • 特定のTODOを削除するボタン
    • 完了した (isDone == true) TODO をすべて削除するボタン
    • 全TODO表示と未完了TODOのみ表示を切り替えるようなチェックボックス

Vue.js を利用することで発生する問題点

何事にも問題点はあり、Vue.js についても当然いくつかあるのだが、ここではわかりやすい一点についてフォーカスしたい。

問題点: "this" への依存

責任の分離について説明した章では、それぞれの責任が依存するもの(状態など)は関数の引数として注入できるようにしていた。
これによってテストが容易になったり、再利用や拡張が簡単になるという利点を説明した。

しかし、Vue.js は状態や処理は JavaScript の特別なオブジェクト thisを経由して行われている。これによって試験などが難しくなっている。
この点について詳細な説明は避けるが、テストのときには this で参照される値を適切に変更することが必要になる。
以下は、先の例に出てきた increment, btnLabelのテストコードの例。optionsVueコンストラクタに渡していたオブジェクトだと思ってほしい。

/**
 * increment の試験
 * インクリメントされる (1 -> 2)
 */conststate1={count:1}options.methods.increment.bind(state1).call()if(state1.count==2){counsole.log("OK: test increment1")}else{thrownewError("Fail: test increment1");}/**
 * btnLabel の試験
 * インクリメントされる (1 -> 2)
 */conststate10={count:10}constlabel=options.computed.btnLabel.bind(state10).call()if(label=="10 回"){counsole.log("OK: test btnLabel")}else{thrownewError("Fail: test btnLabel");}

Vue.js によって宣言的にプログラミングをすることができるようになったが、状態や処理が thisを介して密に結合するようになってしまった。

composition-api

composition-api (https://vue-composition-api-rfc.netlify.com/) は 2020の1Qにリリース予定となっている新しいバージョンの Vue で採用予定のAPI。現在はプラグインとして提供されており、既に利用することができる。

composition-api を利用することで、thisに依存することを回避することができる。また、関連する状態や処理をひとまとまりに定義することができ、試験や再利用がしやすくなる。

以下は、前の章で作成したTODOアプリケーションを composition-api を用いて実装したもの。

See the Pen 責任分離をして Vue.js と composition-api を使った TODO by sterashima78 (@sterashima78) on CodePen.

ここでは、新しいTODOを追加するためのフォームとTODOに関連する状態や操作をそれぞれ useTextFormuseTodoに分離した。
状態とそれを変更する処理が関数に分離されたので、テストがしやすくなっている。
また、依存する値があれば引数で注入するようになっているので、これもテストの容易性を高めることに寄与している。

例えば、 useTextFormの試験は以下のように書ける。

const{input,isInputted,clear}=useTextForm("init")if(input.value=="init"){console.log("OK: init")}else{thrownewError("Fail: init")}if(isInputted.value){console.log("OK: isInputted")}else{thrownewError("Fail: isInputted")}clear()if(isInputted.value){thrownewError("Fail: clear")}else{console.log("OK: clear")}

まとめ

  • Vue.js の既存の API は this依存しているためテストが難しくなるなどの側面がある
  • composition-api は機能ごとの責任分割を容易にし、再利用性やテストの容易性を高めることに寄与する

プラクティス

  • 前章のプラクティスで機能追加したTODOアプリケーションを composition-api を使って実装せよ

終わりに

非常に駆け足になったが、Webでのインタラクティブなアプリケーションを作成する方法、よりよいソフトウェアを書く方法、Vue.js を利用した宣言的なプログラミングをする方法、そして、よりモジュール性を高めるための composition-api について説明をした。

技術は利用するだけでも一定の効果を見込めることもあるが、重要なのはその技術がどのような特徴を持つか、なぜそのような特徴が有効なのかを理解して用いることと考えている。
本文書が、効果的に技術を利用することに寄与できれば嬉しい。

また、冒頭にも記載したが Vue.js の特徴であるカスタムコンポーネントについて記述できなかった。特に Vue.js で特徴てきな SFC に触れようと思うとどうしても webpack などのツールチェーンに触れる必要があるため断念した。SFC 触れずにコンポーネントシステムについての記事をいずれ作成したいと考えている。

CSS3で除夜の鐘を作った話

$
0
0

理由

  • CSSアニメーションで遊びたかったため
  • 煩悩APIという面白いものをみつけたため
  • 年末で暇していたため

作り方

 鐘を撞いて煩悩をカウントアップしていくことを目標としていました。実際は鐘を撞くところまでしか完成していません。理由は末尾のCodePenに全て書いてあります。

まず鐘を作ります。

<divclass="bell"></div>
@keyframesring{0%{transform:rotate(0deg);}25%{transform:rotate(5deg);}75%{transform:rotate(-5deg);}100%{transform:rotate(0deg);}}
.bell{height:200px;width:150px;background-color:#444;margin-top:100px;margin-left:100px;border-radius:100px100px100px100px/75px75px5px5px;transform-origin:centertop;animation:ring1slinear2s;}

これで鳴るようになりました。

次に撞くものを作ります。

<divclass="stick"><divclass="torso"></div><divclass="upper"></div><divclass="lower"></div></div>
@keyframeskick{0%{margin-top:-500px;margin-left:500px;transform:scale(2);}40%{margin-top:-200px;margin-left:200px;transform:scale(1);}60%{margin-top:-200px;margin-left:200px;transform:scale(1);}100%{margin-top:-500px;margin-left:500px;transform:scale(2);}}
.torso{width:50px;height:50px;background:#000;border-radius:25px;position:relative;}.torso:before{content:"";display:block;width:10px;height:75px;background:#000;top:50px;left:20px;position:absolute;}.upper{width:10px;height:50px;background:#000;position:relative;margin-left:20px;transform-origin:centertop;transform:rotate(60deg);}.upper:before{content:"";display:block;width:10px;height:30px;background:#000;position:absolute;transform-origin:centertop;transform:rotate(-150deg);}.upper:after{content:"";display:block;width:10px;height:30px;background:#000;left:25px;position:absolute;transform-origin:centertop;transform:rotate(-200deg);}.lower{width:10px;height:50px;background:#000;position:relative;margin-left:20px;margin-top:25px;transform-origin:centertop;transform:rotate(20deg);}.lower:before{content:"";display:block;width:10px;height:30px;background:#000;position:absolute;transform-origin:centertop;transform:rotate(-100deg);}.lower:after{content:"";display:block;width:10px;height:30px;background:#000;left:30px;position:absolute;transform-origin:centertop;transform:rotate(30deg);}.stick{transform-origin:leftbottom;transform:rotate(30deg);margin-top:-500px;margin-left:500px;animation:kick5slinear;}

これで撞けるようになりました。

結果

See the Pen Joya bell by mnmtmym (@mnmtmym) on CodePen.

改良の余地しかないですので、これをベースに好みの除夜の鐘を作り上げましょう!!

【CSS】背景画像を複数枚重ねてレスポンシブに対応させる

$
0
0

Webページの背景画像で、一部の画像だけ形を崩さずにディスプレイサイズに対応させる方法です。

やりたかったこと

2.png
最初はこのような1枚画像を用意して、ブラウザサイズに合わせて画像を変えようとしました。
が、ディスプレイサイズに合わせて縮小させると波線形状部分の形が崩れるし、画像固定にしてしまうと手前の波線画像の一部しか見えず型崩れ(あるいは画面の8割を締める)・・・など問題が出て来たので、手前の波線形状の画像だけ、常に形を崩さず最下部に表示できるにしました。

1.png3.png

ディスプレイの横幅が変わっても、波線形状だけは形を崩さず、画面下部にいるようにします。

やり方

一番奥の背景画像(desktop1.jpg)、手前の波線画像(cover1.png)をそれぞれに用意。

    body{
    background: url(./img/cover1.png),url(./img/desktop1.jpg);
    background-repeat: no-repeat,no-repeat;
    background-position: bottom,top;
    background-size: contain,cover;
    background-attachment: fixed,fixed;
    }

background-sizeを背景画像はcoverにし、隙間が生まれないように。
波線画像はcontainにすることで、常に画像の全体が見えるようにしました。

【初心者向け】超簡単なぐるぐる回るローディングアニメーションCSS

$
0
0

はじめに

どうも、よわよわエンジニアです。
大晦日だというのになぜかQiitaを執筆する異常者です。
さて、今回はみなさん一度は目にしたことがある読み込み中のアレについて解説します。

今回作るもの

ローディング中のこれ↓
スクリーンショット 2019-12-31 1.59.14.png

よくみかけるコレですが、
実は結構簡単にhtmlとcssで実装できちゃいます。
今回はアレンジしやすいように1個ずつ解説入りで説明したいと思いますので、
よければ手を動かしながら読んでください。

実装

まずは背景の黒画面、そしてぐるぐるを真ん中に持ってくる記述から行きます。
コメントは全て//で書きますので、コピペされる方は取り除いてあげてください。

htmlの構成は以下の通り

test.html
<!DOCTYPE html><htmllang="ja">  //日本語設定
<head><metacharset="UTF-8">  //文字化け防止のおまじない
  <metaname="viewport"content="width=device-width, initial-scale=1.0"> //レスポンシブ対応のおまじない
  <title>Test</title> //タイトル
  <linkrel="stylesheet"type="text/css"href="style.css"></link> //css読み込みの宣言
</head><body><divclass="container"> //背景
    <divclass="loader"></div> //例のぐるぐる
    <p>Now loading...</p> //ぐるぐる下の文字
  </div></body></html>

で、次にcssです。
現状はただの真っ黒い画面にしかならないとおもいますが、
ぐるぐるとNow loading...のもじが画面中央に配置さるよう設定しておきます。

style.css
body{margin:0;//ブラウザ固有の余白を消します。padding:0; //同上box-sizing:border-box; //余白のとりかたを指定。width:100vw; //表示画面の大きさを決めます。height:100vh; //同上}.container{background-color:black; //背景色width:100%; //横幅を画面いっぱいに指定height:100%; //縦幅を・・・同上display:flex; //flexBoxでレイアウト制御します。justify-content:center; //左右中央に指定align-items:center; //上下中央に指定flex-direction:column; //ぐるぐると文字を縦並びにする指定}

ぐるぐる本体作成

以下を先ほどの記述の下に追加してください。
解説はこのあとすぐ!

style.css
.loader{border:12pxsolid#fafafa; //12pxの白い四角をつくりますborder-radius:50%; //作った四角の角を丸めますwidth:100px; //ぐるぐるの大きさを決めますheight:100px; //ぐるぐるの大きさを決めます}p{color:#fafafa; //これはNowloading...の色指定なのでぐるぐるとはあまり関係ない}

解説

border: 12px solid #fafafa;
枠線を記述しています。
12pxの1本線で色が#fafafaだよって意味です。

border-radius: 50%;
先ほどの枠線の角をどれだけ丸めるか?っていう記述です。
丸にしたけりゃ問答無用で50%だと覚えておけばいいでしょう。

width: 100px
ぐるぐるの横幅をきめています。

height: 100px
ぐるぐるの縦幅をきめています。

さて、この時点で
スクリーンショット 2019-12-31 2.24.31.png

こうなってたら成功です。
なんかそれっぽいですね!!!!

色付け

では、先ほどのものに色付けをしていきましょう。
色付けは実は超簡単。以下の一文を追加してください。

style.css
.loader{border:12pxsolid#fafafa;border-radius:50%;border-top:12pxsolid#3498db;//これを追加!!width:100px;height:100px;}

解説

border-top: 12px solid #3498db
ぐるぐるの上部に#3498dbという色のバーを追加するよという意味です。
注意!!このとき、boaderの大きさとborder-topの大きさは必ず同じにしてください。
今回なら12pxで揃えています。
スクリーンショット 2019-12-31 1.59.14.png
こうなっていたら成功です。

アニメーションの追加

ここまできたらあとはアニメーションを追加して終わりです。
あと一歩なんで、頑張って実装しましょう。

style.css
.loader{border:12pxsolid#fafafa;border-radius:50%;border-top:12pxsolid#3498db;width:100px;height:100px;animation:spin1slinearinfinite;//これを追加!!!}@keyframesspin{0%{transform:rotate(0deg);//アニメーション開始時にどういう状態か?}100%{transform:rotate(360deg); //アニメーション終了時にどういう状態か?}}

解説

animation: spin 1s linear infinite;
animation: 任意の名前何秒でアニメーションするかアニメーションの進行度無限ループするか?
という感じで記述をしていきます。

linearとは、一定のスピードで動きますよーという意味です。
ここを、ease-inや ease-out にしてみてください。
開始が遅くて終了間際に早くなったり、その逆になったりと面白い変化が見られます。

@keyframes spin
これは先ほどつけた任意の名前に具体的にどういうアニメーションをつけるかという
アニメーションの設定みたいな記述です。

今回だと、0%のときに
rotate(0deg)と記述しているので、
アニメーション開始時には回転させない(0度地点にいる)という記述です。
そして、100%のときに
rotate(360deg)と記述しているので、
アニメーション終了時には360度回転した場所にいるよ。という意味です。

これをinfiniteで無限ループさせることでぐるぐる回っているように見えます。

Image from Gyazo

こんな感じになったでしょうか??

いざアレンジ

ここまでで、解説自体は終了なんですが、
ここにアレンジを加えてみましょう。
自分だけのローディングアニメーションが完成します。

例その1

Image from Gyazo

THE定番の薄くなったりするアレです。
コードは以下の通り。

style.css
.loader{border:12pxsolid#fafafa;border-radius:50%;border-top:12pxsolid#000;//バーの色を背景色と同じにwidth:100px;height:100px;animation:spin1slinearinfinite;}@keyframesspin{0%{transform:rotate(0deg);opacity:1; //透明度を100%}65%{transform:rotate(180deg); //開始から65%の段階で半回転(180deg)する。さらに透明度を40%に設定opacity:0.4;}100%{transform:rotate(360deg);opacity:1;}}

変更点は上記のコメントつけているところだけです。
これで、アニメーション開始時から65%たったタイミングでバーが真下にくるようになるので、
ゆったり始まって、さっと終わるアニメーションができます。
さらに、opacityの設定をしてあげることで、半透明になります。

例その2

Image from Gyazo

サイズと色が可変するあれです。
通常のローディング画面より「なんかかっこいい」ですね。
コード以下のとおり

style.css
.loader{border:15pxsolid#39d4ff;//border-topは削除border-radius:50%;width:100px;height:100px;animation:spin2slinearinfinite;  //スピード遅く}@keyframesspin{0%{transform:rotate(0deg);}50%{                //50%に変更transform:rotate(180deg);border-radius:0%;      //四角にするwidth:20px;         //小さくするheight:20px;        //同上border:5pxdouble#061fd5; //ぐるぐるの線を二重線にし、細くしてくる}100%{transform:rotate(360deg);}}

可変型なので、50%の段階で可変cssをしこたま仕込みました。
これで、大きさが可変するので、別途文字は固定してあります。

最後に

いかがだったでしょうか?
普段は見かけたらイラっとするローディング画面でも、自分で作るとなると愛着沸きませんか?
htmlとcssだけでこんなに簡単にローディングアニメーションが実装できます。
なんかワクワクが止まりませんね!

CSSってかなり奥が深くて、知れば知るほどおもしろいです!
ぜひ、知る!という快感を味わってみて、アレンジして自分のページをかっこよくしてみてください!

ひとり開発時の備忘録

初心者によるプログラミング学習ログ 199日目

$
0
0

100日チャレンジの199日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

199日目は

JavaScriptでロード画面を作る

$
0
0

JavaScript勉強中、「文字にアニメーションをつける」解説動画を見つけたので、ロード画面として作ってみました。

Demoページ

https://kngy0306.github.io/Loading/

コード

html

<body><!-- ロード画面 --><divclass="init"><h1class="loading">Now Loading...</h1></div><!-- ロード後の画面 --><divclass="main">    <h1>メイン画面</h1>  </div></body>

css

*{padding:0;margin:0;}.init{background:black;width:100%;height:100vh;position:fixed;}.inith1{color:#ecf0f1;text-align:center;line-height:100vh;font-size:3em;}span{transition:all.3s;}.coloring{color:#812990;}.fadeout{animation:fadeOut2s;}@keyframesfadeOut{0%{opacity:1;}100%{opacity:0;}}

javascript

// ロード中、表示する文字一つ一つに<span>をつけるconsttext=document.querySelector('.loading');conststrText=text.textContent;constsplitText=strText.split("");text.textContent='';for(leti=0;i<splitText.length;i++){text.innerHTML+="<span>"+splitText[i]+"</span>";}// 160ミリ秒ごとspanにcoloringクラスを加えるletchar=0;lettimer=setInterval(setFade,160);functionsetFade(){constspan=text.querySelectorAll('span')[char];span.classList.add('coloring');char++;// 最後の文字に到達したら二つの関数を呼び出すif(char===splitText.length){finish();fadeOut();}}functionfinish(){clearInterval(timer);timer=null;}// ロード画面を作るdivにfadeoutクラスを加えるfunctionfadeOut(){constinit=document.querySelector('.init');init.classList.add('fadeout');// 2秒後にdisplay: none;を加えるsetTimeout(function(){init.style.display='none';},2000);}

年末まで毎日webサイトを作り続ける大学生 〜74日目 オセロ【最終日】~

$
0
0

はじめに

こんにちは!@70days_jsです。
今日はオセロを作りました。
自動で駒を返す機能はつけられませんでしたが、手動で駒を返したり外したりできるようにしました。(gif)↓
test3.gif
今日は74日目。最終日です。(2019/12/31)
よろしくお願いします。

サイトURL

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

やったこと

オセロを作りました。
自動で駒を返す機能はつけられませんでした。その代わり手動で駒を返したり外したりできるようにしました。

html↓

<body><h1>Othello</h1><divid="gameBoard"></div><div>click: put a Piece alternately / dbClick: delete a Piece</div></body>

css↓

body{margin:0;display:flex;justify-content:center;align-items:center;flex-direction:column;background-color:black;color:white;}#gameBoard{display:flex;justify-content:center;align-items:center;}.oneBlock{background-color:rgba(0,250,0,0.5);height:50px;width:50px;border-right:solid1pxblack;border-bottom:solid1pxblack;display:flex;justify-content:center;align-items:center;background-size:cover;cursor:pointer;}.oneBlock:hover{background-color:rgba(0,250,0,0.8);}.black{background-image:url(day74_black.png);}.white{background-image:url(day74_white.png);}

駒は画像で表現しています。
.blackクラスが黒で、.whiteクラスが白の駒です。

JavaScript↓

letgameboard=document.getElementById("gameBoard"),N=8,nowPlayer="white",black="black",white="white",divList=[];for(vary=0;y<N;y++){letwrapper=document.createElement("div");for(varx=0;x<N;x++){letdiv=document.createElement("div");div.setAttribute("id",String(y)+String(x));div.classList.add("oneBlock");if(y==N/2&&x==N/2)div.classList.add("white");if(y==N/2-1&&x==N/2-1)div.classList.add("white");if(y==N/2&&x==N/2-1)div.classList.add("black");if(y==N/2-1&&x==N/2)div.classList.add("black");divList.push(div);wrapper.appendChild(div);gameboard.appendChild(wrapper);}}functionchange(player){letp=player==black?white:black;nowPlayer=p;returnp;}for(vari=0;i<divList.length;i++){divList[i].addEventListener("click",function(e){if(e.target.classList.contains("white")){e.target.classList.remove("white");e.target.classList.add("black");}elseif(e.target.classList.contains("black")){e.target.classList.remove("black");e.target.classList.add("white");}else{change(nowPlayer);e.target.classList.add(nowPlayer);}});}for(vari=0;i<divList.length;i++){divList[i].addEventListener("dblclick",function(e){if(e.target.classList.contains("white"))e.target.classList.remove("white");if(e.target.classList.contains("black"))e.target.classList.remove("black");});}

まずfor文で盤面を作っています。

for (var y = 0; y < N; y++) {
for (var x = 0; x < N; x++) {...}
}

change関数で打ち手の順番を判断しています。

function change(player) {
let p = player == black ? white : black;//三項演算子
nowPlayer = p;
return p;
}

盤面はそれぞれdivでできているので、イベントリスナーをつけていきます。

for (var i = 0; i < divList.length; i++) {
divList[i].addEventListener("click", function(e) {...}
}

.blackクラス、whiteクラスをつけたり外したりすることで駒を置いたり置き換えたりしています。

もう一つ、このオセロは置ける場所を自動で探してくれる機能がないので、間違った場所に置いてしまう可能性があります。その対策として、ダブルクリックで駒を消す関数を用意しておきます。

for (var i = 0; i < divList.length; i++) {
divList[i].addEventListener("dblclick", function(e) {...}
}

これで完成です。

謝辞

最後まで読んでいただきありがとうございます。
今までありがとうございました。
いいねやコメントとても嬉しかったです。

途中何度もやめようかと思いましたが、最後までやり切れたのは皆様が暖かく見守ってくださったお陰です。
本当にありがとうございます。

最後にオセロのロジックを組みきれなかったことはとても悔しいですが、今後も自分のペースで焦らず楽しくやっていこうと思います。

そういえば、一日目にはこんなこと言ってたんですね。 笑↓

情報系の学部にいながらwebサイトの1つもパパッと作れない男。
意識高いけど実力が伴っていない男。
そんな現状に嫌気がさして、年末まで1日1つwebサイトを作ることを決めた男。
扱う技術レベルは低いですが、同じように悩んでる初心者の方の参考になれば幸いです。
今日は1日目。
よろしくお願いします。

恥ずかしい。 笑
でもこれをみて思ったことは、いつの間にか心持ちが変わってるなあということです。
毎日続けて知識や技術力はもちろん向上したんですが、なんというか、それよりも変な焦りがいつの間にか消えていました。

続けてみたメリットって、意外とこれが大きかったなぁと感じました。

というわけで焦ってる人! 2ヶ月半サイトを作り続けてみませんか?笑

えー、長くなってしまいましたが、今まで本当にありがとうございました。
またどこかでお会いしましょう!

参考

  1. アイコン素材ダウンロードサイト「icooon-mono」 | 商用利用可能なアイコン素材が無料(フリー)ダウンロードできるサイト | 6000個以上のアイコン素材を無料でダウンロードできるサイト ICOOON MONO

アイコンを使用させていただきました。ありがとうございます!

初心者によるプログラミング学習ログ 200日目

$
0
0

100日チャレンジの200日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

200日目は

HTML要素をドラッグで動かす

$
0
0

See the Pen MovableElement by Yoshiharu (@yoshiharu2580) on CodePen.

interfaceElementPosition{top:number;left:number;}interfacePointerPosition{x:number|null;y:number|null;}classMovableElement{// Elementオブジェクトprivateelement:HTMLElement;// 要素の初期位置privateelementInitialPosition:ElementPosition;// 要素の動き始めの位置privateelementStartPosition:ElementPosition;// ポインタ-の動き始めの位置privatepointerStartPosition:PointerPosition={x:null,y:null};constructor(id:string){this.element=document.getElementById(id);this.elementInitialPosition=this.getCurrentPosition();this.element.addEventListener("mousedown",(event:MouseEvent)=>{this.elementStartPosition=this.getCurrentPosition();this.pointerStartPosition.x=event.clientX;this.pointerStartPosition.y=event.clientY;});this.element.addEventListener("mousemove",(event:MouseEvent)=>{if(this.pointerStartPosition.x===null||this.pointerStartPosition.y===null){return;}constpointerMovingDistanceX=event.clientX-this.pointerStartPosition.x;constpointerMovingDistanceY=event.clientY-this.pointerStartPosition.y;this.changeTranslate(pointerMovingDistanceX,pointerMovingDistanceY);});window.addEventListener("mouseup",()=>{this.resetPointerStartPosition();});this.element.addEventListener("mouseleave",()=>{this.resetPointerStartPosition();});}// 要素の位置を取得するgetCurrentPosition():ElementPosition{const{top,left}=this.element.getBoundingClientRect();return{top,left};}// 要素の位置を移動するchangeTranslate(movingDistanceX:number,movingDistanceY:number){constx=this.elementStartPosition.left-this.elementInitialPosition.left+movingDistanceX;consty=this.elementStartPosition.top-this.elementInitialPosition.top+movingDistanceY;this.element.style.transform=`translate(${x}px, ${y}px)`;}// ポインターの動き始めの位置をリセットresetPointerStartPosition(){if(this.pointerStartPosition.x===null||this.pointerStartPosition.y===null){return;}this.pointerStartPosition.x=null;this.pointerStartPosition.y=null;}}newMovableElement("element");

初心者によるプログラミング学習ログ 201日目

$
0
0

100日チャレンジの201日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

201日目は

[Rails][bootstrap]css→SCSSへ変更する方法

$
0
0

Bootstrapのロジック整理のため投稿です。
CSS→SCSS(Sass)への変更方法についてまとめていきます。

rails new

の直後では、デフォルトでapp/assets/stylesheets/application.cssが読み込まれる仕様になっています。

そこで手順は、以下の流れになりそうです。

①app/assets/stylesheets/application.css を削除
②app/assets/stylesheets/application.scssを作成
③Gemfileにbootstrapを追加→bundle install
④app/assets/stylesheets/application.scssにインポート

具体的に見て行きましょう!

①app/assets/stylesheets/application.css を削除

$ rm app/assets/stylesheets/application.css

②app/assets/stylesheets/application.scssを作成

③Gemfileにbootstrapを追加→bundle install

Gemfile.
  gem 'bootstrap'
$ bundle install

④app/assets/stylesheets/application.scssにインポート

application.scss
@import"bootstrap";
Viewing all 8767 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>