20191205のCSSに関する記事は21件です。

FontFamilyでフリーフォントを使いたい

経緯

FontFamilyで宣言できるFontの種類ってどれも似たり寄ったりでつまんない!!
シャレオツな文字使いたい!!
フリーフォント表示してくれ!!

手順

1.使いたいフリーフォントをダウンロードする

まずは自分の気に入ったフォントをダウンロードします!
僕が検索に使ったサイトはこれ
フォントフリー
(今回僕は「切り絵字フォント」をダウンロードしました)
ダウンロードしたフォントファイルはttf形式になっていると思いますが、これをwoff形式に変換します。
ちなみに、woffとはWeb Open Font Formatのことで、Webページ埋め込み用フォーマットでWebフォントとして使われるために作られたフォントファイル形式です。ほとんどのブラウザで使用できるようです。

2.ダウンロードしたフォントファイルをwoff形式に変換する

以下のサイトで公開しているWOFFコンバータをダウンロードして、先ほどダウンロードしたttf形式のフォントファイルをwoff形式に変換します。

WOFFコンバータ

3.CSSでフォントを指定する

あとは先ほど変換したフォントファイルをCSSで指定するだけ!
@font-face{
font-family: 'SyareotuFont';
src: url('./kirieji.woff') format('woff');
}

@font-faceで読み込むフォントを指定します。
次にそのフォントファミリーを好きな名前に名付けたら完成です!

あとは適用させたいタグやIDにチョチョイとフォントファミっちゃってください⭕️

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

CSSでカレーパンマン作った

そうだ、おそれないで

カレーアドベントカレンダーと言いつつ、カレーを絡めた記事が1つだけというサボりをしたわけですが、
やっと、、カレー出てきます

何作ったの

カレーパンマン作りました。
頑張ったところ褒めてください。

......(アウトプットするだけでも)褒めてください。

See the Pen カレーパンマン by Thugumi Ishimaru (@thugumi-ishimaru) on CodePen.

頑張ったところ

カレーパンマンの口の波線

波線のいろんなやり方を試しました。

divを4つ作るまではやった。話はそこからだ。

カレーパンマンの口の波線を表現するために、まず、波線を表現するためのdivを4つ作りました。

スクリーンショット 2019-12-05 22.31.55.png

鎖。。。。。。
(border-radiusで楕円形にしています。今回は省きます。)

<div class="curryPanMan_mouce">
   <div class="curryPanMan_mouceItem"></div>
   <div class="curryPanMan_mouceItem"></div>
   <div class="curryPanMan_mouceItem"></div>
   <div class="curryPanMan_mouceItem"></div>
</div>

そこから、CSSでいくつかやり方はあるのですが今回2種類ほど試しました。

オーバーレイする用のdivを用意して、愚直に重ねる方法

  • 1.口をオーバーレイするdivを用意する
    • 例:div.curryPanMan_mouceHide
  • 2..curryPanMan_mouceHideを下部が丸くなるように修正
  • 3.用意した4つの波線用の口の上にちょうど重なるように.curryPanMan_mouceHideを移動させる
1.オーバーレイするdivを用意

.curryPanMan_mouceと並列に配置しました。

<div class="curryPanMan_mouce">
   <div class="curryPanMan_mouceItem"></div>
   <div class="curryPanMan_mouceItem"></div>
   <div class="curryPanMan_mouceItem"></div>
   <div class="curryPanMan_mouceItem"></div>
</div>
<div class="curryPanMan_mouceHide"></div>
2. .curryPanMan_mouceHideを下部が丸くなるように修正

以下のcssを書きます。

$curryMan:#E06B31;

.curryPanMan_mouceHide {
  width: 100%;
  height: 50px;
  background: $curryMan;
  border-bottom-left-radius: 50%;
  border-bottom-right-radius: 50%;
}

スクリーンショット 2019-12-05 22.25.55.png

こんな感じのができたので、重ね合わせます。

3. 融合

ついに、この鎖と融合します。
スクリーンショット 2019-12-05 22.31.55.png

合体

スクリーンショット 2019-12-05 22.31.40.png

これが実装方法1つ目

波線用のdiv1つ1つに擬似要素を用意して、色を重ねる方法

  • 1. 用意した4つの口に擬似要素を用意する
  • 2. 擬似要素を1つ1つの口に重ねる

やってみよう

1. 用意した4つの口に擬似要素を用意する

擬似要素を用意します。
今回はbeforeでやります。

まず、擬似要素の親に対してposition:relativeを指定してあげます。
次に、擬似要素に対して、position: absoluteを指定し、親子関係を明確にしておきます。

この時点でこんな感じ

スクリーンショット 2019-12-05 22.41.04.png

.curryPanMan_mouceItem {
    border: solid 8px #333;
    width: 100px;
    height: 30px;
    border-radius: 50%;
    position: relative;
}
.curryPanMan_mouceItem:before {
    content: "";
    display: block;
    width: 130px;
    height: 28px;
    background: #E06B31;
    border-radius: 30%;
    position: absolute;
    transform: scale(0.9);
}
2. 融合

最後に、beforeの位置を調整しましょう。
重ねます。

.curryPanMan_mouceItem:before {
    content: "";
    display: block;
    width: 130px;
    height: 28px;
    background: #E06B31;
    border-radius: 30%;
    position: absolute;
    transform: scale(0.9);
    top: -10px; //追加
    left: -16px; //追加
}

スクリーンショット 2019-12-05 22.43.10.png

口って難しい!!!!!!!!

まとめ

どっちも結局口が微妙

今回はカレーパンマンを表現波線を書くということで2種類の実装方法の可能性を探ってみました。
こういうときはSVGでやった方が確実かつ楽なんだろうなと思いつつ、やってみたわけです。

「波線を書く」というだけでも、いろんな作り方があるしいろんな実装方法がありました。
今回は2種類だけ紹介しましたが、きっと、絶対にもっと楽かつ、確実な実装方法はあります!!!

実際に作る時は以下を頭の片隅にとどめとくと良いかもです。

  • 実装方法は1つじゃない、いくつもある
  • いくつかの実装方法のパターンを出して、それぞれのメリット・デメリットを考える
  • メリット・デメリットを踏まえてどの実装方法が一番最適化を自分の中で理由を持っておこう

以上です!今日のカレーごちそうさまでした!!!!

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

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

100日チャレンジの177日目

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

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

177日目は

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

アクセシビリティのためによく書く CSS

アクセシビリティを意識した CSS に関するいくつかの tips です。

スクリーンリーダー用のテキスト

テキストを視覚的には隠したいけどスクリーンリーダーには伝えたい、デザイン上にタイトルはないけどマークアップで見出しを入れて構造化したい要件などを実現するために、要素を隠すような CSS を書きます。

たとえば、Apple の ホーム にアクセスしてみると、次のような CSS で隠された h1 を見つけることができます。

.visuallyhidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  -webkit-clip-path: inset(0px 0px 99.9% 99.9%);
  clip-path: inset(0px 0px 99.9% 99.9%);
  border: 0;
}

要素にはいろいろな隠し方がありますが、display: nonevisibility: hidden だと支援技術は認識しません。この辺りはいろいろな hack が入り組んだスタイリングになっていますが、次のスニペットや Bootstrap のヘルパーが参考になります。

ぼくは Bootstrap の mixin を参考にしています。

@mixin sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

要素の順序が乖離する

Flex や Grid などで要素の順序を変更した場合、DOM の順序と実際に表示される順序が違ってしまう現象がおきます。キーボード操作やスクリーンリーダーに大きな影響を与えるので、フォーカスされる要素の積極的な順序変更には注意が必要です。

分割したテキストのフォロー

CSS でアクセシブルにするのではなく、ちょっと分脈がそれますが、テキストを分割して 1 文字ずつ CSS アニメーションするときなどに HTML で対応しておきたい tips です。

スクリーンリーダーによっては <span> などでスプライトしたテキストたちをひとつの単語として読み上げてくれない場合があります。テキスト集合を aria-label でラベリングして aria-hidden で元の文字列を無視するよう、スクリーンリーダーに伝えることで解決します。

<div aria-label="accesible text">
  <span aria-hidden="true">
    <span>a</span>
    <span>c</span>
    <span>c</span>
    <span>e</span>
    <span>s</span>
    <span>i</span>
    <span>b</span>
    <span>l</span>
    <span>e</span>
    <span> </span>
    <span>t</span>
    <span>e</span>
    <span>x</span>
    <span>t</span>
  </span>
</div>

印刷用のスタイルシート

印刷用のスタイルシートを用意することもアクセシビリティ対応のひとつだと考えています。印刷用のルールはメディアクエリで分岐して簡単に記述できます。

@media screen {
  .print-only {
    ...
  }
}

調整する内容としては、文章中のリンク先 URL を明示したりするなど印刷時に不足する情報を補ったり、改ページの指定などレイアウトを整えたりするといいと思います。

次のガイドに基本的な tips が集まっています。

また関連として、未来の CSS で page floats という仕様があります。 区切られるページの一番上部にコンテンツを持ってくることなどを可能にしてくれます。float のプロパティとして機能することもあり、おもしろいので注目しています。

デザイナーへアラートするための簡単なチェック

CSS を書いているときによく気付く(フォントサイズやコントラストとか)、デザインレイヤーで検討するべきアクセシビリティ項目もいろいろありますよね。もちろん、デザイナーがアクセシブルなデザインを作ってくれるような文化や理解やガイドラインが整っているのが理想ですが、なかなかそうでない場合や見落としもよくあると思います。このあたりをうまくエンジニアがデザイナーに相談しつつ連携できると、優しいサイトが実現できるなーという意識を持って作業したいです。

こちら CSS Advent Calendar 2019 でした。
よいお年をお迎えください?

おわります。

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

自作したWebページをCSSでダークモードにする

序文

