20200414のCSSに関する記事は16件です。

HTML / CSS から Nuxt.js で webアプリを開発するまでのロードマップ

はじめに

この記事では、HTML / CSS から学び、Nuxt.js で webアプリを開発するまでの過程を紹介します。

本記事は、以下のような方が対象です。同じ初学者を意識しています。

  1. web開発に興味がある。
  2. HTML / CSS を学んだが、そこからどうすれば良いか謎。不可思議。
  3. フレームワークとは何ぞや。フレームワークのフレームワーク?
  4. どこまでやれば、どういうものができるのか具体的に知りたい。
  5. とりあえず、web開発に興味はあるよ。

その道の方でも、「趣味で学ぼうとする人は、こういう学び方をしているんだな」と参考になるかもしれません。

筆者であるうたかたは、web開発を始めて早2ヶ月ですが、わからないことでいっぱいです。基本的に表面的な理解に終始しています。ただ「初学者でも、今あるものを使うと、こういうものができるよ」という具体例とその学習過程を紹介することで、何か少しでもお役に立てたらと思います。Qiita も利用し始めたばかりなので、何かありましたら色々とご指摘いただけると助かります。

開発中の音楽SNS「UTAKATA」の紹介・解説動画を YouTube に投稿しているので、「この記事で紹介しているもの(Vue.js・Vuetify.js・Nuxt.js・Firebase)を学ぶと、少なくともこういう webアプリを作ることができるよ」という具体例として参考にしていただければと思います。近日中にベータ版(?)を公開する予定です。

最後に、本記事は各言語・フレームワークについて詳細な解説をするものではありません。「何を学べば良いかわからない」「何を学べば、何ができるかわからない」という方に、一つの指針を提供することが目的です。

少し前置きが長くなりましたが、最後までお読みいただけると嬉しいです。

ロードマップ

これまでの学習の軌跡を振り返りつつ、web開発のロードマップを紹介します。

学習の流れは、HTML / CSS → JavaScript → Vue.js & Firebase → Vuetify.js → Nuxt.js でした。

学習期間と内容は、概ね以下の通りです。

  • 前半(1ヶ月):HTML / CSS / JavaScript の基本を学び、その後何を学べば良いか調べてた。もはや「web開発」とは何ぞや状態。そして今も。
  • 後半(1ヶ月):Vue.js → Firebase → Vuetify.js → Nuxt.js の存在を辿り、動画を見て、公式ドキュメントを見ながらコードを書いた。

主に前半は The Net Ninja さんの動画(YouTube & Udemy)、後半は公式ドキュメントを頼りにしています。

The Net Ninja さんについては、偶然見つけただけで、特に深い理由はありません。運命の出会いでした。英語ですが、とてもわかりやすいです。このわかりやすさに慣れると、少しつらいものもあります。ストリートファイターの春麗(Chun Li)が好きみたい。マリオも出てくる。ほぼ全て無料で見ることができるのには、感謝しかないです。謝謝。

「どこまでやれば、どういうものができるのか」が想像もできなかったので、一度動画を(コードを書かないで)見るだけみて、Nuxt.js に行き着いてから、公式ドキュメントを参照しつつ、コードを書き始めました。

この記事を参考にする場合も、一度最後まで読み通して見通しをつけてから、各言語・フレームワークを学習し始めると良いと思います。知らない用語が出ても、「そういうものがあるんだね」と思って進んでください。知らないことばかりですもん。

学習項目は以下の通りです。

  • HTML
  • CSS
  • JavaScript
  • Vue.js:JavaScript のフレームワーク。
  • Vuetify.js:Vue.js のデザイン担当。
  • Nuxt.js:Vue.js の開発環境・機能強化担当。
  • Firebase:ユーザー認証(登録・ログイン)やデータベースを管理。

1. HTML / CSS

自分は「Flexbox とは何ぞや」という人間だったので、以下の動画も見ました。あとで紹介する Vuetify.js で採用されている Grid システムをそのまま理解することができます。

動画が洗練されていくのを肌で感じることができるのは、複数見た人の特権です。

今回紹介している動画は有料(Udemy)2つを含みますが、それ以外はほぼ全て無料なので、ぜひ覗いてみてください。

最近では、Firebase Functions に関するシリーズ(無料)が投稿されていたようです。まだ見ていませんが、きっと参考になると思います。

2. JavaScript

フルバージョンは Udemy(有料) で公開されています。動画の説明欄にクーポン付きのリンクがあるので、そちらからご利用ください。

基本的な文法(「こうやって書くよ」)・関数(「こういうことがしたい時、こういう機能があるよ」)・概念(「こういう考え方で、コードを組み立てるよ」)を一通り学ぶことができます。

学習の指針としては、動画を見て基本的な概念を理解しつつ、文法・関数(の存在)を何となく知っておきます。実際にコードを書く段階で、その関数名やしたいことで検索して、例を見ながら書きます。「検索できるようになる」こと、そして「書かれている内容を理解できるようになる」ことが大事だと思います。全てのコードを覚えておく必要はありません。未だに何でも調べてます。

この後も基本的に、動画を見て何となく理解する → ドキュメントを参照してコードを書くという流れです。

3. Vue.js & Firebase

Udemy(有料)で公開されている動画の紹介動画です。動画の説明欄にクーポン付きのリンクがあるので、そちらからご利用ください。

web開発を学ぶのにかけた費用は、以上の動画2つ分(約2400円)です。
安いと思います。感謝しかないです。

Vuex については、以下の動画(無料)を参考にしました。

Vue については、以下のサイトも参考になりました。Vuex についての記事を載せておきます。目を通せてはいないですが、初学者にも、とてもわかりやすい解説です。謝謝。

一応、Firebase [Firestore/Storage] セキュリティルールの具体例を以下の記事で紹介しています。とても参考になったブログ・記事についても触れているので、いつの日か覗いてみてください。喜びます。

4. Vuetify.js

使用しているコンポーネント(デザインを形作るパーツ。Buttonコンポーネントなど)や使い方が古い場合もありましたが、コメント欄で有志により全て補足されていました。

コードを書くときには公式ドキュメントの例を見ながら書くので、まずは動画で雰囲気を掴めれば良いと思います。その点で、とても参考になりました。

5. Nuxt.js

存在は Vuetify.js の公式ドキュメントで知りました。

Nuxt.js については、はじめから公式ドキュメントのガイドに沿って何となく理解していきました。一応、Vue School の動画も見たと思います。

Vue.js・Vuetify.js・Nuxt.js・Firebase は、いずれも日本語の公式ドキュメントが充実しているので、動画を見て雰囲気を掴んだら、そのまま公式ドキュメントを読むと何となく理解できます。どんなにわかりやすいサイトがあっても、参照しているのは最終的に公式ドキュメントのはずなので、それを読むことで安心感を得るのです。公式ドキュメントのわかりにくいところは、検索すれば先人が知恵を貸してくれます。

おわりに

この記事では、HTML / CSS から学び、Nuxt.js で webアプリを開発するまでの過程を紹介してきました。

「何があるかわからない」「何から手をつけていいかわからない」という方の参考になれたら幸いです。

web開発を学ぶ上で、数多くのサイト・記事を参考にさせていただいています。本記事では全て列挙することはできませんが、この場を借りてお礼申し上げます。いつもありがとう。謝謝。

趣味で NCS 等の和訳を YouTube に投稿しているので、よければそちらもご覧ください。
YouTube チャンネル:うたかた / UTAKATA

少し長くなりましたが、ここまで読んでいただきありがとうございました。ではでは!

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

HTML、CSSで忘れそうだけど押さえておきたいこと

CSS

HTMLと別のファイルで書くのが基本。しかしHTMLの要素に直接書き込みこともある。例えば最初はdisplay:none;にしておく要素など。

<p style="display:none;">見えない</p>

大きさの単位

絶対的な大きさとしてpxが主流。しかしスマホの普及により、rem(html要素のフォントを1とした時の相対的な単位)を使用される

色は#FFFFFFやrgb(255,255,255)などの方法で表される。
カラーコードでぐぐるとわかる

idとclass

idは一度しか定義できず、CSSで読みだすときは#をつける。
classは複数回定義できるが、CSSで読みだすときは.をつける。またclassは複数所属可能なので、class = aaa bbbとしてやるとaaaとbbbに所属できる。

優先度

親要素でCSSの内容を記述し、子要素でもCSSの内容を記述したとき子要素の内容が優先される
同じ要素のidのCSSの内容とclassのCSSの内容ならば、idのCSSの内容が優先される

詳しくはCSSセレクタの優先度に関してググると良い

ボックスモデル

HTMLの要素はpadding border marginで囲まれている。
HTMLの要素自体の幅、高さをwidth、heightで表す

要素.jpg

またその要素に
box-sizing: border-box;
と指定すると、widthやheightをmarignまで含んだ時の大きさに設定することになる

インラインとブロック

ブロック要素

ブロックは画面の横幅全体を使い、次の要素は改行された状態になる。
例 h1~h6 p form table ul ol dl li div

text-alignやmarginをいじるやインラインブロックへの変更をすることでブロック要素は配置設定に使用できる(インライン要素は配置設定をしないのは基本。)

インライン要素

インラインは画面の横幅全体を使わず、次の要素は隣にくるようになる。
例 br a img input select textarea strong span

上述したがインライン要素は配置設定をしない。

そもそも下記なので配置設定できない。
・大きさ制限できない(width,height)
・marginできない(ホントは左右はできる)
・text-alignできない
・floatできない

またインライン要素の配置を変えたいならば、その要素に親要素を作り、そいつのtext-alignやmarginをいじるやインラインブロックへの変更をすることで配置設定をする。そのためインライン要素から別の要素への変換(display)をする機会はない。

インラインブロック要素

インラインブロックは基本的にブロック要素的な面が強いが、次の要素は隣にくるようになる。ブロック要素だけでは配置設定のバラエティーがなくなるので、ブロック要素からインラインブロック要素に変更することがある。ブロック→インラインブロックのパターンしかない。

重要

以上のことからわかることは
配置変更をしたければ、ブロック要素をいじることで行う。例えば、text-alignやmargin変更、インラインブロックへの変更で横に大きいの並べるとか

text-alignとmargin

私はtext-alignとmargin 0 autoが同じだと思っていた。でも違うのだ。

text-alignはその要素の幅の範囲内(width内)での文字の位置を指定している。つまり文字の位置を指定しているのである。

marginはその要素のmargin(余白)の部分を変更しているので、要素の幅(width)や高さ(height)の範囲には影響を与えない。

要するにtext-alignは要素の中での指定、marginは要素の外側での指定。

marginのあれこれ

同じ方面でmarginがかぶると、marginの相殺(margin同士の足し算ではなく、marginの大きい方を採用する)。marginの相殺と呼ぶ
margin 0 autoで中央ぞろえ
margin-left autoでベタッリ右

要素の真ん中に文字をおきたければ

要素の大きさ(幅や高さ)のwidthやheightで行う。要素の大きさを変えても要素内での文字の位置は変わらない。

要素内での文字の位置を変えたければ、text-align: center;で文字を幅でも高さでも真ん中に置くのかを決める。またline-heightで文字自体の高さを決めれるので、要素のheightとline-heightを同じにすることで、完璧に要素の真ん中にもじが来るようになる。

範囲指定

範囲を指定するためだけの要素

ブロックで範囲を指定するのがdiv(text-alignやmarginでいじって、指定範囲の位置指定)

インラインで範囲をしてするのがspan(特定の文字の色変更とかに使用)

background

backgroundを使用すると背景を変えれる。backgroundでの範囲はその要素のborderまでの範囲なので、余白をつけたければ,marginを使う。またrepeatを指定すると、永遠にその背景ってことになる。

img

imgはインライン要素なので、pで囲って無理やりブロックにして、配置指定をする。

position

配置指定でたまに使うのposition。こちらのサイトが非常にわかりやすかったです。CSSのpositionを総まとめ!absoluteやfixedの使い方は?

CSSの開発の仕方

BEMではclass名を長くして、名前が被らないように開発する。あとで書き直すときに書き直しやすい。Sassのおかげで書くのが楽になった。

OOCSSではオブジェクト志向でCSSを記述するので、一つの要素が複数のclassに所属している状態になる。配置や構造を示すclassとデザインを示すclassに所属するイメージ。デザインが一貫しているWEBを作りたいならこちらの様式でやる

Sass

@ mixin  名前A('引数') {
}

#名前B {
@include  名前A('引数')
}

//このようにcssをクラスのように扱えるようになる

参考文献はSCSSの基本的な書き方

HTML

<>で囲まれている部分を要素idやnameなどは属性という。

h1やpで囲んで記事を書くが、なくても文字は表示される

imgのalt属性は画像が表示されない時に出る文字、最近はSEOに必要な要素にもなっている?

ulは箇条書き(順序なし)、olは箇条書き(順序あり)、dlは説明って感じ(dlの中にdt(用語)、ddが用語の詳細説明)

表に関して。
まず

で表が作成できる準備をする

そいつの子要素としてtrで行をざっくり作る、trの中にthやtdを入れて行にマスを作っていくイメージ。thは見出し、tdは左寄せ。

bodyの構造。headerとfooterを頭とお尻に。その間の空間をarticleとして、その中に複数のsection(切りの良いところで、次のセクションに次の内容を書く)を置く。最近はSEO的にも重要だとか

form_tagとform_forの違い。モデルに対して操作を行うならば、form_forを使い、そうでないならばform_tagを使用する。詳しくはrailsで学ぶサーバーサイド

またform_tagでmethodを指定するが、postは見えない状態で、paramsの中に入れて運ぶ感じ。getではURLに?でクエリ(条件)を置いて、送信する。詳しくはrailsで学ぶサーバーサイド

<a>は外部のURLにアクセスするための要素
<%= link_to %>はアプリ内部のrootingにアクセスするために作られた関数

nameとid属性の違い
id属性はCSSやJSで使用する。nameはサーバーサイドでparamsから値を得る時に使用する。

viewでの注意