最近のiosアップデートでiphoneをダークモードに設定できるようになりました。私個人的にはダークモードの方が好みであり、自分自身のiphone,iPad,MacBookも全てダークモードに設定しております。
そこでふと自身で作成したWebページやポートフォリオをダークモードにできないかと思い、調べて見たところ簡単に設定する事ができましたので、下記に共有いたします。

コード

閑話休題、styleの中に下記を追加するだけです。
現在主要なブラウザ、crome,firefox,safariでは対応している模様です。

<style>
    @media (prefers-color-scheme: dark) {
    body{
      background-color: #000;
      color: #aaa;
    }
    }
 </style>

使用例

実際に私の簡単なサイト内で試して見ましたので画像を共有いたします。
*MacBookAir(2018)をダークモードの設定状態で、ブラウザはcromeを使用しております。
*サイトはちなみに自身の本管理用途をして,laravel(+vue,jquery)で作成したものです。

1.ダークモード実装前
スクリーンショット 2019-12-05 20.13.06.png

image.png

2.ダークモード実装後
image.png

image.png

最後に

以上WebページをCSSでダークモードにする方法でした。
なんとなくダークモードの方がテンション上がる気がする笑

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

Web入門(2)

はじめに

CSSは一言でいうと、Webサイト上の文字・枠・背景などの見た目やそれらの配置を指定するための言語です。最初は「CSS は見栄えを変えることができるんだ」くらいの認識で構いません。CSS は HTML と合わせて用います。ちなみに CSS はCascading Style Sheetsの略です。

書き方

CSS を用いてスタイルを指定する際には、まずどこをどのような見た目に変更するか決めます。

sample.css
p { font-size : 40px; }

CSS の基本的な書き方は セレクタ {プロパティ名:値;} という構造になっています。セレクタには変更したい要素の名前を指定します。上の例ではp要素となっています。プロパティ名にはスタイルの種類を指定します。プロパティとは変更するスタイルの種類みたいなものです。例では文字の大きさとなっています。値にはプロパティをどのように変更するかを指定します。上の例では40pxとなっています。

一度に複数のプロパティを指定することもできます。その際、改行をしてもスタイルには影響がでません。コードが見やすくなるので、個人的には改行して書くことをおススメします。

sample.css
/* 改行しない*/
p { font-size : 30px; color: red; height : 80px; }

/*改行した*/
p {
   font-size: 30px;
   color: red;
   height: 80px;
}

基本的なプロパティとその使用例

基本的なプロパティ一覧

プロパティ 説明
width 横幅の指定
height 高さの指定
color 文字の色の指定
background 背景関係をまとめて指定
background-color 背景の色を指定
margin 要素外の間隔の指定(余白のようなもの)
padding 要素内の間隔の指定(余白のようなもの)
font フォント関係をまとめて指定
font-size フォントの大きさ(文字の大きさ)を指定
font-family フォントの種類の指定
float 要素を左右に寄せる

使用例

以下の sample.html を用意しました。(比較し易くなるように予めbackground-colorに黄色を指定しています。)

sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Sample</title>
    <link rel="stylesheet" href="sample.css">
</head>
<body>
    <p>こんにちは!</p>
</body>
</html>

tempsnip1.png

このWebページに以下のCSSを適用させてみます。

sample.css
/*背景を黄色、横幅を100px、高さを30pxにして、padding,marginを100px加える*/
p {
   width: 100px;
   height: 30px;
   padding: 100px;
   margin: 100px;
   background-color: yellow;
} 

tem2.png
Webページが変化しました!
ここで、「margin」と「padding」の違いについて軽く触れておきます。
上のプロパティ一覧表にも書いてありますが、「margin」は要素外、「padding」は要素内に余白を追加します。下図のようなイメージです。
tem.png

次にfloatを適用させてみます。

sample.css
/*p要素を右に寄せ、さらに背景を青色に変更*/
p {
   width: 100px;
   height: 30px;
   padding: 100px;
   margin: 100px;
   background-color: yellow;
/*要素を右に配置*/
   float: right;
}

tem3.png
要素が右に移動しました!

まとめ

  • CSS は HTMLで記述した要素のスタイルを指定するための言語である。
  • 「margin」は要素外、「padding」は要素内に余白を加える。
  • floatプロパティを用いると要素を左右に移動させることができる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CSSアニメーションで雪だるまとツリーを作ろう⛄?

はじめに

この記事は、 CAMエンジニア Advent Calendar 2019 6日目の記事です。

記事一覧はこちらから↓
https://qiita.com/advent-calendar/2019/cam-inc

昨日はid:youkouJB さんの 「入社してCSS記述で指摘されたこと」 でした。
CSSの記述方法について気になる方は是非読んでみてください!とてもためになりました!!

ここからはid:tomomi_hがCSSアニメーションについて書いていきたいと思います。

アニメーションてなに?

そもそもcssアニメーションにはCSS TransitionとCSS Animationの2つの機能がある。

CSS Transition

アニメーションが始まって終わるまでの時間を設定するプロパティ。

CSS Animation

キーフレームアニメーションのプロパティとその変化を指定して、アニメーションの名前を設定します。
0〜100%までの値で、時間経過を元に変化する。
@Keyframeとanimationはセットで使うプロパティ。

今回は、CSS Animationを使って簡単なアニメーションを試してみます〜。

作るもの

12月といえばクリスマス:santa_tone1:
今回はクリスマスにちなんで「雪だるま」と「ツリー」を作ってCSS Animationを学びます。

keyframesとanimationのプロパティについて

keyframesの使い方

@keyframes の後の名前は任意で決める。
アニメーションの開始と終了を0%(/from) から100%(/to)で指定する。

@keyframes 自分で決めた名前 {
   0% {
     CSSプロパティ:値;
   }
   50% {
     CSSプロパティ:値;
   }
   100% {
     CSSプロパティ:値;
   }
}

たとえば、回転させたかったら

@keyframes rotation {
  0% {
    background: red;
  }
  100% {
    transform: rotate(90deg);
    background: blue;
  }
}

これに、例えば

animation: rotation 1s ease-out infinite;

を加えると、
09c16c5fdf29c1be1ab6ab94fb0f461d.gif
このように、0%の時は色がredのまま、100%のときに90°回転して色が青になる。

animationプロパティについて

animationプロパティには以下の9つがある。

①animation-name アニメーションを適用する要素を指定する
②animation-duration アニメーションが完了するまでの時間を指定する
③animation-timing-function アニメーションの進行度を指定する
④animation-delay アニメーションが開始するまでの時間を指定する
⑤animation-iteration-count アニメーションの実行回数を指定する
⑥animation-direction アニメーションの再生方向を指定する
⑦animation-fill-mode アニメーションの再生中・再生後のスタイルを指定する
⑧animation-play-state アニメーションの再生、または一時停止を指定する
⑨animation 上記8つのプロパティを1つでかけるショートハンドプロパティ

animation-name

animation-nameには@keyframesの名前を書く。

@keyframes rotation {
  0% {
    background: red;
  }
  100% {
    transform: rotate(90deg);
    background: blue;
  }
}

.クラス名 {
 animation-name: rotation;
}

animation-duration

animation-durationは、アニメーションの開始から終了までの時間を指定できる。

@keyframes rotation {
  0% {
    background: red;
  }
  100% {
    transform: rotate(90deg);
    background: blue;
  }
}

.クラス名 {
 animation-name: rotation;
 animation-duration: 5s;
}

これなら90度回転するのに5秒かかる。
b675ea27e199b56fd88c428f48d47aa0.gif

animation-timing-function

アニメーションが変化する速度を指定できる。

① ease 初期値。開始時と終了時は緩やかに変化する。
② ease-in 開始時は緩やかに変化、終了に近づくと早く変化する。
③ ease-out 開始時は早く変化し、終了時は緩やかに変化する。
④ ease-in-out 開始時と終了時は、かなり緩やかに変化する。
⑤ linear 開始から終了まで一定に変化する。
⑥ step-start 開始時に最終の状態になる。
⑦ step-end  終了時に最終の状態になる。
⑧ steps(正数, start または end)
  指定した正数の段階で変化する。第2引数には start または end を指定。
  startを指定すると、アニメーション開始時から変化。endを指定すると、アニメーション終了時に変化。

違いがよくわからないから、サンタさんとトナカイを走らせて比べてみた。
e9cdd679488e495b36634cd7ae0b7444.gif

なるほど〜〜!

animation-delay

アニメーションが始まるまでの時間を指定できる。

@keyframes rotation {
  0% {
    background: red;
  }
  100% {
    transform: rotate(90deg);
    background: blue;
  }
}

.クラス名 {
 animation-name: rotation;
 animation-delay: 3s;
}

3秒経ってから始まる。
2194f59a1c4047829c9d20ce2252b14b (1).gif

animation-iteration-count

アニメーションの繰り返しの回数を指定できる。

@keyframes rotation {
  0% {
    background: red;
  }
  100% {
    transform: rotate(90deg);
    background: blue;
  }
}

.クラス名 {
 animation-name: rotation;
 animation-delay: 2s;
 animation-iteration-count: 2;
}

2秒経ってから始まって、2回で終わる。
cb92faf664f339fcec283ce4b3afe593.gif

animation-direction

アニメーションの方向を指定できる。
①nomal アニメーションを毎回順方向に再生。
②reverse アニメーションを毎回逆方向に再生。
③alternate アニメーションを毎回反転させる。初回が順方向。
④alternate-reverse アニメーションを毎回反転させる。初回が逆方向。

またまた、サンタさんとトナカイを走らせて比べてみた。

.santa {
  animation-name: santa;
  animation-duration: 3s;
  animation-timing-function: ease;
  animation-direction: ここにanimation-direction;
}

@keyframes santa {
  0% { left: 500px; }

  100% { left: 0; }
}

a750ef5fd0839d1ffa21dbe04667ee46.gif

animation-fill-mode

アニメーション再生中、再生後のstyleを指定できる。
①none
スタイルを指定しない。アニメーション終了後はもとのスタイルが適用される。
animation-delayを指定している場合は、アニメーションが開始するまでは、もとのスタイルが適用される。
②backwards
アニメーション終了後は0%のスタイルが適用される。
animation-delayを指定している場合は、アニメーションが開始するまでは、0%のスタイルが適用される。
③forwards
アニメーション終了後は100%のスタイルが適用される。
animation-delayを指定している場合は、アニメーションが開始するまでは、もとののスタイルが適用される。
④both
アニメーション終了後は100%のスタイルが適用される。
animation-delayを指定している場合は、アニメーションが開始するまでは、0%のスタイルが適用される。

.squear {
  background-color: red;
  animation-name: rotation;
  animation-duration: 5s;
  animation-timing-function: ease-out;
  animation-fill-mode:   ;
}

@keyframes rotation {
  0% {
    background: blue;
  }
  50% {
    transform: rotate(90deg);
    background: yellow;
  }

  100% {
    transform: rotate(90deg);
    background: green;
  }
}

5b7db6e943b906135929aee66c3a2f35.gif

animation-play-state

アニメーションが実行中か停止中かを指定できる。
①running アニメーションを再生させる。
②paused アニメーションを停止させる。

.text {
  animation-name: color;
  animation-duration: 1s;
  animation-timing-function: ease;
  animation-play-state: running;
}

@keyframes color {
  0% {
    color: red;
  }
  100% {
    color: green;
  }
}

ed00a73a7d0e30431beea5a652114129 (1).gif
初期値runningで、ボタンを押したら止まる→動く→止まる

animation

1行にまとめられる。
例)

transition :  3s linear 0 infinite alternate;

この機能を使って、雪だるまとツリーを動かしてみる⛄?

雪だるまをゆらゆらさせる⛄

.snowman {
  animation: swing 1s 1s ease-in-out infinite alternate;
}
@keyframes swing {
  0%,100% { 
    transform-origin: bottom center; 
  }
  50% {
    transform: rotate(-2deg);
  }
}

原点をbottom centerにして,1秒かけてswingさせる。

7cbd22a269c4f27cb265a03e300aaf66.gif

クリスマスツリーをキラキラさせる?✨

.reflect {
  animation: reflect 2s linear infinite;
}

@keyframes reflect {
  0% { opacity: 0.2; }
  50% { opacity: 0.8; }
  80% { opacity: 0.2; }
}

ひとつひとつに色を付けて、2秒間のopacityを指定する。
20c41cab06f3928ab49ce67306e10fb6.gif

雪だるま⛄とクリスマスツリー?を使って、冬景色ぽくしてみた:snowflake:

? Merry Christmas ?

See the Pen ExaYbQE by ともみ (@tomomi0425) on CodePen.

さて、明日はid:rumanさんの「JSのつまづいたところ」です。
お楽しみに!

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

コーディングのTIPS

コーディングのTIPSを随時更新していきます。

・ホバー時の色は、カラーコードではなくopacity(透明度)をいじると良い

・基本的には要素同士の関係よりクラスで指定した方が良いが、
liとか、絶対にタグが変わらないものとかは関係でもOK

・タブレットで表示した時の見え方は、meta viewportでPC版に合わせる。そうするとタブレットの微妙な画面幅のことを考えなくて良くなる

・コーディングに入る前に、繰り返し使えそうなパーツは何かを考える

・余白はパーツのスタイルに入れず、利用箇所ごとで設定するとパーツの再利用性が上がる

・BEMの命名は、セクションごとではなくパーツごと
(ヘッダーにBlockが4個くらいあったりする)

・Block名はキャメルケースで少し長めにするとかぶる心配が減ってやりやすい

・flexboxで、カラム数を「2or4」みたいにしたい時は、要素を2つずつdivで囲む

・色は最初に定義しておくとやりやすい

・SMACSSの各セクションの開始位置に、エディターでしおりをつけておくと捗る

li:not(:last-child):not(:first-child)first-childlast-child以外という指定ができる

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

コーディングでハマったポイント

コーディングでハマったポイントを、随時更新していきます。

display: tableを持つ要素には、overflow: scrollが効かない
tabledisplay: blockを指定すると、widthが効かなくなる
→tableはdivで囲っておくのが無難

・classに対して:first-childnth-of-type()などを指定すると、特殊な動きをする

display:inline-blockを使うと、謎の余白が生まれることがある。
→親要素にfont-size: 0を指定すると解消。
(参考:inline-blockの隙間をなくす方法

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

よくある動き、お気に入りの実装方法

コーディングをする上でよく遭遇する動きの実装方法を、随時更新していこうと思います。

ハンバーガーメニュー

CSSで実装。表示の動きとか場所は、以下の記事よりもう少し工夫した方が良いかも。
CSSだけで簡単!ハンバーガーメニューの作り方(スマホ対応)

タブ切り替え

CSSで実装。
CSSだけでタブ切り替えを作る方法

画像スライダー

Swiperを使って実装。
【実例12パターン】画像スライダーはSwiper使っておけば間違いない!実用的な使い方を紹介

画像ポップアップ

これって方法が見つかってません。lightboxが有名だけど、何となくもっさりしていた印象があります。

グラフ

Chart.jsを使って実装。
Chart.jsでグラフを描画してみた

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

年末まで毎日webサイトを作り続ける大学生 〜48日目 マウスの軌跡を描く & マウスの動きに画像が付いてくる〜

はじめに

こんにちは!@70days_jsです。

14日目に、マウスの動きに合わせて黒い丸を表示したかったけどできませんでした。
今日はそのリベンジです。

48日目。(2019/12/5)
よろしくお願いします。

サイトURL

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

やったこと

test3.gif

主に2つのことをやりました。

  1. マウスに合わせて画像が付いてくる
  2. マウスの軌跡を描く

では1から説明していきます。

1. マウスに合わせて画像が付いてくる

html全体↓

  <body>
    <div id="mouseMove">
      <div id="positionDisplay"></div>
      <img src="day48men.png" id="men" class="position" />
      <img src="day48doctor.png" id="doctor" class="position" />
    </div>
  </body>

css全体↓ 

body {
  margin: 0;
  overflow: hidden;
}

#mouseMove {
  height: 100vh;
  width: 100vw;
}

.position {
  position: absolute;
  height: 50px;
  width: 50px;
  transform: translateY(-50%) translateX(-50%);
}

.dot {
  position: absolute;
  background-color: black;
  width: 3px;
  height: 3px;
}

#men {
  top: -100%;
  left: -100%;
}

#doctor {
  top: -100%;
  left: -100%;
}

JavaScript 全体↓

let mouseX = 0;
let mouseY = 0;
let mouseMove = document.getElementById("mouseMove");
let positionDisplay = document.getElementById("positionDisplay");
let men = document.getElementById("men");
let doctor = document.getElementById("doctor");
let x;
let y;

mouseMove.addEventListener("mousemove", function(e) {
  x = e.pageX;
  y = e.pageY;
  let coordinate = " (X座標:" + x + " Y座標:" + y + ")";
  positionDisplay.innerHTML = coordinate;
  doctor.style.top = y + "px";
  doctor.style.left = x + "px";
  men.style.top = y + 25 + "px";
  men.style.left = x + 30 + "px";
  let div = document.createElement("div");
  div.setAttribute("class", "dot");
  div.style.top = y + "px";
  div.style.left = x + "px";
  mouseMove.appendChild(div);
});

#mouseMove {
height: 100vh;
width: 100vw;
}

id="mouseMove"のdivを画面いっぱいに広げて、その中で検知するようにしています。
bodyではなく、divを作って設定しておくことで、mouseMoveの大きさを変えるだけで、いつでも表示したい範囲を調整できるようになります。

.position {
position: absolute;
height: 50px;
width: 50px;
transform: translateY(-50%) translateX(-50%);
}

.positionクラスで画像の位置をabsoluteにしています。
transformは画像の表示場所をマウスの中心に置くために付けています。

位置の検知はJavaScriptで、mousemoveイベントを使い、pageXとpageYのプロパティから取得しています。

mouseMove.addEventListener("mousemove", function(e) {
x = e.pageX;
y = e.pageY;

マウスに画像が付いてくるのは、スタイルのtopとleftをpageXとpageYの値に変えてやるだけです。

doctor.style.top = y + "px";
doctor.style.left = x + "px";

2. マウスの軌跡を描く

これもmousemoveイベントをトリガーにして行っています。

mouseMove.addEventListener("mousemove", function(e) {
//処理
}

イベントが起こるごとに、divを作っています。

let div = document.createElement("div");

作ったdivに用意してあるクラスをつけます。

div.setAttribute("class", "dot");

.dotクラス↓

.dot {
position: absolute;
background-color: black;
width: 3px;
height: 3px;
}

positionがabsoluteなので、あとはtopとleftの値をpageXとpageXの値に設定して、appendchildを使い子要素に加えたら完成です。

div.style.top = y + "px";
div.style.left = x + "px";
mouseMove.appendChild(div);

感想

14日目には分からなかったことができて嬉しいです。
いまいち成長しているかどうか分からなかったんですが、過去にできなかったことができるようになっていたので少し自信がつきました。
とりあえずこの調子で年末まで頑張ります。

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

参考

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

アイコンをお借りしました。ありがとうございます!

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

年末まで毎日webサイトを作り続ける大学生 〜48日目 マウスの軌跡を描く & マウスの動きに画像が付いてくる〜

はじめに

こんにちは!@70days_jsです。

14日目に、マウスの動きに合わせて黒い丸を表示したかったけどできませんでした。
今日はそのリベンジです。

48日目。(2019/12/5)
よろしくお願いします。

サイトURL

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

やったこと

test3.gif

主に2つのことをやりました。

  1. マウスに合わせて画像が付いてくる
  2. マウスの軌跡を描く

では1から説明していきます。

1. マウスに合わせて画像が付いてくる

html全体↓

  <body>
    <div id="mouseMove">
      <div id="positionDisplay"></div>
      <img src="day48men.png" id="men" class="position" />
      <img src="day48doctor.png" id="doctor" class="position" />
    </div>
  </body>

css全体↓ 

body {
  margin: 0;
  overflow: hidden;
}

#mouseMove {
  height: 100vh;
  width: 100vw;
}

.position {
  position: absolute;
  height: 50px;
  width: 50px;
  transform: translateY(-50%) translateX(-50%);
}

.dot {
  position: absolute;
  background-color: black;
  width: 3px;
  height: 3px;
}

#men {
  top: -100%;
  left: -100%;
}

#doctor {
  top: -100%;
  left: -100%;
}