・お作法としてapplication.htmlには統一レイアウトを置き
yeildという場所を書き、そこに全てのviewの内容が反映される。

app/views/layouts/application.html.erb
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all',
                               'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application',
                               'data-turbolinks-track': 'reload' %>
    <%= render 'layouts/shim' %>
  </head>
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <%= yield %>
      <%= render 'layouts/footer' %>
    </div>
  </body>
</html>

同様に全てのviewは、別のviewファイルから読みだして自身のviewに反映させてもいい

<%= render '反映させたいviewの場所' %>
<%= render @microposts %>
#これをするとviewの中のmicroposts/_micropost.html.erbを追加することになる

これをパーシャルを追加するという。他にも

<%= render 'shared/error_messages', object: f.object %>
#これを行うとshared/error_messagesの方で、f.object(つまりf自身、入力内容自身)を変数objectと設定してパーシャリ川で使用できるという事

_error_messages.html.erb
<% if object.errors.any? %> #このようにして使用する
.
.
.

これも同じような意味

this.erb
<%= render partial: "list_footer", locals: {username: @username, listname: @listname} %>

この意味はlist_footerパーシャル(view)の中でthis.erbで定義した@usernameをusername、 @listnameをlistnameとして使用できるという事。しかしloacalsを使わずに、@usernameをそのまま使用することも可能。しかしlocalsを使った方がパーシャルを再利用しやすいため使用される。参考文献は部分テンプレートにlocals:を使って変数を渡す時は partial:もつけないとエラー

・erb(rubyの埋め込まれたHTML)
erbでは<% 中身 %>で中身の処理をして、<%= 中身 %>では中身の処理をして結果をHTMLに出す。

app/views/static_pages/home.html.erb
<% provide(:title, "Home") %> #ここで:titleにHomeを代入
<!DOCTYPE html>
<html>
  <head> #ここで読み出して、HTMLに出す
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
  </head>

provideもyieldも関数で、変数に値を入れる、読み出すの処理をしてくれているということ。

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

rails 開発日記1 トップページの実装

 トップページの実装

*この記事は技術や知識の共有目的ではなく、完全に自己満足のアウトプット用です。

<開発環境>
1. ruby 2.6.3
2. Rails 5.1.6
3. AWS Cloud9
4. GitHub
5. Heroku(予定)

SNSのコピーサイトの開発にあたり、トップページを実装をした。
スクリーンショット 2020-04-14 16.14.22.png
                 1、トップページの完成系

自分なりに工夫した点

1.パーシャルの使用
パーシャルは開発時にHTMLの中身を整理する為のものである。
Railsチュートリアルを参考に、headerとIE用のHTML shimをまとめてみた。

<!DOCTYPE html>
<html>
  <head>
    <title>JiroApp</title>
    <%= csrf_meta_tags %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%= render 'layouts/shim' %>
  </head>

  <body>
    <%= render 'layouts/header' %>
    <%= yield %>
  </body>
</html>

これによって、headerのHTMLを <_header.html.erb> に移行することができました。

HTML CSSはあまり得意ではないのでこだわるつもりはないです。。。

次はユーザー登録機能の実装をしていきます。

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

CSSで華やかなサイトにしたい③~背景を彩ろう(色、画像の設定)~

CSSで背景を彩ろう

今回は背景に色を付けたり、画像を設定したりします:relaxed:
背景が変わることで、Webサイトの印象が大きく変わります。文字の読みやすさに注意しながら、背景を選んでいきましょう:bangbang:

今回の記事:arrow_down:

  • 背景に色を付けよう「background-color」プロパティ
  • 背景に画像を設置しよう「background-image」プロパティ
    • 背景画像の繰り返し表示「background-repeat」プロパティ
    • 背景画像の大きさを指定「background-size」プロパティ
    • 背景画像の位置指定「background-position」プロパティ
    • 背景関連プロパティをまとめて指定「backgroundプロパティ」
  • 上級者編?!背景画像のカスタマイズ
    • 背景画像にブレンドモードで色を重ねる
    • 背景をグラデーションカラーにする
    • 背景画像にブレンドモードでグラデーションカラーを重ね合わせる
  • 写真素材、背景画像をダウンロードできるオススメWebサイト

背景に色を付けよう「background-color」プロパティ

背景に色を付けるには、「background-color」プロパティを使います。色の指定方法は文字に色をつけるときと同じく、カラーコードや、色の名前を書きます。

文字の色の付け方はこちらを参考にしてください:point_down_tone2:
CSSで華やかなサイトにしたい②~文字や文章の装飾、Webフォントの使い方~
文字に色を付けてみよう「colorプロパティ」

主な値

指定方法 説明
カラーコード 「#(ハッシュ)」で始まる3桁もしくは6桁のカラーコード指定
色の名前 「red」「blue」などの決められた色の指定
RGB値 「rgb」から書き始め、赤、緑、青の値を「,(カンマ)」で区切って指定。透明度も含める場合は「rgba」から書き始め、赤、緑、青、透明度の値を「,(カンマ)」で区切って指定。透明度は0~1の間で記録する。 

ページ全体の背景に色を付けるなら<body>タグに対して指定します。

HTML
   <h1>猫の好きな事</h1>
   <h2>毛づくろいをすることが好き</h2>
   <p>毛づくろいの目的はいくつかありますが、舌にある無数の突起をブラシ代わりにして、体を清潔にすることが大半。
    猫は、起きている時間の30〜50%を毛づくろいに費やすほどキレイ好きなんです。  
   </p>
ページ全体に色付け:CSS
body{
    background-color: pink;
}

コメント 2020-04-13 084727.png

またタグや、クラスごとに背景色を設定することもできます。

ページ全体に色付け:CSS
h1{
    background-color: rgb(255, 183, 195);
}
h2{
    background-color:#fc5ba1 ;
}
p{
    background-color:#ff3845 ;   
}

image.png

背景に画像を設置しよう「background-image」プロパティ

background-imageプロパティで、要素の背景に画像を設置します。画像がちゃんと読み込まれなかったときのことも考え、背景画像と同時に同じような色合いの背景色も指定すると良いでしょう。

主な値

指定方法 説明
url 画像ファイルの指定
none 背景画像を設定しない

「url」に続いて丸かっこ()内に画像のパスを記述します。CSSファイルから見た画像の位置を書きましょう。

ファイルパスについてはこちらを参考にしてください:point_down_tone2:
HTMLの基本的な書き方をマスターしよう-ファイルパスの指定

背景画像:CSS
body{
    background-color: whitesmoke;
    background-image: url(../img/bg.png);
}

ページ全体に背景が設定されます。
image.png

背景画像の繰り返し表示「background-repeat」プロパティ

CSSのデフォルトの設定では背景画像を縦と横に繰り返し表示し、画面いっぱいに画像を敷き詰めます。これをどの方向に繰り返すか、または繰り返さないかをbackground-repeatプロパティで設定できます。

主な値

指定方法 説明
repeat 縦・横ともに繰り返して表示
repeat-x 横方向に繰り返して表示
repeat-y 縦方向に繰り返して表示
no-repeat 繰り返さない

例えば先ほど背景に設定した画像は以下の模様の画像を繰り返して作ることができます:point_down_tone2:
jade.jpg

「repeat-x」で横一列に画像を並べてみます。

背景横一列繰り返し:CSS
body{
    background-image: url(../img/jade.jpg);
    background-repeat: repeat-x;
}

image.png

「repeat-y」で縦一列に画像を並べてみます。

背景縦一列繰り返し:CSS
body{
    background-image: url(../img/jade.jpg);
    background-repeat: repeat-y;
}

image.png

repeatで設定すれば、模様を繰り返して背景画像を作ることができますね:heart_eyes:

背景画像の大きさを指定「background-size」プロパティ

background-sizeプロパティで背景サイズを指定します。元の画像の比率を維持したまま要素に当てはめたり、指定したサイズに引き延ばしたりもできます。

主な値

指定方法 説明
数値 数値に「px」や「rem」、「%」などの単位をつける
キーワード 「cover」、「contain」で指定

「cover」を使うと、画像の縦横比を保持したまま、表示領域をうめつくすように背景画像を表示できます。表示領域より画面が大きい場合は画面が切れます。

例:こちらの画像を背景画像として設定してみます:point_down_tone2:
bg-palmtree.jpg

背景画像大きさ:CSS
body{
    background-image: url(../img/bg-palmtree.jpg);
    background-repeat:no-repeat;
    background-size: cover;
    height: 100vh;
}

要素サイズいっぱいに画面が広がりますが、画像の下部分が切れます。
コメント 2020-04-14 151914.png

「contain」では、画像の縦横比を保持したまま、画像すべて表示されるように表示できます。表示領域のほうが画像より大きい場合は余白ができます。

背景画像大きさ:CSS
body{
    background-image: url(../img/bg-palmtree.jpg);
    background-repeat:no-repeat;
    background-size: contain;
    height: 100vh;
}

image.png

画像がすべて表示されましたが、右側に余白ができました。

背景画像の位置指定「background-position」プロパティ

background-positionプロパティで背景画像を表示する開始位置を指定します。基本的に横方向、縦方向の順にスペースで区切って記述します。デフォルトでは左上(left top)が表示開始位置です。

主な値

指定方法 説明
数値 数値に「px」や「rem」、「%」などの単位をつける
キーワード 横方向は「left(左)」、「center(中央)」、「right(右)」、縦方向は「top(上)」「center(中央)」 「bottom(下)」

表示する位置が画面の四隅なら、キーワードで指定すると良いでしょう。

背景画像の位置:CSS
body{
    background-image: url(../img/jade.jpg);
    background-repeat:no-repeat;
    background-position: center top;
}

画面の上部、真ん中に表示しました。
image.png

背景画像の位置:CSS
body{
    background-image: url(../img/jade.jpg);
    background-repeat:no-repeat;
    background-position: 30px 80px;
}

画面の左から30px、上から80pxの位置に表示しました。
コメント 2020-04-14 155512.png

背景関連プロパティをまとめて指定「backgroundプロパティ」

backgroundプロパティを使えば、背景色や、背景画像、サイズ、繰り返し表示など、背景に関するすべての値を一括で設定できます。すべてのプロパティを指定する必要はありません。指定していないものは初期値が適応されます。

一括指定できるプロパティ

  • background-clip
  • background-origin
  • background-size
  • background-color
  • background-position
  • background-attachment
  • background-image
  • background-repeat

「background-size」の値は「background-position」の直後に「/(スラッシュ)」で区切る必要があります。

一括指定:CSS
body{
    background: aliceblue url(../img/bg-palmtree.jpg) no-repeat 
    center bottom/cover;
    height: 100vh;
}

上級者編?!背景画像のカスタマイズ

背景画像に少し手を加えてカスタマイズしてみましょう:grin:
色を重ねたり、グラデーションカラーなどを使って、背景画像を華やかにしていきたいと思います。

背景画像にブレンドモードで色を重ねる

複数の画像や色を様々な手法で重ね合わせ、独特の効果を生み出す機能を「描画モード(ブレインモード)」といいます。
background-blend-modeプロパティを使い、値に加えたい効果の名前を指定すれば利用できます。

主な値

ブレインモード
multiply 乗算
screen スクリーン
overlay オーバーレイ
darken 暗く
lighten 明るく
color-dodge 覆い焼きカラー
color-burn 焼きこみカラー
hard-light ハードライト
soft-light ソフトライト」
difference 差の絶対値
exclusion 除外
hue 色相
saturation 彩度
color カラー
luminosity 輝度

1つ例を見てみましょう。今回はメインカラーである青を全面に、明るい色合いで表示したかったので、「hard-light」の値を使いました。

ブレインモード、ハードライト:CSS
body{
    background-image: url(../img/bg-palmtree.jpg);
    background-color: #0bd;
    background-position: center bottom;
    background-size: cover;
    background-blend-mode: hard-light;
    height: 100vh;
}

image.png

爽やかな印象になりましたね:point_up_tone2:

背景をグラデーションカラーにする

テーマカラーをうまく取り入れて美しいグラデーションを実施しましょう。グラデーションはbackground-imageプロパティに「linear-gradient」の値を使い、カンマ「,」で区切って異なる色を指定します。直線上に伸びるグラデーションではなく、円形のグラデーションを実施するには、「radial-gradient」を使います。

主な値

グラデーションの形状
linear-gradient 線形グラデーション
radial-gradient 円形グラデーション

例:#c9ffbf(明るい黄緑)から#ffafbd(明るいピンク)へのグラデーションです。