JavaScript 全体↓

let mouseX = 0;
let mouseY = 0;
let mouseMove = document.getElementById("mouseMove");
let positionDisplay = document.getElementById("positionDisplay");
let men = document.getElementById("men");
let doctor = document.getElementById("doctor");
let x;
let y;

mouseMove.addEventListener("mousemove", function(e) {
  x = e.pageX;
  y = e.pageY;
  let coordinate = " (X座標:" + x + " Y座標:" + y + ")";
  positionDisplay.innerHTML = coordinate;
  doctor.style.top = y + "px";
  doctor.style.left = x + "px";
  men.style.top = y + 25 + "px";
  men.style.left = x + 30 + "px";
  let div = document.createElement("div");
  div.setAttribute("class", "dot");
  div.style.top = y + "px";
  div.style.left = x + "px";
  mouseMove.appendChild(div);
});

#mouseMove {
height: 100vh;
width: 100vw;
}

id="mouseMove"のdivを画面いっぱいに広げて、その中で検知するようにしています。
bodyではなく、divを作って設定しておくことで、mouseMoveの大きさを変えるだけで、いつでも表示したい範囲を調整できるようになります。

.position {
position: absolute;
height: 50px;
width: 50px;
transform: translateY(-50%) translateX(-50%);
}

.positionクラスで画像の位置をabsoluteにしています。
transformは画像の表示場所をマウスの中心に置くために付けています。

位置の検知はJavaScriptで、mousemoveイベントを使い、pageXとpageYのプロパティから取得しています。