グラデーションカラー:CSS
body{
    background-image: linear-gradient(#c9ffbf,#ffafbd);
    min-height: 100vh;
}

image.png

背景画像にブレンドモードでグラデーションカラーを重ね合わせる

背景画像にグラデーションカラーを重ね合わせることもできます。「background-blend-mode」でブレンドモードを指定するところは変わりませんが、background-imageプロパティで背景画像とグラデーションカラーをカンマ「,」で区切って両方指定するところがポイントです。

ブレンドモードでグラデーションカラー:CSS
body{
    background-image: url(../img/bg-palmtree.jpg),linear-gradient(#c9ffbf,#ffafbd);
    background-blend-mode: luminosity;
    background-position: center bottom;
    background-size: cover;
    background-blend-mode: hard-light;
    height: 100vh;
}

image.png

写真素材、背景画像をダウンロードできるオススメWebサイト

背景画像にお勧めな画像がダウンロードできるオススメサイトです。以下のサイトは気軽に使える無料版です。

The Pattern Library:point_down_tone2:
image.png
上の例で利用した模様の画像はこちらのサイトから使いました。背景用パターンが無料でダウンロードできます。可愛らしいものからユニークなものがあります。

StockSnap.io:point_down_tone2:
image.png
上の例で使用したヤシの木の風景画像はこちらのサイトから使いました。著作権制限のない、パブリックドメインの写真を集めたWebサイトです。海外のサイトで、おしゃれなデザインが多く、クオリティが高いものが多いです。

参考文献

Mana著、「1冊ですべて身につくHTML&CSSとWebデザイン入門講座」、SBクリエイティブ株式会社、2019年

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

スクロール位置でクラスを付与してくれるDelighters

delighters.png
Delighters公式サイト

スクロール位置によって、表示要素に動きを付けたい際利用できるライブラリです。
散々流行った今更のパララックスかもしれませんが、まだちょっと需要はありそうです。

この演出をGoogle先生に聞いてみたところ、jQueryを利用したライブラリばっかりがヒットしてしまいました:cry:
Delightersはピュアなjsで実装できる貴重なライブラリだと思います。

Delighters Good Points :point_up:

◉ 軽量
◉ レスポンシブ対応 - タブレット、スマホもどんとこい!!
◉ スクロール位置で指定した要素にクラスが付与されるだけ。導入がシンプルで簡単。
◉ jsによる動きの定義がない。使い慣れたCSSを利用してこちらで細かな設定が自由に定義できて嬉しい。

Delighters 使い方 :point_up:

ざっくりとした使い方です。
※慣れてる方は飛ばして下さい。Delighters公式サイトのUsageをみていただくのが一番です。

:one: scriptファイルを読み込む
公式のGitHubから落としてこれます。

<script type="text/javascript" src="delighters.js">

:two: 動かしたい要素のhtmlにdata-delighterという属性を追加する

<div class="xxxクラス名は自由" data-delighter>

:three: 自分で自由にスタイルシートで動きをつける
センスが出る腕の見せどころw ダサくなりたくない…
アニメーションの設定をします。ここでは公式のクラスを引用してます。

/* delighters.jsが読み込まれると、 [data-delighter] 属性を持っている要素それぞれに .delighter が付与されます。*/

.foo.delighter {
  transition: all .3s ease-out;
  transform: translateX(-100%);
  opacity: 0;
}

/* スクロールしてターゲットが画面上部(初期設定)から75%(初期設定)の位置にきた際 .started が設定されます。*/

.foo.delighter.started {
  transform: none;
  opacity: 1;
}

/* スクロールしてターゲットが画面下部(初期設定)から75%(初期設定)の位置にきた際 .ended が設定されます。 */

.foo.delighter.started.ended {
  border: solid red 10px;
}

Delightersカスタマイズ :point_up:

属性名や、スクロール位置で設定されるクラス名、上部もしくは下部からどれくらいの位置にするかなど変更できるそうです。

options = {
  attribute:  'data-delighter',
  classNames: ['delighter', 'started', 'ended'],
  start:      0.75, // default start threshold
  end:        0.75, // default end threshold
  autoInit:   true  // initialize when DOMContentLoaded
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

女子高生が友だちと3日間で作った「Yobikake」というWebサービスの、見た目を作る技術と工夫の話

image.png

こんにちはー!東京都在住のため、がっつり外出自粛をしている人間です。「ぴえん?」よりも「display: flex;」を愛用しているJKです。(これが言いたいだけで女子高生という属性を乱用してしまいました。申し訳ございません。)

友だち(@nztm)と2人で「Yobikake ~あなたの呼びかけからはじめよう~」というWebサービスをつくったので、今回は自分が主に実装した部分の技術的解説・デザイン的解説をします。なお、Nuxt.js (Vue.js)を使用しています。

※今回初めて触ったので、間違った知識など記載していましたら、コメント等でご指摘いただけますと嬉しいですm(_ _)m

この記事の想定読者

  • 自分でちょっとしたWebサイトを作りたい人
  • HTML/CSS から一歩踏み出した技術をつかってWebサイトを作ってみたい人
  • Webデザインに興味がある人

何を作ったのか

今回開発した「Yobikake ~あなたの呼びかけからはじめよう~」は、OGP画像を活用した、新型コロナウイルスに関連する呼びかけができるWebサイトです。#StayHome や #うちで過ごそう といったハッシュタグを見たことはないでしょうか。現在、様々な人が世界中、各SNSで呼びかけを行っています。
「その『呼びかけ』を、ワンクリックで気軽にできるようになれば、世界を少しでも救えるのではないか」という発想で、このサービスは作られました。

仕組みは以下の図のようになっています。
yobikakeの仕組み.png

開発の流れ

4/10, 金曜日午前に「今日とか明日って忙しいですか?」と、@nztm さんから一通のメッセージが。話を聞いてみると、OGP画像を利用して、新型コロナウイルスに関するムーブメントを促すという、シンプルなWebサービスを作りたいとのこと。「面白そう!やりたい!」と、協力させていただきました。

役割の分担についてですが、コンテンツ、仕組みの実装、デザインの方向性決定は @nztm さん、見た目に関する実装は私が担当しています。コンテンツを @nztm さんが作り、それをもとに私が見た目を整えていき、それに @nztm さんがフィードバックを返し、という流れを繰り返しました。

なお、コンセプトや仕組みについての記事は以下で @nztm さんが書いています。
https://qiita.com/nztm/items/2de55be97ac1de9a435b

サービスの概念と方向性の共有は、初日にZoomを利用して行いました。ディレクトリはGitHubで管理し、コンテンツ及びデザインに関する議論はissueまたはTwitterDMで行っています。

工夫した点・語りたい点

共有ボタンの実装

まずは、このサービスの重要な機能ともいえる「共有ボタン」の実装についてです。
共有ボタンは共通で使いまわしたいので、コンポーネント化しました。

1. 共有するテキストを動的に変更できるようにする

「よびかけ」ごとに共有したい文章とURLが異なります。文章とURLのデータを受け取って、aタグのhrefが変わるようにしました。

コンポーネント化・読み込み

毎回ボタン3つ分を記述するとメンテナンス性が下がってしまうので、コンポーネント1つをそれぞれ読み込むようにしました。なにか変更を加えたいときも、一つのファイルをいじるだけで良いので、とてもスッキリとした設計になりました。
いくつか略していますが、共有ボタン3つのコンポーネントは以下のようになっています。

shareButtons.vue
<template>
  <div class="share-buttons">
    <a
      :href="
        'http://twitter.com/share?url=https://yobikake.com/' +
          url +
          '&text=' +
          encodeURIComponent(text) +
          '%0A' +
          '&related=yobikakecom,nztm_tw'
      "
      target="_blank"
      class="share-link share-link-twitter"
      ><i class="fab fa-twitter"></i> ツイートする
    </a>
    <a
      :href="
        'https://www.facebook.com/dialog/share?app_id=640540216785473&display=popup&href=https://yobikake.com/' +
          url
      "
      target="_blank"
      class="share-link share-link-fb"
      ><i class="fab fa-facebook"></i> シェアする
    </a></div>
</template>

<script>
export default {
  props: ['url', 'text'],
  
}
</script>

<style lang="scss" scoped>

</style>

これを、以下のように呼び出すことで表示できます。

index.vue
<template>
  <div>
    <shareButtons
      url="stayhome"
      text="うちで過ごそう!みんなのために?
 #うちで過ごそう #stayhome #Yobikake"
    ></shareButtons>
  </div>
</template>

<script>
import shareButtons from '~/components/shareButtons.vue'

export default {
  components: {
    shareButtons
  }
}
</script>

このように表示されます。
image.png
もう少し細かく説明します。

URLの設定について

共有するURLの前半は共通なので、urlhttps://yobikake.com/ に続くパスを入れることにしました。また、text は、メンテナンス性・可読性を考えて、UTF-8に変換する前の状態で管理できるようにしました。意外とシンプルに、encodeURIComponent() でさくっと変換できています。
(下記Twitter用のリンクの例を参照)

<a :href="
        'http://twitter.com/share?url=https://yobikake.com/' +
          url +
          '&text=' +
          encodeURIComponent(text) +
          '%0A' +
          '&related=yobikakecom,nztm_tw'
      " >
href ではなく :hrefとなっている理由

href他、HTML属性の内部では文字列の連結等操作ができません。そこで活躍するのがVue.jsさんのv-bindです。v-bindはプロパティや属性と、式を結びつけてくれるものです。便利ですねぇ。
例えば、<a v-bind:href="式"> のように書くことができます。ここでは省略記法で、v-bind:hrefではなく:hrefと記述しています。

Vue.js ガイドで、構文について書いてあるので、詳しくはそちらを読んでいただけるとわかりやすいと思います。

2. コピーボタン

できるだけ多くの方に使っていただけることが一番なのですが、Twitter, Facebook以外のサービス全てに対応することは難しいです。そこで、どんなプラットフォームでもペーストで呼びかけられるよう、簡単にURLをコピーできるボタンを設けました。

このボタンは、クリック時にcopy()というメソッドを呼び出します。ラベルはcopyLabelという変数に入っている文字列を表示します。

<span
  class="share-link share-link-copy copy"
  @click="copy('https://yobikake.com/' + url)"
  ><i class="far fa-copy fa-fw"></i>{{ copyLabel }}
</span>

copy()では、引数をクリップボードにコピーして、copyLabelを変更しています。

<script>
export default {
  props: ['url', 'text'],
  data: () => ({
    copyLabel: 'コピーする'
  }),
  methods: {
    copy(msg) {
      const copyText = msg
      navigator.clipboard.writeText(copyText)
      this.copyLabel = 'コピーしました!'
      setTimeout(
        function() {
          this.copyLabel = 'コピーする'
        }.bind(this),
        2000
      )
    }
  }
}
</script>

もう少し余裕があれば、それぞれの「呼びかけ」もコンポーネント化して管理したいところですね。ですが、まずは2日後のリリースまでに使える状態にすることが最優先だったので、このような形になりました。

きれいに魅せる工夫

さて、機能が正常に動くことも大事ですが、その配置・表示も重要です。
いくつかこだわった点をまとめます。

ヘッダーのキャッチコピー表示

ヘッダーのキャッチコピーですが、文字を表示するだけではない、小さなこだわりがあります。単なる表示だと、このように変な改行が入ってしまいます。まるで「今すぐダウンロー ⏎ド」のようですね。

image.png
そこで、文を分解(ダジャレ)して、それぞれにdisplay: inline-block;を設定します。そうすることで、自然な部分で改行されるようになります。
image.png

<span>あなたの呼びかけから</span><span>はじめよう</span>
span {
  display: inline-block;
}

一覧のレスポンシブ対応

image.png
この部分は、いろいろやりました。項目は4つなので、並べ方は2,2か4か1,1,1,1にすることで、仲間はずれがなくきれいに並べられます。
そのため、コンテンツそれぞれは基本固定幅に設定して、親要素の幅を画面幅に応じて変えるようにしました。技術的にはなにも難しくないのですが、細かなこだわりでぐっと見栄えが良くなります。

絵文字/色

最後に、絵文字と色についてです。絵文字はTwitterのオープンソースな絵文字、「twemoji」を使っています。絵文字の見た目が端末に依存しないという利点があります。また、フラットなデザインなので最近の流行りと相性が良いです。

色は、基本的に @nztm さんのデザインラフをメインに設定しています。背景色、フッターの色、影の色は、青〜水色で統一させています。

コンプレックスカラーといって、フッターよりも背景色を青寄りに設定しました。すこし意外性のある配色ですが、見ていて楽しいですよね。これ以上語ると話がそれてしまうので、以上にしたいと思います。

最後に

読んでいただきありがとうございました!
技術的な話より、考え方の話の紹介になってしまいましたが、WebサイトデザインやWebサービスづくりをやってみようかな、と考えている人の力になれていたら幸いです…!

ちなみに、ここから実際に動いているサービスを見られます?
https://yobikake.com/

この「Yobikake」はGitHubで公開しています。PRやIssueお待ちしておりますm(_ _)m

追伸: 今回のサービスは3日間で作ったのですが、爆速開発をしてみようかな、と考えている方には「睡眠は大事ですよ」とだけお伝えしておきます。

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

コロナに関する呼びかけが簡単にできるWebサービス「Yobikake」の、見た目を作る技術と工夫の話

image.png

こんにちはー!東京都在住のため、がっつり外出自粛をしている人間です。「ぴえん?」よりも「display: flex;」を愛用しているJKです。(これが言いたいだけで女子高生という属性を乱用してしまいました。申し訳ございません。)

友だち(@nztm)と2人で「Yobikake ~あなたの呼びかけからはじめよう~」というWebサービスをつくったので、今回は自分が主に実装した部分の技術的解説・デザイン的解説をします。なお、Nuxt.js (Vue.js)を使用しています。

※今回初めて触ったので、間違った知識など記載していましたら、コメント等でご指摘いただけますと嬉しいですm(_ _)m

この記事の想定読者

  • 自分でちょっとしたWebサイトを作りたい人
  • HTML/CSS から一歩踏み出した技術をつかってWebサイトを作ってみたい人
  • Webデザインに興味がある人

何を作ったのか

今回開発した「Yobikake ~あなたの呼びかけからはじめよう~」は、OGP画像を活用した、新型コロナウイルスに関連する呼びかけができるWebサイトです。#StayHome や #うちで過ごそう といったハッシュタグを見たことはないでしょうか。現在、様々な人が世界中、各SNSで呼びかけを行っています。
「その『呼びかけ』を、ワンクリックで気軽にできるようになれば、世界を少しでも救えるのではないか」という発想で、このサービスは作られました。

仕組みは以下の図のようになっています。
yobikakeの仕組み.png

開発の流れ

4/10, 金曜日午前に「今日とか明日って忙しいですか?」と、@nztm さんから一通のメッセージが。話を聞いてみると、OGP画像を利用して、新型コロナウイルスに関するムーブメントを促すという、シンプルなWebサービスを作りたいとのこと。「面白そう!やりたい!」と、協力させていただきました。

役割の分担についてですが、コンテンツ、仕組みの実装、デザインの方向性決定は @nztm さん、見た目に関する実装は私が担当しています。コンテンツを @nztm さんが作り、それをもとに私が見た目を整えていき、それに @nztm さんがフィードバックを返し、という流れを繰り返しました。

なお、コンセプトや仕組みについての記事は以下で @nztm さんが書いています。
https://qiita.com/nztm/items/2de55be97ac1de9a435b

サービスの概念と方向性の共有は、初日にZoomを利用して行いました。ディレクトリはGitHubで管理し、コンテンツ及びデザインに関する議論はissueまたはTwitterDMで行っています。

工夫した点・語りたい点

共有ボタンの実装

まずは、このサービスの重要な機能ともいえる「共有ボタン」の実装についてです。
共有ボタンは共通で使いまわしたいので、コンポーネント化しました。

1. 共有するテキストを動的に変更できるようにする

「よびかけ」ごとに共有したい文章とURLが異なります。文章とURLのデータを受け取って、aタグのhrefが変わるようにしました。

コンポーネント化・読み込み

毎回ボタン3つ分を記述するとメンテナンス性が下がってしまうので、コンポーネント1つをそれぞれ読み込むようにしました。なにか変更を加えたいときも、一つのファイルをいじるだけで良いので、とてもスッキリとした設計になりました。
いくつか略していますが、共有ボタン3つのコンポーネントは以下のようになっています。

shareButtons.vue
<template>
  <div class="share-buttons">
    <a
      :href="
        'http://twitter.com/share?url=https://yobikake.com/' +
          url +
          '&text=' +
          encodeURIComponent(text) +
          '%0A' +
          '&related=yobikakecom,nztm_tw'
      "
      target="_blank"
      class="share-link share-link-twitter"
      ><i class="fab fa-twitter"></i> ツイートする
    </a>
    <a
      :href="
        'https://www.facebook.com/dialog/share?app_id=640540216785473&display=popup&href=https://yobikake.com/' +
          url
      "
      target="_blank"
      class="share-link share-link-fb"
      ><i class="fab fa-facebook"></i> シェアする
    </a></div>
</template>

<script>
export default {
  props: ['url', 'text'],
  
}
</script>

<style lang="scss" scoped>

</style>

これを、以下のように呼び出すことで表示できます。

index.vue
<template>
  <div>
    <shareButtons
      url="stayhome"
      text="うちで過ごそう!みんなのために?
 #うちで過ごそう #stayhome #Yobikake"
    ></shareButtons>
  </div>
</template>

<script>
import shareButtons from '~/components/shareButtons.vue'

export default {
  components: {
    shareButtons
  }
}
</script>

このように表示されます。
image.png
もう少し細かく説明します。

URLの設定について

共有するURLの前半は共通なので、urlhttps://yobikake.com/ に続くパスを入れることにしました。また、text は、メンテナンス性・可読性を考えて、UTF-8に変換する前の状態で管理できるようにしました。意外とシンプルに、encodeURIComponent() でさくっと変換できています。
(下記Twitter用のリンクの例を参照)

<a :href="
        'http://twitter.com/share?url=https://yobikake.com/' +
          url +
          '&text=' +
          encodeURIComponent(text) +
          '%0A' +
          '&related=yobikakecom,nztm_tw'
      " >
href ではなく :hrefとなっている理由

href他、HTML属性の内部では文字列の連結等操作ができません。そこで活躍するのがVue.jsさんのv-bindです。v-bindはプロパティや属性と、式を結びつけてくれるものです。便利ですねぇ。
例えば、<a v-bind:href="式"> のように書くことができます。ここでは省略記法で、v-bind:hrefではなく:hrefと記述しています。

Vue.js ガイドで、構文について書いてあるので、詳しくはそちらを読んでいただけるとわかりやすいと思います。

2. コピーボタン

できるだけ多くの方に使っていただけることが一番なのですが、Twitter, Facebook以外のサービス全てに対応することは難しいです。そこで、どんなプラットフォームでもペーストで呼びかけられるよう、簡単にURLをコピーできるボタンを設けました。

このボタンは、クリック時にcopy()というメソッドを呼び出します。ラベルはcopyLabelという変数に入っている文字列を表示します。

<span
  class="share-link share-link-copy copy"
  @click="copy('https://yobikake.com/' + url)"
  ><i class="far fa-copy fa-fw"></i>{{ copyLabel }}
</span>

copy()では、引数をクリップボードにコピーして、copyLabelを変更しています。

<script>
export default {
  props: ['url', 'text'],
  data: () => ({
    copyLabel: 'コピーする'
  }),
  methods: {
    copy(msg) {
      const copyText = msg
      navigator.clipboard.writeText(copyText)
      this.copyLabel = 'コピーしました!'
      setTimeout(
        function() {
          this.copyLabel = 'コピーする'
        }.bind(this),
        2000
      )
    }
  }
}
</script>

もう少し余裕があれば、それぞれの「呼びかけ」もコンポーネント化して管理したいところですね。ですが、まずは2日後のリリースまでに使える状態にすることが最優先だったので、このような形になりました。

きれいに魅せる工夫

さて、機能が正常に動くことも大事ですが、その配置・表示も重要です。
いくつかこだわった点をまとめます。

ヘッダーのキャッチコピー表示

ヘッダーのキャッチコピーですが、文字を表示するだけではない、小さなこだわりがあります。単なる表示だと、このように変な改行が入ってしまいます。まるで「今すぐダウンロー ⏎ド」のようですね。

image.png
そこで、文を分解(ダジャレ)して、それぞれにdisplay: inline-block;を設定します。そうすることで、自然な部分で改行されるようになります。
image.png

<span>あなたの呼びかけから</span><span>はじめよう</span>
span {
  display: inline-block;
}

一覧のレスポンシブ対応

image.png
この部分は、いろいろやりました。項目は4つなので、並べ方は2,2か4か1,1,1,1にすることで、仲間はずれがなくきれいに並べられます。
そのため、コンテンツそれぞれは基本固定幅に設定して、親要素の幅を画面幅に応じて変えるようにしました。技術的にはなにも難しくないのですが、細かなこだわりでぐっと見栄えが良くなります。

絵文字/色

最後に、絵文字と色についてです。絵文字はTwitterのオープンソースな絵文字、「twemoji」を使っています。絵文字の見た目が端末に依存しないという利点があります。また、フラットなデザインなので最近の流行りと相性が良いです。

色は、基本的に @nztm さんのデザインラフをメインに設定しています。背景色、フッターの色、影の色は、青〜水色で統一させています。

コンプレックスカラーといって、フッターよりも背景色を青寄りに設定しました。すこし意外性のある配色ですが、見ていて楽しいですよね。これ以上語ると話がそれてしまうので、以上にしたいと思います。

最後に

読んでいただきありがとうございました!
技術的な話より、考え方の話の紹介になってしまいましたが、WebサイトデザインやWebサービスづくりをやってみようかな、と考えている人の力になれていたら幸いです…!

ちなみに、ここから実際に動いているサービスを見られます?
https://yobikake.com/

この「Yobikake」はGitHubで公開しています。PRやIssueお待ちしておりますm(_ _)m

追伸: 今回のサービスは3日間で作ったのですが、爆速開発をしてみようかな、と考えている方には「睡眠は大事ですよ」とだけお伝えしておきます。

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

コロナに関する呼びかけを簡単にする、Webサービス「Yobikake」の見た目を作る技術と工夫

image.png

こんにちはー!東京都在住のため、がっつり外出自粛をしている人間です。「ぴえん?」よりも「display: flex;」を愛用しているJKです。(これが言いたいだけで女子高生という属性を乱用してしまいました。申し訳ございません。)

友だち(@nztm)と2人で「Yobikake ~あなたの呼びかけからはじめよう~」というWebサービスをつくったので、今回は自分が主に実装した部分の技術的解説・デザイン的解説をします。なお、Nuxt.js (Vue.js)を使用しています。

※今回初めて触ったので、間違った知識など記載していましたら、コメント等でご指摘いただけますと嬉しいですm(_ _)m

この記事の想定読者

  • 自分でちょっとしたWebサイトを作りたい人
  • HTML/CSS から一歩踏み出した技術をつかってWebサイトを作ってみたい人
  • Webデザインに興味がある人

何を作ったのか

今回開発した「Yobikake ~あなたの呼びかけからはじめよう~」は、OGP画像を活用した、新型コロナウイルスに関連する呼びかけができるWebサイトです。#StayHome や #うちで過ごそう といったハッシュタグを見たことはないでしょうか。現在、様々な人が世界中、各SNSで呼びかけを行っています。
「その『呼びかけ』を、ワンクリックで気軽にできるようになれば、世界を少しでも救えるのではないか」という発想で、このサービスは作られました。

仕組みは以下の図のようになっています。
yobikakeの仕組み.png

開発の流れ

4/10, 金曜日午前に「今日とか明日って忙しいですか?」と、@nztm さんから一通のメッセージが。話を聞いてみると、OGP画像を利用して、新型コロナウイルスに関するムーブメントを促すという、シンプルなWebサービスを作りたいとのこと。「面白そう!やりたい!」と、協力させていただきました。

役割の分担についてですが、コンテンツ、仕組みの実装、デザインの方向性決定は @nztm さん、見た目に関する実装は私が担当しています。コンテンツを @nztm さんが作り、それをもとに私が見た目を整えていき、それに @nztm さんがフィードバックを返し、という流れを繰り返しました。

なお、コンセプトや仕組みについての記事は以下で @nztm さんが書いています。
https://qiita.com/nztm/items/2de55be97ac1de9a435b

サービスの概念と方向性の共有は、初日にZoomを利用して行いました。ディレクトリはGitHubで管理し、コンテンツ及びデザインに関する議論はissueまたはTwitterDMで行っています。

工夫した点・語りたい点

共有ボタンの実装

まずは、このサービスの重要な機能ともいえる「共有ボタン」の実装についてです。
共有ボタンは共通で使いまわしたいので、コンポーネント化しました。

1. 共有するテキストを動的に変更できるようにする

「よびかけ」ごとに共有したい文章とURLが異なります。文章とURLのデータを受け取って、aタグのhrefが変わるようにしました。

コンポーネント化・読み込み

毎回ボタン3つ分を記述するとメンテナンス性が下がってしまうので、コンポーネント1つをそれぞれ読み込むようにしました。なにか変更を加えたいときも、一つのファイルをいじるだけで良いので、とてもスッキリとした設計になりました。
いくつか略していますが、共有ボタン3つのコンポーネントは以下のようになっています。

shareButtons.vue
<template>
  <div class="share-buttons">
    <a
      :href="
        'http://twitter.com/share?url=https://yobikake.com/' +
          url +
          '&text=' +
          encodeURIComponent(text) +
          '%0A' +
          '&related=yobikakecom,nztm_tw'
      "
      target="_blank"
      class="share-link share-link-twitter"
      ><i class="fab fa-twitter"></i> ツイートする
    </a>
    <a
      :href="
        'https://www.facebook.com/dialog/share?app_id=640540216785473&display=popup&href=https://yobikake.com/' +
          url
      "
      target="_blank"
      class="share-link share-link-fb"
      ><i class="fab fa-facebook"></i> シェアする
    </a></div>
</template>

<script>
export default {
  props: ['url', 'text'],
  
}
</script>

<style lang="scss" scoped>

</style>

これを、以下のように呼び出すことで表示できます。

index.vue
<template>
  <div>
    <shareButtons
      url="stayhome"
      text="うちで過ごそう!みんなのために?
 #うちで過ごそう #stayhome #Yobikake"
    ></shareButtons>
  </div>
</template>

<script>
import shareButtons from '~/components/shareButtons.vue'

export default {
  components: {
    shareButtons
  }
}
</script>

このように表示されます。
image.png
もう少し細かく説明します。

URLの設定について

共有するURLの前半は共通なので、urlhttps://yobikake.com/ に続くパスを入れることにしました。また、text は、メンテナンス性・可読性を考えて、UTF-8に変換する前の状態で管理できるようにしました。意外とシンプルに、encodeURIComponent() でさくっと変換できています。
(下記Twitter用のリンクの例を参照)

<a :href="
        'http://twitter.com/share?url=https://yobikake.com/' +
          url +
          '&text=' +
          encodeURIComponent(text) +
          '%0A' +
          '&related=yobikakecom,nztm_tw'
      " >
href ではなく :hrefとなっている理由

href他、HTML属性の内部では文字列の連結等操作ができません。そこで活躍するのがVue.jsさんのv-bindです。v-bindはプロパティや属性と、式を結びつけてくれるものです。便利ですねぇ。
例えば、<a v-bind:href="式"> のように書くことができます。ここでは省略記法で、v-bind:hrefではなく:hrefと記述しています。

Vue.js ガイドで、構文について書いてあるので、詳しくはそちらを読んでいただけるとわかりやすいと思います。

2. コピーボタン

できるだけ多くの方に使っていただけることが一番なのですが、Twitter, Facebook以外のサービス全てに対応することは難しいです。そこで、どんなプラットフォームでもペーストで呼びかけられるよう、簡単にURLをコピーできるボタンを設けました。

このボタンは、クリック時にcopy()というメソッドを呼び出します。ラベルはcopyLabelという変数に入っている文字列を表示します。

<span
  class="share-link share-link-copy copy"
  @click="copy('https://yobikake.com/' + url)"
  ><i class="far fa-copy fa-fw"></i>{{ copyLabel }}
</span>

copy()では、引数をクリップボードにコピーして、copyLabelを変更しています。

<script>
export default {
  props: ['url', 'text'],
  data: () => ({
    copyLabel: 'コピーする'
  }),
  methods: {
    copy(msg) {
      const copyText = msg
      navigator.clipboard.writeText(copyText)
      this.copyLabel = 'コピーしました!'
      setTimeout(
        function() {
          this.copyLabel = 'コピーする'
        }.bind(this),
        2000
      )
    }
  }
}
</script>

もう少し余裕があれば、それぞれの「呼びかけ」もコンポーネント化して管理したいところですね。ですが、まずは2日後のリリースまでに使える状態にすることが最優先だったので、このような形になりました。

きれいに魅せる工夫

さて、機能が正常に動くことも大事ですが、その配置・表示も重要です。
いくつかこだわった点をまとめます。

ヘッダーのキャッチコピー表示

ヘッダーのキャッチコピーですが、文字を表示するだけではない、小さなこだわりがあります。単なる表示だと、このように変な改行が入ってしまいます。まるで「今すぐダウンロー ⏎ド」のようですね。

image.png
そこで、文を分解(ダジャレ)して、それぞれにdisplay: inline-block;を設定します。そうすることで、自然な部分で改行されるようになります。
image.png

<span>あなたの呼びかけから</span><span>はじめよう</span>
span {
  display: inline-block;
}

一覧のレスポンシブ対応

image.png
この部分は、いろいろやりました。項目は4つなので、並べ方は2,2か4か1,1,1,1にすることで、仲間はずれがなくきれいに並べられます。
そのため、コンテンツそれぞれは基本固定幅に設定して、親要素の幅を画面幅に応じて変えるようにしました。技術的にはなにも難しくないのですが、細かなこだわりでぐっと見栄えが良くなります。

絵文字/色

最後に、絵文字と色についてです。絵文字はTwitterのオープンソースな絵文字、「twemoji」を使っています。絵文字の見た目が端末に依存しないという利点があります。また、フラットなデザインなので最近の流行りと相性が良いです。

色は、基本的に @nztm さんのデザインラフをメインに設定しています。背景色、フッターの色、影の色は、青〜水色で統一させています。

コンプレックスカラーといって、フッターよりも背景色を青寄りに設定しました。すこし意外性のある配色ですが、見ていて楽しいですよね。これ以上語ると話がそれてしまうので、以上にしたいと思います。

最後に

読んでいただきありがとうございました!
技術的な話より、考え方の話の紹介になってしまいましたが、WebサイトデザインやWebサービスづくりをやってみようかな、と考えている人の力になれていたら幸いです…!

ちなみに、ここから実際に動いているサービスを見られます?
https://yobikake.com/

この「Yobikake」はGitHubで公開しています。PRやIssueお待ちしておりますm(_ _)m

追伸: 今回のサービスは3日間で作ったのですが、爆速開発をしてみようかな、と考えている方には「睡眠は大事ですよ」とだけお伝えしておきます。

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

新コロに関する呼びかけを簡単にできるWebサービス「Yobikake」を作ったときの、見た目を作る技術と工夫の話

image.png

こんにちはー!東京都在住のため、がっつり外出自粛をしている人間です。「ぴえん?」よりも「display: flex;」を愛用しているJKです。(これが言いたいだけで女子高生という属性を乱用してしまいました。申し訳ございません。)

友だち(@nztm)と2人で「Yobikake ~あなたの呼びかけからはじめよう~」というWebサービスをつくったので、今回は自分が主に実装した部分の技術的解説・デザイン的解説をします。なお、Nuxt.js (Vue.js)を使用しています。

※今回初めて触ったので、間違った知識など記載していましたら、コメント等でご指摘いただけますと嬉しいですm(_ _)m

この記事の想定読者

  • 自分でちょっとしたWebサイトを作りたい人
  • HTML/CSS から一歩踏み出した技術をつかってWebサイトを作ってみたい人
  • Webデザインに興味がある人

何を作ったのか

今回開発した「Yobikake ~あなたの呼びかけからはじめよう~」は、OGP画像を活用した、新型コロナウイルスに関連する呼びかけができるWebサイトです。#StayHome や #うちで過ごそう といったハッシュタグを見たことはないでしょうか。現在、様々な人が世界中、各SNSで呼びかけを行っています。
「その『呼びかけ』を、ワンクリックで気軽にできるようになれば、世界を少しでも救えるのではないか」という発想で、このサービスは作られました。

仕組みは以下の図のようになっています。
yobikakeの仕組み.png

開発の流れ

4/10, 金曜日午前に「今日とか明日って忙しいですか?」と、@nztm さんから一通のメッセージが。話を聞いてみると、OGP画像を利用して、新型コロナウイルスに関するムーブメントを促すという、シンプルなWebサービスを作りたいとのこと。「面白そう!やりたい!」と、協力させていただきました。

役割の分担についてですが、コンテンツ、仕組みの実装、デザインの方向性決定は @nztm さん、見た目に関する実装は私が担当しています。コンテンツを @nztm さんが作り、それをもとに私が見た目を整えていき、それに @nztm さんがフィードバックを返し、という流れを繰り返しました。

なお、コンセプトや仕組みについての記事は以下で @nztm さんが書いています。
https://qiita.com/nztm/items/2de55be97ac1de9a435b

サービスの概念と方向性の共有は、初日にZoomを利用して行いました。ディレクトリはGitHubで管理し、コンテンツ及びデザインに関する議論はissueまたはTwitterDMで行っています。

工夫した点・語りたい点

共有ボタンの実装

まずは、このサービスの重要な機能ともいえる「共有ボタン」の実装についてです。
共有ボタンは共通で使いまわしたいので、コンポーネント化しました。

1. 共有するテキストを動的に変更できるようにする

「よびかけ」ごとに共有したい文章とURLが異なります。文章とURLのデータを受け取って、aタグのhrefが変わるようにしました。

コンポーネント化・読み込み

毎回ボタン3つ分を記述するとメンテナンス性が下がってしまうので、コンポーネント1つをそれぞれ読み込むようにしました。なにか変更を加えたいときも、一つのファイルをいじるだけで良いので、とてもスッキリとした設計になりました。
いくつか略していますが、共有ボタン3つのコンポーネントは以下のようになっています。

shareButtons.vue
<template>
  <div class="share-buttons">
    <a
      :href="
        'http://twitter.com/share?url=https://yobikake.com/' +
          url +
          '&text=' +
          encodeURIComponent(text) +
          '%0A' +
          '&related=yobikakecom,nztm_tw'
      "
      target="_blank"
      class="share-link share-link-twitter"
      ><i class="fab fa-twitter"></i> ツイートする
    </a>
    <a
      :href="
        'https://www.facebook.com/dialog/share?app_id=640540216785473&display=popup&href=https://yobikake.com/' +
          url
      "
      target="_blank"
      class="share-link share-link-fb"
      ><i class="fab fa-facebook"></i> シェアする
    </a></div>
</template>

<script>
export default {
  props: ['url', 'text'],
  
}
</script>

<style lang="scss" scoped>

</style>

これを、以下のように呼び出すことで表示できます。

index.vue
<template>
  <div>
    <shareButtons
      url="stayhome"
      text="うちで過ごそう!みんなのために?
 #うちで過ごそう #stayhome #Yobikake"
    ></shareButtons>
  </div>
</template>

<script>
import shareButtons from '~/components/shareButtons.vue'

export default {
  components: {
    shareButtons
  }
}
</script>

このように表示されます。
image.png
もう少し細かく説明します。

URLの設定について

共有するURLの前半は共通なので、urlhttps://yobikake.com/ に続くパスを入れることにしました。また、text は、メンテナンス性・可読性を考えて、UTF-8に変換する前の状態で管理できるようにしました。意外とシンプルに、encodeURIComponent() でさくっと変換できています。
(下記Twitter用のリンクの例を参照)

<a :href="
        'http://twitter.com/share?url=https://yobikake.com/' +
          url +
          '&text=' +
          encodeURIComponent(text) +
          '%0A' +
          '&related=yobikakecom,nztm_tw'
      " >
href ではなく :hrefとなっている理由

href他、HTML属性の内部では文字列の連結等操作ができません。そこで活躍するのがVue.jsさんのv-bindです。v-bindはプロパティや属性と、式を結びつけてくれるものです。便利ですねぇ。
例えば、<a v-bind:href="式"> のように書くことができます。ここでは省略記法で、v-bind:hrefではなく:hrefと記述しています。

Vue.js ガイドで、構文について書いてあるので、詳しくはそちらを読んでいただけるとわかりやすいと思います。

2. コピーボタン

できるだけ多くの方に使っていただけることが一番なのですが、Twitter, Facebook以外のサービス全てに対応することは難しいです。そこで、どんなプラットフォームでもペーストで呼びかけられるよう、簡単にURLをコピーできるボタンを設けました。

このボタンは、クリック時にcopy()というメソッドを呼び出します。ラベルはcopyLabelという変数に入っている文字列を表示します。

<span
  class="share-link share-link-copy copy"
  @click="copy('https://yobikake.com/' + url)"
  ><i class="far fa-copy fa-fw"></i>{{ copyLabel }}
</span>

copy()では、引数をクリップボードにコピーして、copyLabelを変更しています。

<script>
export default {
  props: ['url', 'text'],
  data: () => ({
    copyLabel: 'コピーする'
  }),
  methods: {
    copy(msg) {
      const copyText = msg
      navigator.clipboard.writeText(copyText)
      this.copyLabel = 'コピーしました!'
      setTimeout(
        function() {
          this.copyLabel = 'コピーする'
        }.bind(this),
        2000
      )
    }
  }
}
</script>

もう少し余裕があれば、それぞれの「呼びかけ」もコンポーネント化して管理したいところですね。ですが、まずは2日後のリリースまでに使える状態にすることが最優先だったので、このような形になりました。

きれいに魅せる工夫

さて、機能が正常に動くことも大事ですが、その配置・表示も重要です。
いくつかこだわった点をまとめます。

ヘッダーのキャッチコピー表示

ヘッダーのキャッチコピーですが、文字を表示するだけではない、小さなこだわりがあります。単なる表示だと、このように変な改行が入ってしまいます。まるで「今すぐダウンロー ⏎ド」のようですね。

image.png
そこで、文を分解(ダジャレ)して、それぞれにdisplay: inline-block;を設定します。そうすることで、自然な部分で改行されるようになります。
image.png

<span>あなたの呼びかけから</span><span>はじめよう</span>
span {
  display: inline-block;
}

一覧のレスポンシブ対応

image.png
この部分は、いろいろやりました。項目は4つなので、並べ方は2,2か4か1,1,1,1にすることで、仲間はずれがなくきれいに並べられます。
そのため、コンテンツそれぞれは基本固定幅に設定して、親要素の幅を画面幅に応じて変えるようにしました。技術的にはなにも難しくないのですが、細かなこだわりでぐっと見栄えが良くなります。

絵文字/色

最後に、絵文字と色についてです。絵文字はTwitterのオープンソースな絵文字、「twemoji」を使っています。絵文字の見た目が端末に依存しないという利点があります。また、フラットなデザインなので最近の流行りと相性が良いです。

色は、基本的に @nztm さんのデザインラフをメインに設定しています。背景色、フッターの色、影の色は、青〜水色で統一させています。

コンプレックスカラーといって、フッターよりも背景色を青寄りに設定しました。すこし意外性のある配色ですが、見ていて楽しいですよね。これ以上語ると話がそれてしまうので、以上にしたいと思います。

最後に

読んでいただきありがとうございました!
技術的な話より、考え方の話の紹介になってしまいましたが、WebサイトデザインやWebサービスづくりをやってみようかな、と考えている人の力になれていたら幸いです…!

ちなみに、ここから実際に動いているサービスを見られます?
https://yobikake.com/

この「Yobikake」はGitHubで公開しています。PRやIssueお待ちしておりますm(_ _)m

追伸: 今回のサービスは3日間で作ったのですが、爆速開発をしてみようかな、と考えている方には「睡眠は大事ですよ」とだけお伝えしておきます。

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

【CSS】文字列を真に折り返したいのなら

※これは元々、overflow-wrap: break-word; や word-break: break-all; が万能の改行処理だったなら、こんなに苦労していないに対するコメントとして2020年1月に書かれたものだが、line-break: anywhere;white-space: break-spaces;の知名度と支持率を上げるため、記事化して人目に触れやすくした。

問題提起

word-break: break-all;はすごい。長い英単語も、何でもかんでもほぼ完ぺきにズタズタに分解して折り返してくれる、何があっても強制改行してくれる、そんなCSSだ。ほとんどの人が、最初はそんな印象を持つだろう。もうword-break: break-all;信者になろう。とりあえず折り返しが防ぎたい時にはこれ!なんて楽だ!
この夢は永遠に続くと思われた。そう、あの文字列に遭遇するまでは。

元記事でのサンプル文字列を拝借:

サンプル
現実はかくも無情!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

おや?情!!!!!!!!!!!!の部分が2行目にまわり、あとは折り返されず突き抜けている。
ここであなたはすかさず、折り返しの定番word-break: break-all;をかける。
はい、効かない。

そう、!!!!!!!!!!!word-break: break-all;で折り返せないのである。

信者の夢は打ち砕かれた。長い英単語だって律義に折り返されてるのに、!!!!!!!!!!!だけが残る。まるで小麦粉のダマだ。裏切られたなんてヌルいもんじゃない、筆舌に尽くしがたい心情に突き落とされる。元記事主様はこれを、「何があっても強制改行と言ったな?あれは嘘だ」と表現している。

これがtableのセルをレイアウト崩壊させたり、そもそもtable以外の本文でも厄介な存在となる。スマホサイトで横スクロールを生み出すのもこいつだ。ユーザー入力コメント欄で「面白かったです!!!!!!!!!!!!!!!!」とか書き込まれてみろ。はい死亡ー

ここで、「CSS 折り返し」等でさんざん調べものをするだろう。だが、ググっても出てくるのは

  • word-break: break-all;overflow-wrap: break-word;といった王道たちを、それらの違いを分かりにくくそれっぽく説明した(つもりになってる)もの
  • white-space: nowrap;がかかってませんか」とかいう筋違いアドバイス
  • 「Unicodeのゼロ幅スペース&#8203;<wbr>を使え」とかいう愚行(←絶対にしちゃ駄目だよ!さもなくばこんなトラブルの元になる。そもそも、見栄えのためにデータに手を加えるなんてあり得ない)

こんなのばかりだ。は????折り返し問題はコレで解決?何をおっしゃい。そんなクソハウツーサイトや有耶無耶ブログばかりだ。英語で検索しても、なかなか真の解決方法を見つけるのは難しい。

万策尽きた…………… この記事は、そんな壁にぶち当たったあなたが対象だ。

さっさと結論

これらはまさしく、過去の私もぶち当たった問題だ。
私はかつてこの問題と徹底的に闘い、Chrome開発者と直接情報交換をしながら、その全貌を
https://ss1.xrea.com/ango.g3.xrea.com/jkkn/chrome_bug5.html
https://ss1.xrea.com/ango.g3.xrea.com/jkkn/chrome_bug14.html
に纏めてある。

結論から書くと、今の所究極の、(しかし、悲しいかな、正確には「将来究極になる予定の」)解決方法は、

word-break: break-all;        /* 元記事と同じ */
overflow-wrap: break-word;    /* 〃 */
word-wrap: break-word;        /* 〃 */
line-break: anywhere;         /* 見慣れない。 */
white-space: pre-wrap;        /* 任意。詳細は後述 */
white-space: break-spaces;    /* 見慣れない。但し、これも任意 */

である。
私が得たこの究極の結論には、見覚えのないCSSが含まれていると思う。
下の方にある、line-break: anywhere;white-space: break-spaces;の2つだ。

また、この中には、元記事中で推奨されていたword-break: break-word;が含まれていない。なぜか? かつては私もword-break: break-word;を発見し、歓喜したものだ。しかし、後に解決方法から除外した。その理由は後述。

この究極の結論、特にline-break: anywhere;について、まだ日本ではまだ殆ど知られていないと思われる為、情報共有する。

問題の整理

まず、問題を整理しよう。実は、元記事主様が実現したいことは、4つに分割できる。以下、その4つの問題を見ていこう。

  1. 長い英単語PneumonoultramicroscopicsilicovolcanoconiosisやURL等)を折り返したい。
  2. 禁則処理はなるべく守りたい。例えば、閉じ括弧や句読点類(.,!?、。等)が行頭に来ないようにしたい(行頭禁則)。開き括弧は行末に来ないようにしたい(行末禁則)。
  3. 連続記号=連続句読点類=禁則処理対象記号の連続」」」」」」」!!!!!!!!等)は、折り返したい。
  4. テーブルセル内でも通用する方法であってほしい。

しかし、これら4つを一挙に解決する方法は、なかなか無いものだ。

一長一短すぎる各方法(元記事の要約)

  • overflow-wrap(word-wrap): break-word;
    1. 長い英単語:  ○
    2. 禁則処理:   ○
    3. !!!!!!!!!: ○
    4. テーブルセル: ×
  • word-break: break-all;
    1. 長い英単語:  ○
    2. 禁則処理:   ○
    3. !!!!!!!!!: ×
    4. テーブルセル: ○

この○×一覧を見て、「あーー!overflow-wrap(word-wrap)さん、いい所までいったのに、なぜ、なぜお前は、肝心のテーブルセルで無力なのか…セルさえ…セルさえ打倒できれば…」と思うのももっともだ。
前者は折り返し問題については満点で、本当に惜しい所まで行っている。一方、word-break: break-all;で×の付いた問題3は、厄介な「何があっても強制改行と言ったな?あれは嘘だ」問題をはらんでいる。その為、後者でなく前者をベースに解決法を練りたくなるのも無理はない。

そこで、前者で未解決の問題4を解決する為に、

(1) (元記事曰く)天真爛漫純粋無垢かつ無情なword-break: break-word;
(2) divタグ

の2方法を試した。

(1)のword-break: break-word;は、非常に惜しい存在だ。問題1~4が全て○のパーフェクトクリアなのだ。最強では!?!?!?そう思った。しかし… IE・Edge非対応の為、暫定解決方法としては除外せざるを得なかった。

(2)は、divタグによってdisplay: table-cell;の呪縛を逃れ、セル内に無理やりdisplay: block;な空間を作る事で、半ば無理やり問題4を解決している。これはうまい事機能するが、方法としては気持ち悪い為、「暫定」の域を出ない…

と、ここまでが元記事の内容だが、

実は天真爛漫な(1)には更なる欠点がある。
実はこのword-break: break-word;、非推奨なのだ。
https://jigsaw.w3.org/css-validator/ 等で確認すると、The value break-word is deprecatedと警告が出る。実はこのvalue、昔のものらしく、今後廃止される運命にあるようだ。IEやEdgeがこのvalueに対応してないのは別におかしな話ではなく、寧ろChromeが未だにこれをサポートし続けているのがおかしい、という事らしい。先程、「このvalueを発見した時、私も歓喜したものだ。しかし、後に解決方法から除外した」と言ったが、こういう事情なのだ。

つまり、(1)も(2)も、究極の解決法としては採用できず、道を断たれる。
※テーブルの場合は(3)としてtable-layout: fixed;も使えるが、テーブル以外では通用しない。

じゃあどうすれば?

新たな天使、line-break: anywhere;様のお出ましだ

先程の経緯により、overflow-wrap(word-wrap): break-word;の欠点を埋める方向での解決策は行き詰まった。

ならば原点に立ち返って、word-break: break-all;の欠点を埋める方向、つまり、「何があっても強制改行と言ったな?あれは嘘だ」問題に立ち向かえばいい。
その中核にあるのが、問題3( !!!!!!!!!問題)だ。

これは一見、無謀に思えたが、私はこの問題をChromeの開発者へ持ち込んでみた。
それがこちら(このコメントの読了前にリンク先を読むと混乱する為、今は読まなくていい):
https://ss1.xrea.com/ango.g3.xrea.com/jkkn/chrome_bug5.html
https://bugs.chromium.org/p/chromium/issues/detail?id=852313

すると、なんてこった。Chrome開発者側も(、実はCSSの仕様策定側も)この問題を承知であり、Chromeとしてはこの問題を
https://bugs.chromium.org/p/chromium/issues/detail?id=720205
として長年扱ってきたという。(その為、私のIssue 852313は、このIssue 720205にマージされた。)

そして、Chrome開発者側から問題3の解決方法として教えて頂いたのが、
line-break: anywhere;だ。ここでやっと、主役の登場である。

「何があっても強制改行と言ったな?あれは嘘だ」問題の黒幕

ここで、件の「4つの問題」を振り返ってみよう。

よく考えると実は、問題2と問題3には、相反する要望が含まれている事が分かるはずだ。
2は禁則処理を守りたがり、3は禁則処理を破ってまで強制的に折り返したがっている。
つまり、2と3は互いに矛盾し合う要望をはらんでおり、両立が難しい。

この矛盾、もとい"仕様や要望の競合"こそが、問題3、つまり「何があっても強制改行と言ったな?あれは嘘だ」問題の解決を難しくしている根本原因であり、黒幕なのだ。
CSSやブラウザを作っているWHATWGやGoogleの開発者も、実は長年、この矛盾問題や仕様策定に頭をひねってきた。

何故Chromeでは、word-break: break-all;!!!!!!!!!!に対して効かないのか。
つまり、何故Chromeでは、問題2と問題3が両立できないのか。
それは、以下のようなメカニズムで起こる。

禁則処理は本来、例えば行頭に,!等が来ないようにする為の処理だ。
そして、この処理を実装する為にはまず、この処理の対象になる記号類をブラウザが選定せねばならない。それが、件の,!等だ。

次にChromeは、この禁則処理を実装する際、
各対象記号から見て、それぞれ(行頭禁則なら)直前/(行末禁則なら)直後にある文字と強く強く結合させるように実装した。

例えば、「あいうえおかきくけこ。」という文字列があり、セルやボックスの幅がそれより1文字分狭い場合。
Chromeは、行頭禁則処理対象である「」の直前の文字、「」を見る。そして、Chromeはこの2文字、「こ。」を強く強く結合させる。そう、word-break: break-all;の優先順位を上回るほどの、強い結合だ。こうなると最早、Chrome上では「こ。」の2文字があたかも分割できない1文字であるかのような振る舞いを見せる。
結果として、1行目には「あいうえおかきくけ」だけが入り、「」が入る隙間を右端に残したまま、「こ。」が2行目に回る、という具合だ。こうして、2行目の行頭が「」になる事は防がれ、「」が行頭となる。

Chromeはこうして、禁則処理を実現している。これが、問題2の裏側だ。

一見これは、禁則処理の実装方法としては妥当のように思えるし、実際これはCSSの定める仕様書にも則った実装だ。その為、この実装方法はバグではなくChromeの仕様であり、将来変更される事はないだろう。
だがこのChromeの実装方法には、結合が連鎖し、結合部分全体が肥大化する可能性を考慮してない点に問題がある。

次の文はどうか。「あい。。。。。。。。。
上記のような実装をしているChromeは、この文字列に対し、以下のような処理をするだろう:

  1. 最後の「」は行頭禁則処理対象の為、その直前にある「」と強く結合させる。これで、最後の2文字「。。」が強く結合される。
  2. しかし、その直前文字自体もまた、禁則処理対象であるから、更にその1文字前の「」とも強く結合させる。この時点で、最後の3文字「。。。」が強く結合された。
  3. 同じようにして、「」までもが、結合対象に組み込まれる。
  4. 結果としてChromeは、「い。。。。。。。。。」をまるごと強く結合させ、あたかも1文字であるかのように扱う。
  5. セルやボックスの幅が、文字列全体よりも1文字分狭かった場合、"2文字目"である「い。。。。。。。。。」は入りきらない。その為、1行目には「」だけが残され、残りの「い。。。。。。。。。」は全て、2行目に回されてしまう。
  6. もしも、全体の幅が「い。。。。。。。。。」自体よりも狭かったとしても、Chromeは「い。。。。。。。。。」を1文字かのように扱うので、レイアウト崩れを起こしてでも無理やり「い。。。。。。。。。」を死守する。

例では「」を取り上げたが、「!」に対しても全く同じだ。上記例では、禁則対象以外の文字で2行目に回された文字は、「」のみ。これは、元記事サンプルの「現実はかくも無情!!!!!!!!!!!」の「」までが1行目に残り、「」以降が2行目へ折り返される挙動と一致する。

こうして、問題3、つまり!!!!!!!!が折り返せない問題が発生してしまうのだ。

問題2を実装する為に、Chromeは結合システムを作った。しかし、その結合ベースな実装方法が、問題3と競合矛盾し合う。これが、さっき「問題2と3が相反する」と言った真意だ。

この原因は何か? 勿論、このChromeの実装方法、つまり、強すぎる禁則結合の多重連鎖に原因がある。

しかし、さっきも言った通り、この実装はCSSの仕様に反してはいない。どういう事か。
CSSの仕様では、禁則処理対象の記号が連続した場合、つまり「。。。。。。。。。」や「!!!!!!!!!!!」が現れた場合の挙動について、明記していない。つまり、CSSの仕様自体が曖昧なのだ。そのせいで、その曖昧な部分の実装方法は、実際のブラウザ開発者に委ねられたのだ。

Chromeと違う実装方法をとっているのが、Firefoxだ。Firefoxはこの件に関してはとても賢い実装をしていて、行頭に対象記号が来るのを防ぐと同時に、うまいこと良しなに連続記号をも折り返してくれる(恐らく、対象記号の結合相手を対象記号以外に限定してくれている為、結合連鎖が起こらない。賢い)。
その為、Firefoxではword-break: break-all;単体で、問題2と問題3の解決を両立できる。

つまり、問題2と問題3が矛盾し合う問題が起こるのはChromeだけ、という事になるが…

改めてこの問題の原因を問おう。原因は何か?
直接の原因は勿論Chromeのくだんの実装方法なのだが、
間接的な原因として、CSSの仕様の曖昧さがある、という事なのだ。

そもそも、line-breakプロパティ is 何

禁則処理に関して仕様に曖昧さが残っていると発覚したCSSには、新たにline-breakというプロパティが追加された。
禁則処理の挙動を明確に決める為、line-breakは誕生したのだ。

これは元々IE等に独自実装として昔からあったが、Chromeがline-breakに対応したのはChrome 58、Firefoxに至ってはFirefox 69である。つまり、標準仕様としてはかなり後発組のプロパティである事が分かる。

つまり、line-breakは禁則処理の挙動を指定する専用のプロパティだ。
このline-breakこそが、「。。。。。。。。。」や「!!!!!!!!!!!」をぶっ壊すかどうかを指定できる権限を持つ、唯一にして待望のプロパティなのだ。

となると、CSSではword-breakoverflow-wrap/word-wrapとは別に、
禁則処理を扱うプロパティとしてline-breakも用意している、という事になる。

仕様がどんどん複雑化してやがる。しかし、おかげで問題3の解決の糸口が見えたというもの。

このline-breakがとりうる値は、autoloosenormalstrictanywhere
詳しい挙動の説明は端折る(というか私も把握しきれていない)が、大体こうだ:
strictは一番禁則処理が強く、normalは普通、looseが緩め、anywhereは禁則処理の完全解除だ。

ここで私が知りたいのは、「!!!!!!!!!!!」を壊せるかどうか。
anywhereこそが、私たちの求める最強のものだろう。禁則処理の完全解除なのだから、「!!!!!!!!!!!」は確実に折り返せる。
少なくともFirefoxは、この全ての値を実装してくれており、Firefoxのline-break: anywhere;は理想通りに動いてくれる。

しかし、Chromeは長年、autoloosenormalstrictしか実装してくれていない。肝心のanywhere様が、Chromeには長年無いのだ。
そこで、次に緩いlooseに希望を託すわけだが、なんと…禁則処理緩めのはずのlooseでさえ、「!!!!!!!!!!!」を壊す事はできなかったのだ。「!!!!!!!!!!!」を壊せるのはanywhereだけらしい。
これが、先程の
https://bugs.chromium.org/p/chromium/issues/detail?id=720205
の内容だ。このIssueのタイトルは「Implement 'line-break: anywhere'」、つまり「(現状のChromeでは実装できていない)line-break: anywhereを実装する」事を目標としたIssueだ。

私がこのIssueに働きかけた結果、長年保留状態だったこのIssueは動き出し、現在はなんとFixedになっている。という事は、2020年現在のChromeでは、バッチリanywhereできるはず。

しかし…あれ?未だ機能しない。これはどういう事か。

実は2020年現在、Chromeのline-break: anywhere;は、chrome://flagsからExperimental Web Platform featuresフラグをEnabledにしないと使えるようにならない。つまり、実装されたはされたが、未だChromeとしてはline-break: anywhere;を実験段階としているのだ。

一応フラグを有効にして試すと、なんと理想通りに動く。やったじゃん。これで、!!!!!!!!!は折り返される。しかもこいつは最強だ。セル内でも有効なのだ。問題4まで一挙に解決だ。
word-break: break-all;line-break: anywhere;の合わせ技で、なんと問題1~4まで全解決だ(厳密には問題2を犠牲にしているが、折り返し問題完全解決という意味で有意義だ。そもそも、前述の仕様矛盾・実装競合の話を考えれば、問題3解決の為には問題2を犠牲にせねばならない事はもう分かるだろう)。

しかし、どうやらChrome開発者側は、anywhereの実装についてまだ突き詰められていない問題があるらしく、まだanywhereを正式リリースしたくないらしい。
冒頭で

悲しいかな、正確には「将来究極になる予定の」

と言ったのは、こういう事情だ。

とはいえ、いずれanywhereが正式リリースされるのは期待できる。
また、念の為overflow-wrap/word-wrapの方も併用して、

word-break: break-all;        /* 当記事と同じ */
overflow-wrap: break-word;    /* 〃 */
word-wrap: break-word;        /* 〃 */
line-break: anywhere;         /* 見慣れない。 */

とする事で、なんと完全理想の文字折り返しが実現するのだ。
これこそが、先程の「私のたどり着いた究極の解決方法」のうち、最初の4つだ。

ただ、実はこの話、更に続きがある。
残る2つ、5・6番目のwhite-space達についてだ。

これで、折り返しの敵を全て倒せたのか?いいえ、まだ空白類があります

※以降は、連続する空白類をそのまま表示したい場合、つまり、
連続空白を表示する為にwhite-space: pre-wrap;を指定した時の話だ。
デフォルトのまま、空白類を切り詰めた表示のままでいいのなら、以降は読まなくてもいい。

貴方は知っていただろうか…

連続する空白類は、連続する句読点類(!!!!!!!!!!!!!!!!等)よりも更に屈強なのだ。
連続した半角空白、つまり、width指定を超えるほどの長い連続空白を含む「a                     bcde」のような文字列に対しては、line-break: anywhere;ですら無力なのだ。
※このコメント欄には連続半角空白を打ち込めないため便宜上全角空白で書いてあるが、実際には半角空白。

どのように表示崩れが起こるのかというと、
a                     」の部分が折り返さずに右に突き抜け、連続空白の終わった直後の「bcde」が次の行頭に来てしまう。

つまり、括弧や句読点類だけでなく、半角空白も行頭禁則処理の対象となっており(半角空白も行頭に来ないよう処理されており)、しかもその制御にline-break: anywhere;が効かないのだ。空白類への禁則処理は、別個に行われているようだ。
言われてみれば、HTMLで行頭に半角空白を見た事がない。
そして、どうやらline-break: anywhere;は空白類に関しては管轄外らしい。

「これでは、幅を超えるほどの大量の連続半角空白を入力された場合のレイアウト崩れを防げないではないか!line-break: anywhere;は、半角空白に対しても効くべきでは?それともこれは仕様か?仕様ならば、回避策は用意されてないのか?」と思い、これもChrome開発者へ報告した。それが以下だ:
Sample: https://ss1.xrea.com/ango.g3.xrea.com/jkkn/chrome_bug14.html
Issue: https://bugs.chromium.org/p/chromium/issues/detail?id=966773

すると今度はChrome開発者側から、
更なる新たなCSS、white-space: break-spaces;を教えて頂いたのだ。驚愕だ。

従来からあるwhite-space: pre-wrap;は、空白類を詰めずにそのまま表示する代わりに、行末の空白類については次の行頭に折り返さずに無理やりはみ出させる挙動をとる。wrapとか言うくせに、空白類についてはそうじゃなかったのだ。
break-spacesは、このはみ出しを防いでくれる。それ以外の挙動はpre-wrapと一緒だ。

これが、冒頭の「究極の解決方法」の6行目white-space: break-spaces;の意味だ。

しかし、break-spacesline-break以上に新しいもので、2020年1月時点では非対応ブラウザの方が多いくらいだ。Chromeでも、Experimental Web Platform featuresフラグを有効にしないと使えない。その為、非対応環境の為にwhite-space: pre-wrap;を併記した方がいいだろう。それが、冒頭の「究極の解決方法」の5行目の真意だ。

纏めると、

CSSでは、word-breakoverflow-wrap/word-wrapとは別に、
括弧や句読点等(但し空白類は含まない)の禁則処理を扱うプロパティとしてline-breakが用意され、
更にそれとは別に、
空白類の禁則処理を扱う値としてwhite-space: break-spaces;も用意されている

という事になる。複雑怪奇。


以上が、私が折り返しとCSSと闘った全貌だ。長々と済まぬが、情報共有したい。

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

divとspanの違いってなんですか??

HTMLのdivタグとspanタグの違い、以前受講生に質問されて苦い思いをしました:confounded::sweat_drops:
この機会にマスターします!

1. 何度でも復習!そもそもタグってなに?

HTMLは、とにかくタグでテキストを挟むのが大好き!変態や...!
開始タグ終了タグで挟まれたテキストは、そのタグの命令を聞かなければいけない:scream:
つまり、挟むタグの種類によって、なんの変哲もないテキストの役割は変わるのです。

書き方: <タグ名>テキスト</タグ名>

2. でも注意!divもspanも意味を持たないタグ!?

先ほど述べたように、タグは種類によって役割が違います。
例えば・・・
・pタグなら段落を表す
・h1タグなら見出しを表す
だけどdivタグとspanタグときたら、
彼らはタグ自体に意味を持たない、つまり何も表さないタグらしいんです!

3. じゃあ一体どんな役割があるのかな?

:star:divタグ編
結論、divタグは囲った部分を、ブロック要素としてまとめて扱うことができるのです:point_up:

どうゆうことかというと・・・

<h1>渡邉貴恵とは</h1>
<p>私は福島県出身の24歳です</p>
<p>皆さんよろしくお願いします!</p>

というコードを、<h1>タグと<P>タグごとに一つのブロック=まとまりとして認識して色分けを行いたい時・・・

<div class="one">
<h1>渡邉貴恵とは</h1>
</div>

<div class="two">
<p>私は福島県出身の24歳です</p>
<p>皆さんよろしくお願いします!</p>
</div>

こんな風に、divタグを使ってまとめることで、各々に違うcssを当てることができるようになるのです!
またdivタグでまとめた部分はmarginやpaddingなどのレイアウトや、width、heightなどのサイズも自由に決めることができるみたい!
確かに思い返せばそうだったなメモメモ...:pencil2:

:star:spanタグ編
divタグではブロック要素ごとに認識され、レイアウトやサイズなどの装飾を加えることができたけど・・・
spanタグでは行の一部ごとのまとまり、つまりインライン要素として認識され、その各々にcssを当てることができるのです:point_up:

詳しく見て行きましょう
例えば・・・

< 私の名前は"渡邉貴恵"でございます >

この"渡邉貴恵"の部分だけを赤く装飾したいよー!って時に、

 <p>私の名前は
   <span class="aka">渡邉貴恵</span>
  でございます</p>

こんな風に装飾したい行の一部分だけをspanタグで囲めば、
なんと!!!
.aka{color:red}
ほら、これでようやく愛しのcssを当てて赤く装飾することができるでしょ:sparkles:

つまり<span class="クラス名"> テキスト </span>で挟んだテキストだけをピックアップして、文字の色や太さを変えたい時に使えるよ!


:hatching_chick:まとめ:hatching_chick:
divタグは、テキストを挟むことで大きなまとまりとしてブロック化(=ブロック要素)し認識させることで、レイアウトやサイズを指定をすることができる。
spanタグは、テキストの行の一部分を挟むことで小さな行のまとまり(=インライン要素)として認識し、文字の色や太さの装飾を加えることができる。

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

liタグの中のaタグ要素を縦方向にセンタリングする方法についての質問

liタグで作ったaタグ要素のテキストをborderの大きさに合わせて縦方向にセンタリングしたいのですが、上寄せとなってしまいます。
よろしくお願い致します。

<head>
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" integrity="sha256-UzFD2WYH2U1dQpKDjjZK72VtPeWP50NoJjd26rnAdUI=" crossorigin="anonymous" />
</head><!--font-awesomeのCDN-->

<div class="class_name">
 <li>
  <a><i class="far fa-question-circle"></i>テキストテキスト</a>
 </li>
</div>
.class_name {
  li {
    border: 1px solid grey;
    border-radius: 3px;
    list-style: none;
    width: 80%;
    height: 50px;
    margin: auto;
    text-align: left;
    padding-inline-start: 0px;
    margin-bottom: 5px;
  }
  i{
    color:blue;
  }
  a{
    font-size:18px;
  }
}

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

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

100日チャレンジの290日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
290日目は、

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

IPアドレスについて学びましょう!

サーバーに関する備忘録として記述します。

サーバーを理解しよう!

IPアドレスを理解するにはサーバーについて理解する必要があります。

サーバーとは?

サーバーとは、サービスを提供するコンピュータのことやコンピュータにある様々な機能のことです。もっと簡単に言うと、ある特化した機能を使うためだけのパソコン、または何かに特化した機能自体の事だと思って下さい。

サーバーが必要な理由

前提として、自身のパソコンだけでもサーバーが行うことを全て行うことが可能です。
それを踏まえた上で、サーバーが必要である理由が以下の3点となります。

・サーバーをバックアップとしてデータを保存しておけば、自身のパソコンが壊れた際にデータを復旧することができる。
・外部のクライアントと接続する機能をサーバーに任せることによって、自身のパソコンの負担を減らすことができる。
・上述の接続機能の例のように、サーバーと自身のパソコンで役割分担をすることによって、自身のパソコンでアプリケーションの開発に集中することができる。

サーバーの役割

サーバーの役割は様々ですが、主に以下のような役割があります。

・様々なデータを管理・保存をする(データベースサーバー)
・パソコン同士の通信を行う(WEBサーバー)

様々なデータを管理・保存する役割はデータベースサーバーが担います。Webアプリケーションとは違うサーバーでデータベースの管理を行うことによってサーバーへの負担を減らします。

パソコン同士の通信を行う役割はWEBサーバーが担います。

Webサーバー

WEBサーバーとは、スマートフォンやパソコンから送られきたリクエストに対して、リクエストに合ったレスポンスを返す仕組みを持ったコンピュータ(ハード)やソフトウェアのことを指します。
このように WEBサーバーは、利用者の送ったリクエストに対して、情報を処理し、レスポンスをする役割を持ちます。

そして本カリキュラムではWEBサーバーが情報を貰ったり送ったりするために必要な「IPアドレス」について学習をしたいと思います。

IPアドレスとは?

IPアドレスとはコンピュータやサーバーに設置された住所のようなものです。コンピュータが他のコンピュータやサーバーにファイルやメールを送受信するときに宛先として利用されます。

IPアドレス例

具体的にどのようにコンピュータに住所を設定するのか、例を見ながら確認していきましょう。
IPアドレスは「183.79.139.228」のように表現されます。この数字の集まりが住所になります。それぞれの数字は0-255までの値を取るので、全パターンは約42億通りになります。(256の4乗)

image.png

IPアドレスの現状

現在このIPアドレスはIPv4と呼ばれるものです。近い将来IPアドレスは足りなくなると言われています。対策としてIPv6という新しいバージョンへの移行が進んでいます。IPv6ではIPアドレスを16進法で表し、例えば「2001.0db8.1234.5678.90ab.cdef.0000.0000」となります。こちらは3.4×10の38乗であるのでほぼ無限に使えます(例えば1兆は10の12乗です)。しかし、IPv6が世界全体で対応するためにはあと何年もかかるようです。

IPアドレス(IPv4)の問題点

ただしIPアドレスの個数は限られており、利用者が好き勝手に利用することはできません。そのため一般家庭で「△△光回線」などのインターネット契約をするとISP(インターネット・サービス・プロバイダ)から自動的にIPアドレスが付与されます。これは接続していないと自動的に変化していき、限りあるIPアドレスを回線利用者で使いまわしている状態になります。IPアドレスを利用するためにはISPから毎回利用許可を貰わないといけません。これでは企業や学校での利用などコンピュータの個数が変動する場合に手間がかかります。
このようなことを解決するために、グローバルIPアドレスプライベートIPアドレスという仕組みが生まれました。

グローバルIPアドレスとプライベートIPアドレス

数が限られ、制限がるIPアドレスですが、グローバルIPアドレスとプライベートIPアドレスによってその問題を解決しました。各々のが何で、どのような仕組みであるのかを学習していきましょう!グローバルIPアドレスとプライベートIPアドレスを理解するためにはルーターの知識も必要なため合わせて記述していきます。

グローバルIPアドレスとは?

インターネットに接続する際に使用されるIPアドレスのことを指します。インターネットに接続している機器のそれぞれに割り振られる番号(現在は上記したように「183.79.139.228」のような3桁の数字×4)になります。
家の住所や電話番号のようなイメージです。例えば「東京都渋谷区○○町××~×,△△マンション」はこの世に一つしかないようにグローバルIPアドレスもこの世に一つしかありません。

グローバルIPアドレスは、「△△光回線」などのインターネット契約をするとISP(インターネット・サービス・プロバイダ)から自動的にグローバルIPアドレスが1つ付与されます。また、グローバルIPアドレスのことをWAN(Wide Area Network)とも呼びます。

プライベートIPアドレスとは?

プライベートIPアドレスとは、ISPから自動的に割り振られたグローバルIPアドレスをさらに小分けにしたIPアドレスです。グローバルIPアドレスの「東京都渋谷区○○町××~×,△△マンション@@号室」の住所例で言うと「@@号室」がプライベートIPアドレスです。プライベートIPアドレスはLAN(Local Area Network)とも呼びます。

プライベートIPアドレスは、以下のような3つに分けられます。
- クラスA:10.0.0.0~10.255.255.255
- クラスB:172.16.0.0~172.31.255.255
- クラスC:192.168.0.0~192.168.255.255

クラスAは大規模ネットワーク、クラスBは中規模ネットワーク、クラスCは小規模ネットワークで使うプライベートIPアドレスです。ルーターはクラスCを使うため「192.168.0.0~192.168.255.255」の65536通りあります。ルーターとプライベートIPアドレスとグローバルIPアドレスを併用すると65536×42億個のプライベートIPアドレスが存在できるということになります。

ルーターとは?

ルーターとは、インターネットと「家庭や会社にある複数のパソコン」間で通信を行うときに必要となる機器です。グローバルIPアドレスの「東京都渋谷区○○町××~×,△△マンション」の住所例で言うと、ルーターは個人の部屋に入るためのドア(入り口)のイメージです。マンションの中に入ると住民それぞれの部屋があるように、グローバルIPアドレスからルーターを通すと、グローバルIPアドレスではなくプライベートIPアドレスの領域になります。ルーターは、グローバルIPアドレスからプライベートIPアドレスへスイッチする役割を持っています。ルーターは、グローバルIPアドレスと後述するプライベートIPアドレスの両方を持っています。

image.png

プライベートIPアドレスについて補足ですが「192.168,x,y」となっていますが「x」はルーターのメーカーを表し、「y」はそれぞれのパソコンによって違います。そのため一つのルーターが割り振れる番号は256通り(「y」の分だけ)です。また、ルーターはパソコンの再起動や回線が切れるごとに「y」を切り替える機能もあります。
ルータがyを切り替えることにより、ルーターが割り振る番号の消費を抑えています。
例えばTECH::CAMPの教室にいない人のパソコンに対して固定のプライベートIPアドレスを設定してしまうと256人しかwi-fiを繋ぐことができません。そのため、ルーターが必要に応じてプライベートIPアドレスの数を減らしたり増やしたりします。

ドメインとDNSとは?

グローバルIPアドレスとプライベートIPアドレスの使い分けによってIPアドレスの利用可能数は節約できましたが、まだ問題があります。
例えば、「52.196.209.128」といわれてもそれがTECH::CAMPのサイトであるとは分かりませんよね?
そのためにドメインとDNSが誕生しました。

ドメインとは?

ドメインとは、IPアドレスを文字列に変換したものです。TECH::CAMPのページのIPアドレスは、「52.196.209.128」です。IPアドレスで検索することでTECH::CAMPを表示することができますが、TECH::CAMPのページを見ようとする度にIPアドレスを覚えておくのは大変です。そこで、数字よりも覚えやすい文字列をIPアドレスに割り当てることにしました。これがドメインの誕生です。

またこのように「IPアドレスを文字列化する仕組み」のことをDNS(Domain Name System)と呼びます。
IPアドレスに比べドメインは無尽蔵に組み合わせられるので、IPアドレスを取得するよりも簡単で個人でも購入することができます。

URLから見るドメイン

TECH::CAMPのドメインを例にあげてみていきましょう。https://tech-camp.in/
この内ドメインに当たるのはtech-camp.inです。ドメインは、.(ドット)の前後で「tech-camp」と「in」に分けられます。
「in」をトップレベルドメインと呼びます。トップレベルドメインは、他にも「.com」や「.jp」などがあります。ドメインを取得するにはトップレベルドメインがなければいけません。
「tech-camp」をセカンドレベルドメインと呼びます。セカンドレベルドメインに関しては早いもの勝ちです。同じセカンドレベルドメインが先に使われていた場合は、使うことができません。

IPアドレスを調べてみよう

実際にドメインに紐づいたIPアドレスを確認してみましょう!ドメインからIPアドレスを調べるためにはdigというコマンドを使用します。

digコマンド

digコマンドは、ドメインを管理しているサーバー(DNSサーバー)に問い合わせをしてドメインからIPアドレスを取得し表示するコマンドです。digは、「domain information groper」の略です。

DNSサーバー

IPアドレスとドメインのそれぞれの組み合わせを管理・保存しているサーバーです。

DNSサーバーの場所

DNSサーバーは様々な場所に存在します。身近なところでいうとルーターの中に存在する可能性があります(機種によってない場合もある)。
またはIPアドレスを配布しているISP(インターネット・サービス・プロバイダ)内にもあります。

digコマンドを使ってIPアドレスを調べましょう!

ターミナルでdigコマンドでIPアドレスを調べましょう!

dig master.tech-camp.in
$ dig master.tech-camp.in

; <<>> DiG 9.8.3-P1 <<>> master.tech-camp.in
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64426
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;master.tech-camp.in.       IN  A

;; ANSWER SECTION:
master.tech-camp.in.    3265    IN  A   52.196.209.128

;; Query time: 66 msec
;; SERVER: 192.168.179.1#53(192.168.179.1)
;; WHEN: Tue Oct  4 23:49:29 2016
;; MSG SIZE  rcvd: 53

このような実行結果が返ってきます。IPアドレスは、ANSWER SECTIONという部分に記載されています。テックマスターのIPアドレスは、52.196.209.128ということがわかります。

ポートについて学習しよう

ポートとは1つの「サーバーと複数のサーバーを繋げるものです。それぞれのサーバが番号ごとに管理されていて、リクエストに応じてそれぞれの番号(つまりサーバ)へつなぐ橋渡しをする役割を持っています。ポートが割り振る番号には、0から65535まで使うことができます。しかし、0から1023までの番号はよく使われるもので予約されていて自由に使うことはできません。
WEBサーバはリクエストを受け付けたり、データを送信したりするのが主な仕事ですが、これ以外にもデータベースサーバや、SSHコマンド受け付けるためのSSHサーバ、メールを送受信するためのメールサーバなどいろいろなサーバがあります。

そこで1つのサーバで複数のサーバを起動するためにポートという仕組みがあります。

image.png

なぜポートが必要なのか?

一般的なサーバは1つのIPアドレスしか持っていないことがほとんどで、このIPアドレスをWEBサーバで使ってしまうと、他のサーバとして動作することができません。
例えば、WEBサーバなら「80」、SSHなら「22」、メールサーバなら「3306」などはすでに決まっています。既に利用されているポートは利用することができずにエラーになります。
Ruby on Railsでサーバーを起動するときは「3000」ポートを使うことが多いです。既に3000ポートが使われている場合や複数のサーバを起動したい場合は、rails server -p 3001のようにすることで別のポートでサーバを起動することができます。
このように、コンピュータが通信する場合はどのIPアドレスのどのポートに接続するか、というようにIPアドレスとポートのセットで考えます。

WEBサーバの動作をポートを使っておさらいしよう

一度WEBサーバについては説明しましたが、ここではポート踏まえてWEBサーバの動作について説明します。
WEBサーバでは一般的には以下の様な動作を1秒間に数千回行なっています。

1.「80ポート」でHTTPリクエストを受け付ける
2. リクエストに応じた処理や、要求されたファイルを探す
3. リクエストしてきたコンピュータに返送する

ここでいう「HTTP」はWEBサーバに情報を送るための通信規約、つまり約束事です。
次にHTTPについて詳しく説明したいと思います。

HTTPとは?

Webページやページ内で必要なCSS、JavaScript、画像などのファイルをWEBサーバーにリクエストするためのファーマットです。具体的には、「http://~」あるいは「https://~」で始まるURL(Uniform Resource Locator)/URI(Uniform Resource Identifier)という形式で送られます。
皆さんがブラウザにURLを入れたり、リンクをクリックしているときに、自動的にブラウザがHTTPのフォーマットに従ったリクエストを作成して、サーバにリクエストしています。

コマンドでホストに接続してみよう

ターミナルから「TECH CAMPのホームページ」に接続することを例としてブラウザが裏で処理しているか、コマンドを使って手動実行してみましょう。ホストに接続するには、telnetコマンドを使用します。

telnetコマンド

telnetコマンドは、離れたところにあるホスト(サーバやネットワーク機器)を手元の端末から遠隔操作するために、ネットワーク接続するコマンドです。

作業手順

①URLバーに「https://tech-camp.in」と入力する
②TECH CAMPのTOPページが表示される

手順

①digを使ってhttps://tech-camp.in のIPアドレスを調べる
②telnet でリクエストしてみる

dig tech-camp.in +noedns

以下の部分を確認しましょう!

;; ANSWER SECTION:
tech-camp.in.       11  IN  A   13.230.191.243 

たくさん情報が出てくると思いますが、「ANSWER SECTION」だけに注目してください。(実際のIPアドレスは異なることがあります。)

次にtelnetを使うのですが、ブラウザで Webページを開く際、ブラウザはサーバに下記のような要求メッセージを送信します。

$ telnet <dig tech-camp.in +noednsで表示されたIPアドレス> 80
# 例えばIPアドレスが「13.230.191.243 」であれば、「telnet 13.230.191.243  80」となる
brew install telnet

telnetを実行すると

Trying 13.230.191.243...
Connected to ec2-13-230-191-243.ap-northeast-1.compute.amazonaws.com.
Escape character is '^]'

上記のような結果が返ってきます。トップページが取得できました。

最後に以下のようにGET / HTTP/1.0を追記し,ENTERを2回押してください。

Trying 13.230.191.243...
Connected to ec2-13-230-191-243.ap-northeast-1.compute.amazonaws.com.
Escape character is '^]'.
GET / HTTP/1.0

実行すると、ターミナルにトップページのHTMLが返ってくると思います。

HTTP/1.1 200 OK
Date: Wed, 08 Jan 2020 02:27:38 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 29951
Connection: close
Server: nginx/1.10.1
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
ETag: W/"faa286c66f8e354025a495a0fe7282a7"
Cache-Control: max-age=0, private, must-revalidate
Set-Cookie: _tech-camp%E3%80%80-d_session=S3FUMkREYkFLcXB4OTBOb01NS1pPa2pEb3duWVlUM2tCZ0U3Sys5QU45UXdTQXVnL2lhcmFCdHdSSGw3TkFxVTJRWXJZV0FpK2xTdHZlditwNHhhUk01SU12YzZwWk9Md1lqbU9YeDRKM1NvY09mSUlJVGRia3dEc0NVVjE2elVaVUxTRDdranU5MzZSdjNnY3NLUkVRPT0tLWJSS2V3empPMFowVUM0NzRNNUtiQlE9PQ%3D%3D--573b3947da1245e8d5bdba7702e497fc081fa692; path=/; HttpOnly
X-Request-Id: 58c478f2-48f5-4ab3-8443-5d4d44c8a2fa
X-Runtime: 0.012434
Vary: Origin
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff

<!DOCTYPE html>
・
・
中略
・
・

<!DOCTYPE html>より上の部分がhtmlの「レスポンスヘッド(headタグ)」の部分でそれ以降が「メッセージボディ(bodyタグ)」の部分に当たります。
中略の部分は「bodyタグ」になっているので、試して確認してください。
今回は最後に「レスポンスヘッド(headタグ)」について確認します。

レスポンスヘッドとは?

レスポンスヘッドとはHTMLで学習したheadタグと同じです。「メッセージボディ(bodyタグ)」で足りない情報をメタ情報として記述しています。
ここでいうメタ情報とは、「データに関する補足情報」と思ってください。次に上から順に詳しく見てみましょう。

HTTP/1.1 200 OK

レスポンスが成功した際に表示されるものです。

Content-Type

HTMLファイルに使用している文字コードを示しておき、文字化けや誤動作を回避するために書いてあります。

P3P

P3Pはサイト運営者が個人情報を保護しながら、ユーザーが自分の情報をどの程度Webサイトに提供するかをコントロールできるようにする技術仕様です。
例えば、cookie(WEBサーバーがユーザーを認識する仕組み)を使うとユーザーのアクセス情報を収集することができます。(それを通じて無駄なく広告を打つことが可能です。)
しかし、プライバシーの観点からそれを保護する動きが高まりました。
それをP3Pを導入することによってユーザーの必要ない情報を受け取れないようにしています。

X-Content-Type-Options: nosniff,X-XSS-Protection: 1; mode=block,X-Frame-Options: SAMEORIGIN,X-XRDS-Location: ,

XXS(クロスサイトスプリング)によってCookie等の情報が盗まれないようにするためのものです。

Vary: Accept-Encoding,Expires: -1,Pragma: no-cache,Cache-Control:

こちらはキャッシュを残すためのものです。
キャッシュとは、使用頻度が高いデータを複製し記憶装置に蓄えられるものです。キャッシュを利用することによってより早いページの更新を行うことができます。

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

ページトップボタン

以下のようなページトップボタン(ページの右下当たりにあって、クリックすると一番上に戻ってくるやつ)を実装します。

image.png

まず、ボタンを置きたいhtmlに以下をコピペ

index.html.erb(など)
<p id="pagetop"><a href="#">↑ </a></p>

これがページトップの指令になります。

次に以下を該当cssファイルにコピペしましょう。

tweets.css
/*ページトップ設定*/
#pagetop {
  margin-right: 10px;
    clear: both;
    padding-bottom: 40px;
}
#pagetop a {
    color: #FFF;        /*文字色*/
    font-size: 20px;    /*文字サイズ*/
    background: grey;   /*背景色*/
    text-decoration: none;
    text-align: center;
    display: block;
    float: right;
    border-radius: 30px;    /*角丸のサイズ*/
    width: 50px;
    line-height: 50px;
}

良い感じになるかと思います!

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

フォームの作り方

input要素

input要素は1行のテキスト入力の要素です。
※input要素は終了タグが不要です。
【例】

<form>
 <p>テキスト入力</p>
 <input>  #終了タグは不要
</form>

textarea要素

textarea要素は複数行のテキスト入力の要素です
【例】

<form>
 <p>テキスト入力</p>
 <textarea></textarea>
</form>

送信ボタン

送信ボタンにも、input要素を使います。
input要素にtype属性を指定でき、type属性にsubmitを指定すると、入力欄ではなく、ブラウザに設定されている言語で送信ボタンが表示されます。
日本語のブラウザではデフォルトで「送信」になります。
テキストを変更するには、value属性に値を指定することで、ボタンに表示されるテキストを変更することができます。
【例】

<form>
 <p>テキスト入力</p>
 <textarea></textarea>
 <input type = "submit" value = "送信します">
</form>

classを指定する場合

<input class = "sample-submit" type = "submit" value = "送信します">
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む