mouseMove.addEventListener("mousemove", function(e) {
x = e.pageX;
y = e.pageY;

マウスに画像が付いてくるのは、スタイルのtopとleftをpageXとpageYの値に変えてやるだけです。

doctor.style.top = y + "px";
doctor.style.left = x + "px";

2. マウスの軌跡を描く

これもmousemoveイベントをトリガーにして行っています。

mouseMove.addEventListener("mousemove", function(e) {
//処理
}

イベントが起こるごとに、divを作っています。

let div = document.createElement("div");

作ったdivに用意してあるクラスをつけます。

div.setAttribute("class", "dot");

.dotクラス↓

.dot {
position: absolute;
background-color: black;
width: 3px;
height: 3px;
}

positionがabsoluteなので、あとはtopとleftの値をpageXとpageXの値に設定して、appendchildを使い子要素に加えたら完成です。

div.style.top = y + "px";
div.style.left = x + "px";
mouseMove.appendChild(div);

感想

14日目には分からなかったことができて嬉しいです。
いまいち成長しているかどうか分からなかったんですが、過去にできなかったことができるようになっていたので少し自信がつきました。
とりあえずこの調子で年末まで頑張ります。

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

参考

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

アイコンをお借りしました。ありがとうございます!

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

CSSは神なのでゲームも作れる

はじめに

この記事はN高等学校 Advent Calendar 2019の12日目の記事です。
昨日の記事は同じキャンパスの先輩であるGenbu氏の静的な Web サイトをどうやって速くするかです。合わせて是非。
因みに明日の記事も同じキャンパスの狂人Nemesis氏のFlutterと云ふものを触った話を語りんすです。こちらも合わせてどうぞ。

こんにちは。N高等学校1年生のはとと申します。プログラミング歴は一年にも満たない若輩者ではありますが、ここまでの学習の成果としてアドベントカレンダーを書かせていただきます。よろしくお願いいたします。

作ったもの

See the Pen GRgJjZL by HATO (@hatopoppo) on CodePen.

タイピングゲームです。HTMLとCSSだけで実装しました。JavaScriptは使ってません。
inputの自動選択は、私が知る限りHTMLとCSSではどうにもならないので一々クリックしないといけない仕様となっております。
本来こんな事CSSでやるべきじゃないので当然の如く脳筋クソコードです。それにあいまって元々のクソコード力も重なりクソの二段構えコードとなっております。

若干ゃ解説

このコードの鍵や、苦労した点等の解説を少しだけします。

仕組み

まずこのタイピングゲームで鍵になるのはここ

CSSisGOD.html
<input type="text" class="A1" pattern="java" required>

inputタグの中の

CSSisGOD.html
pattern="java"

ここ。

このpatternという所でinputに入れられたテキストの正誤判定をしています。
本来の用途としては、

sample.html
pattern="^[0-9A-Za-z]+$"

等で受け付ける文字の種類を限定するのですが1、今回はここに文字列javaを入れることにより、この文字列以外は受け付けないという形に出来ました。

そして、文字列が正しいと判断されると擬似要素 :valid が、
正しくないと判断されると擬似要素 :invalid が与えられる為、CSSで

CSSisGOD.css
.A1:valid ~
.A2:invalid ~
.A3:invalid ~
.A4:invalid ~
.A5:invalid ~
.A6:invalid ~ .Q2 {
  opacity: 1;
}

のように書いてやって、A1(最初の問題のinput)が正しければ次の問題を表示という形に出来ました。
因みに得点の部分もこういう感じで切り替えています。本来は別の方法を使いたかったのですが後述の理由により断念しました。

苦労した点

今回苦労したのは、inputの切り替えと得点の兼ね合いです。
現在正解時のinputの交代は、

CSSisGOD.css
input[pattern]:valid{
  display: none;
}

このように、validの時に要素を消すという処理で行なっているのですが、このような形にすると、元々得点の部分で行なっていた、要素のカウントを出来るコード

sample.css
input[pattern]:valid{
counter-increment: count; 

が動かなくなり、原因と改善案の模索で半日ほど潰していました。
理由は恐らく、要素そのものを消している為、カウント対象の要素がなかった事だと思います。
実際、opacityを0にする方式にしてみるとしっかりと得点のカウントがされました。
しかし、opacityを切り替える場合では、inputが常に存在している状態になります。
その状態だと問題を解いた後も、見えないinputがまだ選択状態、即ち入力待ちの状態になってしまう為、そこから次のinputの選択をせずに入力を行うと

一問前のinputに入力
    ↓
patternの正誤判定が働き一問前の問題とinputがまた表示

というストレスフルの状態になった為、やむなくinputは消滅させ得点は正誤判定で切り替えるシステムとしました

終わりに

脳筋実装ではありますが、CSSでもゲームを作る事ができました。
CSSの限界はもっと上にあると思うので、今後もCSSの限界に挑み続けようと思います。
最後に、このゲームを作っている途中にクラスメートに言われた言葉を金言として書き、終わろうと思います。
「CSSはゲームを作るものじゃない」
「時間の無駄」
「JavaScript使え」
「CSS中毒」

ご覧いただきありがとうございました。

追記

すでにCSSで僕なんかよりも完成度高くタイピングゲームを作り、分かりやすく解説もしていらっしゃる先駆者の方がおりましたので、畏敬の念を込めてリンクを貼らせていただきます。
codegrid


  1. この場合は、半角英数字のみという制限をかけている。詳しくは他記事参照。 

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

divの中央に画像を配置する

画像の要素をブロックにし、margin:auto;で配置する

img{
display:block;
margin:auto;}

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

Webを見ているときに起きていること

この記事はSmartHR Advent Calendar 2019 5日目の記事です。

はじめに

こんにちは、フロントエンドエンジニアの@cidermitainaです。

みなさん、Webを見ているときにブラウザで起きていることって考えたことありますか?
ちなみに私は考えたことがなかったです。。。

アドレスバーにURLを入力すると、すぐに見たいページが表示される、このことが当たり前だと思っていたのですが、実はブラウザの中では様々のことが起きているのです。

今回はそんなブラウザについての記事です。

アドレスバーにURLを入力してから起きていることについて追っていこうと思います。

アドレスバーにURLを指定されたWebブラウザの動作

1. http://www.example.comをアドレスバーに入力。

まずはブラウザのアドレスバーにURLを入力します。

68747470733a2f2f6573612d736d61727468722e73332d61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f75706c6f6164732f70726f64756374696f6e2f6174746163686d656e74732f31313434392f323031392f31312f33302f36333932342f66356636363631342d363337362d.png

2. www.example.comのIPアドレスを探す(DNS解決)

www.example.comサーバーにあるリソース(HTML)を取得したいというリクエストを送りたいのですが、www.example.comのままではブラウザはwww.example.comのサーバーの場所は分かりません。

www.example.comのサーバーの場所を探すためにルートサーバーにwww.example.comのIPアドレスを問い合わせます。

68747470733a2f2f6573612d736d61727468722e73332d61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f75706c6f6164732f70726f64756374696f6e2f6174746163686d656e74732f31313434392f323031392f31312f33302f36333932342f62646630653338342d386432612d.png

3. www.example.comのIPアドレスに対してTCPの80番ポートで接続する

www.example.comのIPアドレスが分かったので、さっそくサーバーにリクエストを送りたいのですが、Webを含む、インターネットにおける通信の大半がTCPを前提にしています。

TCPで通信を行うためにはまず接続するという作業が必要です。

  1. 通信を開始したい側が「このポート番号で接続させてください」という接続要求パケットを送信する
  2. その接続を受け入れるのであれば「いいですよ」という応答を返す
  3. 受け取った通信を開始したい側は「ありがとうございます。お願いします!」という内容を送信してTCP接続が確立。

(↑は3回メッセージがやり取りされるので、3 way handshake と呼ばれています。)

68747470733a2f2f6573612d736d61727468722e73332d61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f75706c6f6164732f70726f64756374696f6e2f6174746163686d656e74732f31313434392f323031392f31312f33302f36333932342f31373434303332632d316630372d.png

4. リクエストメッセージを送信する

TCP接続が成功したので、やっとwww.example.comにリクエストを送れます。

WebブラウザとWebサーバーの間ではHTTPでやり取りをしているので、HTTPリクエストメッセージを送信します。

image (5).png

(HTTPリクエストメッセージはChrome DevToolsのNetworkパネルから確認することができます。)
image (6).png

5. サーバーがメッセージを受け取り、レスポンスメッセージを返信する。

WebブラウザからのHTTPリクエストを受け取ったWebサーバーは、要求されたリソースをWebブラウザに返します。

image.png

6. リソースの読み込み(loading)

リソースを受け取ったWebブラウザですが、受けとったリソースのHTMLをそのまま表示させる訳にはいきません。

解釈した上で画面に表示しなければなりません。

リソースのDownload

HTMLをサーバーから受け取りましたが、どうやらHTMLには画像やCSS参照されている記述があります。

ブラウザは受け取ったHTMLにCSS,JavaScriptや画像といったリソースの参照があれば、さらにそのリソースを読み込みます。

リソースの解釈 (Parse)

index.html
<html>
<head></head>
<body>
  <h1>My Header</h1>
  <a href="www.example.com">My link</a>
</body>
</html>

この状態ブラウザに表示させても全く分からないので、ブラウザがRenderingしやすいように読み込んだHTMLを解釈してドキュメントのDOMツリーを構築していきます。

image.png

同じようにCSSも解釈され、CSSOMツリーを構築していきます。
image (7).png

8. JavaScriptの実行 (Scripting)

リソースを一式読み込んだ後はJavaScript実行(Scripting)します。

レンダリングエンジンは、JavaScriptのコードを実行することができないのでJavaScriptエンジンに引き渡して実行させます。

ですが、このままのコードでは、JavaScriptエンジンは、実行することができません。
実行可能な形式に変換(コンパイル)しないと処理を実行することができないのです。

コンパイルを行うために、JavaScriptのコードを抽象構文木(AST:abstract syntax tree)と呼ばれるコンパイル可能な形に変換します。

  1. 字句解析を行い、トークン列に。
    image (1).png

  2. トークン列をもとに構文解析を行い抽象構文木(AST)に。
    image.png

  3. 抽象構文木を実行可能な形式にコンパイル

  4. 実行

9. レイアウトツリー構築 (Rendering)

JavaScriptの実行が終わるといよいよ画面に表示する準備に取り掛かります。

DOM と CSSOM を組み合わせて、ページ上の表示可能なすべての DOM コンテンツと、各ノードのすべての CSSOM スタイル情報を取り込んだレイアウトツリーを作成していきます。

image (2).png
image (3).png

レイアウト

レンダリング ツリーが出来たので、いよいよ画面に表示したいところですが、端末のビューポート内での要素の正確な位置とサイズはまだ分かりません。

ページ上の各オブジェクトの正確なサイズと位置を算定するために、

  • 要素の大きさ
  • 要素のmargin
  • 要素のpadding
  • 要素の位置

等のレイアウト情報の計算を行います。

image (4).png

10. レンダリング結果の描画(Painting)

レイアウト情報の算出の算出が終わったので、いよいよ画面に描画です。

レイアウトツリーが画面上のピクセルに変換されます。

これでやっと画面上にページが表示されました!

まとめ

アドレスバーにURLを入力してから、表示されるまでたくさんの処理があります。

こんなにたくさんの処理があるのに一瞬でページを表示してくれるブラウザって素敵だと思いませんか?

Webを見ているときに起きていることを理解してみると、普段何気なく書いてるJavaScriptのコードだったり、HTMLやcssの理解が深まる気がしています。

ブラウザの仕組みについて考えてみることで、フロントエンド開発で本当に大切なことが見えてくるような気がして、私はブラウザについて考えるのが好きです。


参考

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

CSSだってJavaScriptの値が欲しい!

インターン先でreact + typescript + scssのお仕事をしている @haduki1208 と申します。
最近reactよりscssを多く書いてる気がします。割と楽しいです。

TL;DR

  • CSS変数をインラインスタイルで書く
  • var()で読み込む

CSSでJavaScriptの値を取得する

趣味で「任意の大きさ・色・向きを指定できる矢印アイコン:arrow_up::arrow_right::arrow_down::arrow_left:」を作っていた時に

:thinking:「CSSでJavaScriptの値を取得できないのか?」

と思ったのでやってみました。

cssにattr()という関数がありますが、content属性でしか動作しないようです。
今回はheight, width, background-color, rotateに任意の値を使いたいのですがダメです。微妙な仕様ですね。

環境

  • typescript + react + scss および typescript + react + styled-components
  • chromeで動作確認
  • 動いたコードをcodepenに移植(codepenを使ってみたかった :heart: )

ソースコード

See the Pen Arrow01 react + ts + scss by haduki1208 (@haduki1208) on CodePen.

最初に作った矢印アイコンのソースコードです。

このコードの弱点は以下になります。

  1. size, color, rotateの1つでも違う値を使いたい場合、新たにclassnameを作成しなければならない
  2. tsxとscssの両ファイルに変更を加える必要がある
  3. mixinを使っているため、トランスパイル後のcssの容量が大きくなる

1番、2番は面倒くさいです。
これらを全て解消してみます。

変更後のソースコード

See the Pen Arrow02 react + ts + scss by haduki1208 (@haduki1208) on CodePen.

CSS カスタムプロパティ (変数)を使いました。

ポイントは以下になります。

  1. style属性に指定したオブジェクトは、インラインスタイルに変換される
  2. インラインスタイルで記述されているため、CSS変数が他の要素に影響しない
  3. typescript環境の場合、React.CSSPropertie型以外のオブジェクトを代入するため「as any」する必要がある

これでscssを編集せず色々なアイコンを作ることができます!

おまけ styled-componentsに置き換えたソースコード

こんなことするなら、最初からstyled-componentsにすれば良いじゃないと思った人もいらっしゃるでしょう。
僕は今までstyled-componentsを使ったことがなかったので、勉強のため置き換えをしてみました。

See the Pen Arrow03 react + ts + styled by haduki1208 (@haduki1208) on CodePen.

なんて素晴らしいライブラリなのでしょう。
scss、インラインスタイル、as any 全て消え去りました。
(ついでにwebpack.config.jsからstyle-loader, css-loader, sass-loader, postcss-loaderも消え去りました)

styled-componentsに惚れてしまいそうです。

感想

react + scssで開発をしているプロジェクトでJavaScripの変数を取得したくなった時はこの方法で解決できそうです。

既にscssで開発しているプロジェクトでは、styled-componentsに移行するにも時間がかかってしまうので、もしcssからjavascriptの値を使いたくなったら、ご検討ください。

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

リーダーブルコードを未経験が読んで理解したこと

触ってない言語、機能について書かれている今必要なさそうなところは飛ばして、自分(初心者)がすぐに実践できそうな知識についてまとめてみました。

優れたコードとは??

他者が読んで理解できるコード。
コードは短い方がいいが、『理解するまでの時間』を短くする方がよい。
そのため短くすることで逆にわかりにくくなるようであれば短くする必要はない。

名前に情報を詰め込む

変数や関数、クラス名でも名前に情報を詰め込むのが大事。名前は短いコメントのようなもの。
  • 明確な単語を選ぶ
    getPageだと何のページをgetしているかわからない。インターネットから取ってきたページなら、downLoadPage等の方がわかりやすい。

  • tmpやretvalなどの汎用的な名前は避ける。
    明確な理由があれば使用してもいい。

  • 抽象的な名前より具体的な名前を使う

  • 変数名に大切な情報を追加する
    ミリ秒を表す変数なら、変数名の後ろに_msとつけると何の変数かわかりやすい。

  • 名前の長さを決める

  • スコープが小さければ短い名前でも良い。

  • 頭文字と略語
    string⇨strなど他人にも通じる略語を使うのがいい。BackEndManager⇨BEM等、他の人がわからない略語はNG

  • 不要な単語は捨てる
    DoServeLoop()だったら、ServeLoop()でも必要な情報は損なわれてないのでOK。なくても通じる単語は捨てる。

  • 名前のフォーマットで情報を伝える
    エンティティごとに異なるフォーマットを使う。
    C++言語であれば、クラス名はキャメルケース、変数名は小文字にしてスネークケースで定義する、など。
    ローカル変数とクラス変数も、異なるフォーマットで書くと一目見て何かわかるので良い。

  • その他フォーマット規約
    プロジェクトや言語によってもフォーマット規約は変わってくる。
    JavaScriptでは、jQueryのライブラリ関数を呼び出したときは、変数名の頭に$をつけるというものがある。⇨iQueryのオブジェクトだと明確にわかるため。
    HTMLだと、タグのid名の区切り文字にはアンダースコアを、class名の区切り文字にはハイフンを使う規約が有力。

誤解されない名前をつける

自分のコードを読んでいる人が、自分の意図を正しく理解できることが大事。
  • 限界値を含め場合はminとmaxを使う。
    CART_TOO_BIG_LIMITという名前だと意味があいまい。(未満なのか以下なのかがわからない)⇨MAX_ITEM_IN_CARTのほうが意味が伝わりやすい。

  • 範囲を指定する場合はfirstとlastを使う
    startは適切な名前になるが、stopは複数の意味に解釈できるため、firstとlastを使用する方が適切。

  • 包含/排他的範囲にはbeginとendを使う

  • ブール値(真偽値)の名前
    read_passward = true
    パスワードをこれから読み取る?もう読み終わっている?適切な名前ではない。
    user_is_authenticated = true
    こっちのほうが適切。また、名前を否定形ではなく肯定系にしたほうがよい。

  • ユーザーの期待に合わせる
    getで始まるメソッドだとメンバの値を返すだけの軽量アクセであるという規約がある。
    この規約を守らないと、DBからすべてのレコードを取ってくるときの変数名にgetをつけたりすると、間違って使用したりしてコストが高くなってしまう。

  • 複数の名前を検討する

コードの美しさ

  • 一貫性のある簡潔な改行位置

  • メソッドを使った整列

  • 縦の線をまっすぐにする

$aaa     =  "test";
$b       =  "test";
$cccccc  =  "test";

イコールの位置を合わせると見やすい。

  • 一貫性と意味のある並び
    アルファベット順にしたり、「最重要」なものから重要度順に並べたり、対応する HTML フォームの フィールドと同じ並び順にするなど。

  • 宣言をブロックにまとめる

  • コードを段落に分割する
    文章と一緒。見やすくなる。

- 個人的な好みと一貫性
クラス定義のカギカッコの位置など、最終的には個人の好みによる部分が大きい。
間違ったスタイルを使っているプロジェクトもあるが、その場合はプロジェクトの規約に従うのが大事。
一貫性の方が重視される。

コメントすべきことを知る

  • コメントすべきではないことを知る
    コードを見てわかることは書かない。関数の名前と同じことを日本語でコメントアウトするなど

  • ひどい名前はコメントをつけずに名前を変える
    コメントで説明するくらいなら、関数等の名前をもっとわかりやすい名前に変える。
    関数名等はいろんなところで使用されるため、そっちを変えた方がよい。
    「優れたコード > ひどいコード + 優れたコメント」

  • 自分の考えを記録する
    優れたコメントというのは「考えを記録する」ためのものである。
    たとえばこんなの

// このデータだとハッシュテーブルよりもバイナリツリーのほうが 40% 速かった。
// 左右の比較よりもハッシュの計算コストのほうが高いようだ。

コメントから情報を得ることができ、下手に最適化しようとして時間を無駄に使う必要がなくなる。
コードが汚い理由を書いてもいい。

  • コードの欠陥にコメントをつける プログラマがよく使う記法
記法      意味        
TODO: あとで手をつける    
FIXME: 既知の不具合があるコード
HACK: あまりキレイじゃない解決策
XXX: 危険! 大きな問題がある
  • 定数にコメントをつける
    定数を定義するときはなぜその値を持っているかという背景を持っている

  • 読み手の立場になって考える

- 「全体像」のコメント

# 顧客が自分で購入した商品を検索する

このような、全体像が掴めるコメントをしておく。

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

リーダブルコードを未経験が読んで理解したこと

触ってない言語、機能について書かれている今必要なさそうなところは飛ばして、自分(初心者)がすぐに実践できそうな知識についてまとめてみました。

優れたコードとは??

他者が読んで理解できるコード。
コードは短い方がいいが、『理解するまでの時間』を短くする方がよい。
そのため短くすることで逆にわかりにくくなるようであれば短くする必要はない。

名前に情報を詰め込む

変数や関数、クラス名でも名前に情報を詰め込むのが大事。名前は短いコメントのようなもの。
  • 明確な単語を選ぶ
    getPageだと何のページをgetしているかわからない。インターネットから取ってきたページなら、downLoadPage等の方がわかりやすい。

  • tmpやretvalなどの汎用的な名前は避ける。
    明確な理由があれば使用してもいい。

  • 抽象的な名前より具体的な名前を使う

  • 変数名に大切な情報を追加する
    ミリ秒を表す変数なら、変数名の後ろに_msとつけると何の変数かわかりやすい。

  • 名前の長さを決める

  • スコープが小さければ短い名前でも良い。

  • 頭文字と略語
    string⇨strなど他人にも通じる略語を使うのがいい。BackEndManager⇨BEM等、他の人がわからない略語はNG

  • 不要な単語は捨てる
    DoServeLoop()だったら、ServeLoop()でも必要な情報は損なわれてないのでOK。なくても通じる単語は捨てる。

  • 名前のフォーマットで情報を伝える
    エンティティごとに異なるフォーマットを使う。
    C++言語であれば、クラス名はキャメルケース、変数名は小文字にしてスネークケースで定義する、など。
    ローカル変数とクラス変数も、異なるフォーマットで書くと一目見て何かわかるので良い。

  • その他フォーマット規約
    プロジェクトや言語によってもフォーマット規約は変わってくる。
    JavaScriptでは、jQueryのライブラリ関数を呼び出したときは、変数名の頭に$をつけるというものがある。⇨iQueryのオブジェクトだと明確にわかるため。
    HTMLだと、タグのid名の区切り文字にはアンダースコアを、class名の区切り文字にはハイフンを使う規約が有力。

誤解されない名前をつける

自分のコードを読んでいる人が、自分の意図を正しく理解できることが大事。
  • 限界値を含め場合はminとmaxを使う。
    CART_TOO_BIG_LIMITという名前だと意味があいまい。(未満なのか以下なのかがわからない)⇨MAX_ITEM_IN_CARTのほうが意味が伝わりやすい。

  • 範囲を指定する場合はfirstとlastを使う
    startは適切な名前になるが、stopは複数の意味に解釈できるため、firstとlastを使用する方が適切。

  • 包含/排他的範囲にはbeginとendを使う

  • ブール値(真偽値)の名前
    read_passward = true
    パスワードをこれから読み取る?もう読み終わっている?適切な名前ではない。
    user_is_authenticated = true
    こっちのほうが適切。また、名前を否定形ではなく肯定系にしたほうがよい。

  • ユーザーの期待に合わせる
    getで始まるメソッドだとメンバの値を返すだけの軽量アクセであるという規約がある。
    この規約を守らないと、DBからすべてのレコードを取ってくるときの変数名にgetをつけたりすると、間違って使用したりしてコストが高くなってしまう。

  • 複数の名前を検討する

コードの美しさ

  • 一貫性のある簡潔な改行位置

  • メソッドを使った整列

  • 縦の線をまっすぐにする

$aaa     =  "test";
$b       =  "test";
$cccccc  =  "test";

イコールの位置を合わせると見やすい。

  • 一貫性と意味のある並び
    アルファベット順にしたり、「最重要」なものから重要度順に並べたり、対応する HTML フォームの フィールドと同じ並び順にするなど。

  • 宣言をブロックにまとめる

  • コードを段落に分割する
    文章と一緒。見やすくなる。

- 個人的な好みと一貫性
クラス定義のカギカッコの位置など、最終的には個人の好みによる部分が大きい。
間違ったスタイルを使っているプロジェクトもあるが、その場合はプロジェクトの規約に従うのが大事。
一貫性の方が重視される。

コメントすべきことを知る

  • コメントすべきではないことを知る
    コードを見てわかることは書かない。関数の名前と同じことを日本語でコメントアウトするなど

  • ひどい名前はコメントをつけずに名前を変える
    コメントで説明するくらいなら、関数等の名前をもっとわかりやすい名前に変える。
    関数名等はいろんなところで使用されるため、そっちを変えた方がよい。
    「優れたコード > ひどいコード + 優れたコメント」

  • 自分の考えを記録する
    優れたコメントというのは「考えを記録する」ためのものである。
    たとえばこんなの

// このデータだとハッシュテーブルよりもバイナリツリーのほうが 40% 速かった。
// 左右の比較よりもハッシュの計算コストのほうが高いようだ。

コメントから情報を得ることができ、下手に最適化しようとして時間を無駄に使う必要がなくなる。
コードが汚い理由を書いてもいい。

  • コードの欠陥にコメントをつける プログラマがよく使う記法
記法      意味        
TODO: あとで手をつける    
FIXME: 既知の不具合があるコード
HACK: あまりキレイじゃない解決策
XXX: 危険! 大きな問題がある
  • 定数にコメントをつける
    定数を定義するときはなぜその値を持っているかという背景を持っている

  • 読み手の立場になって考える

- 「全体像」のコメント

# 顧客が自分で購入した商品を検索する

このような、全体像が掴めるコメントをしておく。

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

並んだコンポーネントの幅を残りいっぱいにする方法

サンプル

See the Pen GRgJooL by taisukek (@taisukek) on CodePen.

flex-basisとflex-growを利用する

.parent {
 /*子要素にflexレイアウトを適用する*/
  display: flex;
}

.child1 {
 /*要素の幅を100pxに指定*/
  flex: 0 0 100px; 
}

.child2 {
  /*
    要素の幅を残りいっぱいにする
    (<親要素の幅>-<flexレイアウト適用対象のflex-basis値の合計>)
  */
  flex: 1 0 0; 
}

flexとは

flexはflex-grow, flex-shrink, flex-basisの短縮系のため以下2つは同じ

 flex: 1 0 0;
 flex-grow: 1;
 flex-shrink: 0;
 flex-basis: 0;
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【CSS】要素の縦中央揃えをいい加減攻略したい。

はじめに

この記事は 株式会社ピーアールオー(あったらいいな!を作ります) Advent Calendar 2019 の5日目の記事です。
突然の初学者向けみたいな内容ですが、よろしくお願いします。

今年は一年かけて、Angularを用いたWebサイトの開発に邁進していました。
Angular、モジュールを分割することで中々気持ちよく開発できるフレームワークだったのですが、モジュール分割をしてる都合上どうしてもCSSを弄らなければならないシーンが多く、弱点:CSSな自分は結構躓いてしまうシーンが多かったです。
中でも毎回悩ませてくれたのが、タイトルにもなっている縦中央揃えです。

縦中央揃えとは

名前の通り、要素を縦中央に沿って並べることです。
Angularなどのフレームワークではモジュールが独立しているため、要素のサイズを事前に決定することができない事が多いため、意外と多用することになります。

理想としてはこんな感じ。
image.png

ただ、どうにもこの縦中央揃え、世に書かれているおすすめコードを試してみても効いたり効かなかったりして、最終的に
「色々試してたら書き散らかしたコードが上手い具合に効いて縦中央に揃ったわ!ヨシ!」
となりがちだったので、今回はこの場を借りて巷でよく聞く縦中央揃えの手法を実際にいじり倒してみようかと思います。

確認環境

  • Google Chrome 78.0.3904.108
  • Firefox 70.0.1
  • Microsoft Edge 44.18362.449.0
  • Internet Explorer 11.476.18362.0

(スクリーンショットはGoogle Chromeを使用)

ベースコード

ちょっと長いので折り畳み
sample.html
<head>
  <style>
    .parent-box {
      display: block;
      width: 350px;
      height: 200px;
      border: 3px solid rgba(100, 0, 0, 1);
      background: linear-gradient(
        180deg,
        #ff9999 0%,
        #ff9999 50%,
        #ffff99 50%,
        #ffff99 100%
      );
    }

    .child-box {
      display: inline-block;
      width: 100px;
      border: 3px solid rgba(0, 0, 100, 1);
      background-color: rgba(100, 100, 255, 0.3);
    }
    .child-box.one {
      font-size: 16px;
      height: 50px;
    }
    .child-box.two {
      font-size: 24px;
      height: 80px;
    }
    .child-box.three {
      font-size: 12px;
      height: 30px;
    }
  </style>
</head>
<body>
  <div class="parent-box">
    <span class="child-box one">Child1</span>
    <span class="child-box two">Child2</span>
    <span class="child-box three">Child3</span>
  </div>
</body>

事前知識:inline要素の縦位置の相互作用

縦中央揃えに行く前に、まずinline要素を並べたときにどんな相互作用が発生するか理解しておく必要があります。

では、まずなんも考えずにベースコードを実行して、何が表示されるか見てみましょう。
no-style.png
…一番上にきちっと揃うのを期待してましたがガッタガタですね。個人的にもうこの時点でなんでやねん!とベタな突っ込みをしてしまいそうになるのですが、一旦落ち着いて1本補助線を引いてみましょう。
baseline.png

フォントサイズの違う3つの文字がきっちりラインで揃ってるのがわかると思います。
このラインがbaselineです。vertical-alignによって位置設定がされていないinline要素は、「alphabetic」というアルファベットベースのbaselineによって、位置が規定されます

もう少しbaselineがどういう動きをするか、色々試してみましょう。
例えば、画像・二行以上の文章・要素の中身なしだと…?
iroiro.png
どうやら、画像の下・一番下の行の下・要素自体の一番下がbaselineとして設定されるようです。
直感的といえば直感的な揃い方ですかね…?

inline要素はこのように同じラインにある子要素の影響を受ける可能性のある要素ということを覚えておく必要があります。

さて、この知識を武器に縦中央揃えを攻略していきましょう。

よく聞く縦中央揃えの手法

今回は以下の5つの縦中央揃えの手法を試してみたいと思います。

  • vertical-align: middle;
  • line-height: (親要素の高さ);
  • margin: auto 0;
  • transform
  • display: table-cell;

vertical-align: middle;

名前が縦中央に揃えられるぜ感を出してるせいで、最初に適当に試して玉砕しがちな手法ですね。

まず、vertical-alignは子要素同士の位置関係性を定義するプロパティです。
したがって、子要素に対して付与するプロパティとなります。

では試しに子要素につけてみましょう。
middle1.png
お、未適用の状態に比べるとbaselineの制約が消えて縦中央に揃いましたね。いやーめでたsコレジャナイ。
はい。やりたいのは親要素に対する中央揃えなので、子要素の縦中央だけ合わせても仕方ないですね。
子要素の中央揃えも必要になりますので、vertical-align: middle; は他の中央揃えの手法と組み合わせて使うのが基本のようです。

ただし、どれかの子要素の縦の中心が親要素の中心と一致している場合 (例:親要素の高さ=子要素の高さ)、vertical-alignのみでも他の要素の縦中央揃えが可能です。
試しにChild3の縦中心を親に合わせてみたのが以下です。
image.png
Child3のボックスに引きずられて、Child1,2どちらも縦中央に揃っています。
このやり方は一つでも高さを指定できるinline-blockが入っていれば有効ですので、意外とこれだけでなんとかなるシーンは多そうです。

line-height: (親要素の高さ);

テキストがline-heightに対して縦中央に配置されることを利用して、無理やり縦中央揃えに利用してしまおうという、どこなくパワーを感じる手法ですね。

まあ、まずは何も考えずに適用してみましょう。テキストに対するプロパティなので適用は「親要素」「子要素全て」のどちらでもOKです。
image.png
あっ、はい。
inline-blockだと内部テキストにデザインが追従しないので文字だけが吹っ飛んでしまうようですね…。また、Child2のbaselineに引きずられて、Child1, Child3の文字が中央からずれているようです。

では、子要素のdisplay: inline-block;display: inline;に変更して、子要素同士が縦中央に並ぶようにvertical-align: middle;を追加してみましょう。
image.png
縦中央に並びましたね!
元のinline-blockを利用する想定とは違いますが、inlineの子要素のみならこれでも行けそうです。
ただし、line-heightは値として"100%"が使用できないので親要素の高さが固定であることが前提となるのに注意する必要があります。

margin: auto 0;

自動的に揃えたい時にautoって単語は非常に心地よく耳に響きますよね。
flexboxのmarginの上下にautoを設定するとうまい具合に(よくわかってないの意)中央揃えになってくれる機能を利用したものです。

もう説明からして求めているものですが、落ち着いて適用してみましょう。
親要素に、display: flex;、子要素にmargin: auto 0を適用しています。
image.png
かなりきれいな中央揃えになりました!baselineの影響も受けていないようです。

なにかすんなり行き過ぎて悔しいので、子要素がinline要素の場合も試してみましょうか。
全ての要素をinlineにして確認してみます。
image.png
悔しいことにこちらもきれいに縦中央揃えになるようです。

Flexboxを利用して問題のないデザインであれば縦中央揃えはmargin: auto 0;が安定しているようです。

transform

失敗が続きパラメータによる自動整列が信用できなくなってくる頃に使いたくなってくる、ちゃんと要素をずらして縦中央揃えを実現する手法です。
以下の三つの要素を子要素に適用することで縦中央揃えを実現します。

{
      position: relative;
      top: 50%;
      transform: translateY(-50%);
}

上記CSSの挙動としては、
1. 親要素の高さの50%の位置を始点に子要素を描画する(top: 50%;)
2. 子要素の高さの50%だけ子要素を上に移動させる(transform: tranlateY(-50%);)
といった感じです
50%の意味が異なるのでちょっと混乱しますが、動作を書きだしてみるとシンプルで間違いのない縦中央揃え方法ですね。

では、子要素に適用してみましょう。
image.png
んん? なぜかChild1, Child3が微妙に中央からずれてしまっていますね…。baselineに沿っているような感じでもないですし…。
確認のために、transform: tranlateY(-50%); を外してみましょうか。
image.png
なるほど、どうやらこれもbaselineの影響のようです。transform: tranlateY(-50%); で綺麗に中央に寄るには全子要素の一番上が親要素の中央線と同じ場所になければなりません。
それが達成できるように、子要素を上揃えにするvertical-align: top;を追加して改めてやりなおしてみます。
image.png
よし!きれいに縦中央揃えになりました!。

では、inline要素の場合はどうでしょうか?全ての要素をinlineにしてみます。
image.png
うーん、どうやらtransform: translateY(-50%);が機能していないようです。inline要素は高さを持っていませんので、その影響だと思われます。

今回の様にinline-blockで構成されている子要素ならば問題ないですが、inline要素の場合は別の縦中央揃えを利用するほうが良さそうです。

display: table-cell;

縦中央揃えって言葉から中々連想が出来ない秘策がdisplay: table-cell;です。
基本的な使い方は、親に以下の要素を追加する形です。

{
    display: table-cell;
    vertical-align: middle;
}

では試しにやってみましょう。
image.png
あ、なんかもう見慣れた感じのズレですね。余計な事は言わず粛々と子要素にvertical-align: middle;を追加しましょう。
image.png
綺麗に縦中央揃えになりました!
このまま子要素をinlineにしてみましょう。
image.png
inlineにしても問題なく縦中央揃えになるようです!

かなりお手軽に中央揃えが出来るtable-cellですが、ちょっと特殊な要素でもありますので使う際は意識しておく必要がありそうです。
※ 以下の記事がtable-cellの制約について詳しく解説しています。
display:table-cell;を安易に使うべきでない理由いろいろ

まとめ

各縦中央揃えについて

vertical-align: middle

  • 通常は親要素に対して縦中央揃えはできない。
    • 親要素と縦の中心が一致している子要素があれば可能。
ベースコードへの適用例

コード
sample-vertical.html
<head>
  <style>
    .parent-box {
      display: block;
      width: 350px;
      height: 200px;
      border: 3px solid rgba(100, 0, 0, 1);
      background: linear-gradient(
        180deg,
        #ff9999 0%,
        #ff9999 50%,
        #ffff99 50%,
        #ffff99 100%
      );
    }

    .child-box {
      display: inline-block;
      width: 100px;
      border: 3px solid rgba(0, 0, 100, 1);
      background-color: rgba(100, 100, 255, 0.3);
      vertical-align: middle;
    }
    .child-box.one {
      font-size: 16px;
      height: 50px;
    }
    .child-box.two {
      font-size: 24px;
      height: 80px;
    }
    .child-box.three {
      font-size: 12px;
      height: 194px;
    }
  </style>
</head>
<body>
  <div class="parent-box">
    <span class="child-box one">Child1</span>
    <span class="child-box two">Child2</span>
    <span class="child-box three">Child3</span>
  </div>
</body>

line-height: (親要素の高さ)

  • 縦中央揃えが適用されるのはinline要素のみ。
  • 親要素の高さが固定長である必要がある
  • 各要素のbaselineが異なる場合、vertical-align: middleを適用する必要あり。
ベースコードへの適用例

コード
sample-line.html
<head>
  <style>
    .parent-box {
      display: block;
      width: 350px;
      height: 200px;
      border: 3px solid rgba(100, 0, 0, 1);
      background: linear-gradient(
        180deg,
        #ff9999 0%,
        #ff9999 50%,
        #ffff99 50%,
        #ffff99 100%
      );
      /* ボーダーの影響を受けるため、3px * 2だけ小さくする必要がある */
      line-height: 194px;
    }

    .child-box {
      display: inline;
      border: 3px solid rgba(0, 0, 100, 1);
      background-color: rgba(100, 100, 255, 0.3);
    }
    .child-box.one {
      font-size: 16px;
    }
    .child-box.two {
      font-size: 24px;
    }
    .child-box.three {
      font-size: 12px;
    }
  </style>
</head>
<body>
  <div class="parent-box">
    <span class="child-box one">Child1</span>
    <span class="child-box two">Child2</span>
    <span class="child-box three">Child3</span>
  </div>
</body>

margin: auto 0;

  • inline要素、inline-box要素どちらでも正しく縦中央揃えを実行することができる
  • 親要素をflexにする必要があるため、適用できるかは要検討。
ベースコードへの適用例

コード
sample-margin.html
<head>
  <style>
    .parent-box {
      display: flex;
      width: 350px;
      height: 200px;
      border: 3px solid rgba(100, 0, 0, 1);
      background: linear-gradient(
        180deg,
        #ff9999 0%,
        #ff9999 50%,
        #ffff99 50%,
        #ffff99 100%
      );
    }

    .child-box {
      display: inline-block;
      width: 100px;
      border: 3px solid rgba(0, 0, 100, 1);
      background-color: rgba(100, 100, 255, 0.3);
      margin: auto 0;
    }
    .child-box.one {
      font-size: 16px;
      height: 50px;
    }
    .child-box.two {
      font-size: 24px;
      height: 80px;
    }
    .child-box.three {
      font-size: 12px;
      height: 30px;
    }
  </style>
</head>
<body>
  <div class="parent-box">
    <span class="child-box one">Child1</span>
    <span class="child-box two">Child2</span>
    <span class="child-box three">Child3</span>
  </div>
</body>

transform

  • inline-block要素は縦中央揃えにすることが可能
    • 各要素のbaselineが異なる場合、vertical-align: top; で調整する必要がある。
  • inline要素はうまく縦中央揃えにすることができない。
ベースコードへの適用例

コード
sample-transform.html
<head>
  <style>
    .parent-box {
      display: block;
      width: 350px;
      height: 200px;
      border: 3px solid rgba(100, 0, 0, 1);
      background: linear-gradient(
        180deg,
        #ff9999 0%,
        #ff9999 50%,
        #ffff99 50%,
        #ffff99 100%
      );
    }

    .child-box {
      display: inline-block;
      width: 100px;
      border: 3px solid rgba(0, 0, 100, 1);
      background-color: rgba(100, 100, 255, 0.3);
      position: relative;
      top: 50%;
      transform: translateY(-50%);
      vertical-align: top;
    }
    .child-box.one {
      font-size: 16px;
      height: 50px;
    }
    .child-box.two {
      font-size: 24px;
      height: 80px;
    }
    .child-box.three {
      font-size: 12px;
      height: 30px;
    }
  </style>
</head>
<body>
  <div class="parent-box">
    <span class="child-box one">Child1</span>
    <span class="child-box two">Child2</span>
    <span class="child-box three">Child3</span>
  </div>
</body>

display: table-cell;

  • inline要素、inline-box要素どちらでも正しく縦中央揃えを実行することができる
  • 親要素をtable-cellにする必要があるため、適用できるかは要検討。
ベースコードへの適用例

コード
sample-table.html
<head>
  <style>
    .parent-box {
      display: block;
      width: 350px;
      height: 200px;
      border: 3px solid rgba(100, 0, 0, 1);
      background: linear-gradient(
        180deg,
        #ff9999 0%,
        #ff9999 50%,
        #ffff99 50%,
        #ffff99 100%
      );
    }

    .child-box {
      display: inline-block;
      width: 100px;
      border: 3px solid rgba(0, 0, 100, 1);
      background-color: rgba(100, 100, 255, 0.3);
      position: relative;
      top: 50%;
      transform: translateY(-50%);
      vertical-align: top;
    }
    .child-box.one {
      font-size: 16px;
      height: 50px;
    }
    .child-box.two {
      font-size: 24px;
      height: 80px;
    }
    .child-box.three {
      font-size: 12px;
      height: 30px;
    }
  </style>
</head>
<body>
  <div class="parent-box">
    <span class="child-box one">Child1</span>
    <span class="child-box two">Child2</span>
    <span class="child-box three">Child3</span>
  </div>
</body>

子要素の属性による縦中央揃えの効きの有無

手法 inline-block要素 inline要素  親要素制約
vertical-align: middle (高さ指定) △※ なし
line-height: (親要素の高さ) × 固定長が指定できること
margin: auto 0; 親表示要素がflexであること
transform × なし
display: table-cell; 親表示要素がtable-cellであること

※ 縦中央が親と一致するinline-blockが混在している場合は、縦中央揃えが可能。

感想

いじり倒してる内に万能の解法が見つからないかな、と淡い期待を持っていたのですが、やはり手法が乱立してるだけあって一長一短、中々簡単にはいかないようです…。
ただ、これなら効く、効かないというのが割とはっきりしたので、今後縦中央揃えにチャレンジしなければならなくなっても上手く立ち回れそうです。
あと、とりあえずCSSで記事書くのはめっちゃしんどい事はわかりました。

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

入社してCSS記述で指摘されたこと?

入社してCSS記述で指摘されたこと?

はじめに

この記事は、 CAMエンジニア Advent Calendar 2019 5日目の記事です。

記事一覧はこちらから↓
https://qiita.com/advent-calendar/2019/cam-inc

昨日はid:gasheeeeさんの ブラウザレンダリング入門 でした。
ブラウザレンダリングについてて書かれてあるので「レンダリングがいまいちパッとしてないなあ〜」と思う方は是非見てみてください!!

この記事では自分id:youkouJBが半年間フロントエンドの職種で業務を行う中でトレーナーさんから指摘されたcssの記述について書いていきたいと思います。

1. 親要素に影響をもたらす子要素のmarginはNG!

まず一つ目にmarginの当て方について指摘された内容を書いていきます。

自分が指摘を受けたのはcomponentの中のmarginが外のcomponentに影響するからおかしいというもので、、、

簡単な例をあげると、

index.html
<div class="box"></div>
<div class="box">
  <div class="box__item"></div>
</div>

上記のようなhtmlがあり、
box を一つの親要素のcomponent、その中のbox__item を子要素のcomponentと仮定します。

その中で、boxとboxにmarginを持たせたいと思い、下記のようなcssを書いてみます。

index.css
.box {
  height: 200px;
  background-color: #ccc;
}

.box__item {
  margin-top: 40px;
  height: 100px;
  background-color: #000;
}

実際に表示上では、boxとboxの間にmarginを持たせることができていますが、

box__item (子要素)にmarginを持たせてしまっているため、そのcomponentがいらなくなり削除してしまうと、完全にmarginがなくなってしまい表示に影響が出てしまいます。
sample1.png sample.png
そのため、親要素に影響が出ないように子要素のcss記述をしなければいけないというものでした。

サービスの中ではいくつかこのようなスタイルの当て方になっているものもあったので、見つけたら直せるようにしていきたいと思います。

2. BEMのmodifierについて

次にBEM(block,element,modifire)について指摘を受けた内容について書いていきます。

BEMは、

  • block: 一つのまとまり、親要素

  • element: blockの一属性である子要素

  • modifier: 状態変化を表現する要素

に分けて考える再利用可能なコンポーネントとコード共有を作成するのに役立つ記述方法です。

もっと詳しくBEMについて気になる方はこちらを見ていただければと思います。(公式)

今回指摘されたのは modifierについてで、
実際に指摘された記述がこちらで、

index.css
.service__subTitle--white {
  margin-top: 60px;
  color: white;
}

.service__subTitle--blue {
  margin-top: 40px;
  color: blue;
}

黒色のサブタイトルの他に白色のサブタイトル、青色のサブタイトルを追加したいと思いこのように記述しました。

しかし、このコードだと--white--blueっという拡張classがmargin-topを持ってしまっており、もし別に白いサブタイトルや青いサブタイトルが出てきてしまったらこのclassが再利用できなくなってしまいます。

自分はclass名を変更することで対応しましたが、そのまま突っ走ってしまうと、いずれclassが増えたときや必要じゃなくなった際にゴジャゴチャになってしまいかねないので、気をつけなければいけないと思いました。。。

最後に

いかがだったでしょうか??
今回は入社してCSS記述で指摘された内容について書いていきました。
記事を書くにあたり、自分自身復習ができてよかったと思っております。
また、Qiitaに記事を書くことが初めてだったので至らぬところがあると思いますが、最後まで見ていただきありがとうございました!

「これは間違っている!」などありましたらコメント等でご指摘のほどよろしくお願い致します!

次回はid:tomomi_broさんのcssアニメーションについてです!
お楽しみに!!

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