【css】line-heightの使い方

テキストのすき間問題。見て見ぬふりしてきたシリーズの1つです。

vertical-align も気になっているのですが、今回は line-height を見つめ直す機会があったのでおさらいします。

まずこちらの記事を読んで「なるほど」と理解してから考えます。

【CSS】line-heightで行間を調整する方法:おすすめの値は?

覚えておきたいこと

line-height の単位は付けないほうが使いやすい

emや%よりも「単位なし指定」がオススメです。なぜかというとemや%だと親要素で計算された行高が、子要素にそのまま引き継がれてしまうからです。つまり、親要素のフォントサイズが40px、子要素のフォントサイズが20pxの場合にも、子要素には親要素と同じ行間が適用されてしまうのです。 一方で単位なし指定の場合、子要素のフォントサイズに応じて行高を計算し直してくれます。

てっきり単位なしは em% と同じ意味だと思っていました(この2つは同じ、だと思います)。

今までのコード書き直したい...。

line-height はblock要素に効く

これはinline-block でもダメでした。 今回検証したところ、span要素には効きませんでした。
確かに文章の途中で行間が変わる、というのは考えにくい事象ですね。

レイアウトしたもの

こんな感じの、1行目が大きい文字で、2行目が小さい文字のレイアウトです。
いろいろ書き方はあると思いますが、今回はp要素の中にspan要素で小さい字を入れて改行させました。

f:id:yokoyoko_115:20201119001000j:plain

この図が今回のまとめです。

当初大きい文字(1行目)と小さい文字(2行目)の行間がものすごく空いてしまい、line-height: 1em だ!line-height: 0だ!とあれこれやっていましたが、改めてちゃんと調べたらスッキリしました。

おまけ

ちなみに、line-height: 0 ですと要素の高さが0になってしまうようです。

テキストをドラッグして選択したときの高さというのは要素の高さとはまた少し違い、line-heightの高さなのかな?と思いました(line-height: 0 は最低限1文字の高さの範囲で選択できます)。
そもそもインライン要素の高さとは...。 このあたりややこしそうです。

See the Pen line-height検証 by yokoyoko (@yokoyoko_code) on CodePen.

正規表現チェックツールの使い方

ごく稀に正規表現を書くことがあり、その度に正規表現の書き方を調べています。 時間のないときはお手上げです...。

そんな時にこちらのツールを教えていただきました!

正規表現チェッカー | WEB ARCH LABO

次回以降、こちらのツールの使い方を思い出せるようにメモします。

正規表現チェッカーの画面の使い方

正規表現もよく分かっていないと、この画面だけを見ても使い方が分かりませんでした。

使い方
① 渾身の正規表現を「正規表現」の欄に入力する
② ①にマッチするであろう文字列を「検証対象文字列」の欄に入力する(改行して何パターンも文字列を検証できる)
③ マッチすると「結果」欄に②の文字列が赤く表示される

例)
f:id:yokoyoko_115:20201024005909p:plain

こんな感じで使いました。 「正規表現」の欄に右の正規表現の表を見ながら試行錯誤して入力して、ひたすらチェックするといった使い方になりそうです。

またこのサイトでは「HTMLエスケープ」という、HTMLエスケープされた文字列を返してくれるツールもあります。便利です。

正規表現とは

そもそもですが調べてみました。

サルにもわかる正規表現入門

端的に言えば、「いくつかの文字列を一つの形式で表現するための表現方法」です。

なるほど。

^$ などの特殊文字正規表現ではメタ文字というそうです。

正規化とは

こちらもよく聞く単語だったので調べました。

https://wa3.i-3-i.info/word11632.html

データとかを使いやすいように整理したり変形したりすることです。

正規表現と関係があるかと思いましたがそうでもないようです。
(同じ「正規」と付くだけあってそこまで遠くはなさそうですが...)

.htaccessでリダイレクトの方法

ちなみに今回は.htaccessでリダイレクトの設定をしました。

これもメモ程度にざっくり書くと、

RewriteRule サイト内の対象ページ リダイレクト先 [R=301,L]

です。正規表現を使って書くことができます。

頭に RewriteRule が付き、最後は [R=301,L] などで終ります。

また、「対象ページ」に書いた (.+) など () で囲った部分は、「リダイレクト先」に$1$2$3 と書いて渡すことができます。

例)

RewriteRule ^blog/(.+)cat/(.*)$ https://%{HTTP_HOST}/blog/cat/$2 [R=301,L]

これで
https://example.com/blog/postcat/hoge

https://example.com/blog/tcat/hoge
リダイレクトします。
$2 には (.*) が渡ります。

.htaccessの書き方は勉強しよう!

と、自分に言い聞かせています。

.htaccessではいろいろなことができますが、1歩間違えればサイトにアクセスすらできない、恐れ多い印象を持っています。
難しく感じてしまうのは正規表現をつかった処理が出てくるから、というのもあると思います。
少しずつ理解していきたいです。

正規表現がある程度スラスラ書けるようになると、いろいろな場面で役立ちそうなので、 こういったツールを使って正規表現に慣れていきたいです。

コマンドが見つかりません(command not found)の対処法

npmのプログラム(パッケージ)をインストールしても、コマンドを叩いてうまくいかないことがあります。

うまくいかなかったケース

私がハマってしまったのは、ProgateのNode.jsの「Expressのアプリケーションを作成しよう」というコラムを実践していたときです。

コラムはこちら

Node.jsの新規アプリケーションを作ろう! | プログラミングの入門なら基礎から学べるProgate[プロゲート]

npmのパッケージ、「nodemon」をインストールしても nodemon app.js でサーバー起動ができないというものでした。

インストール
・グローバル

npm install -g nodemon

・ローカル

npm install nodemon

ローカルやグローバルにインストールしたり、1回アンインストールして再度インストールしてみてもだめ。

実行

nodemon app.js

とすると、
zsh: command not found: nodemon と返ってきます。

☆後ほどグローバルでインストールして実行したところ、うまくいきました。スペルミスしていたのか、何だったのでしょう...。
めでたしめでたしですが、ここはローカルにインストールした場合で進めます。

環境

  • シェルはzsh
  • nodenvからnodeとnpmはインストール済み

原因と対処法

原因はPATHが通っていないケースが大半なのではないでしょうか。

実際、パスを付けてnodemon という実行ファイルを直接叩けば実行されました。

node_modulesフォルダのあるところまで移動して

./node_modules/.bin/nodemon app.js

です。
(ローカルにインストールしたnodemonの実行です)

毎回ここまで打つのは大変なので、その他の対処法を考えてみました。

対処法その1:PATHの設定をする

PATHの設定をすれば nodemon コマンド一つで実行できます。

Macで「zsh: command not found」が出る原因と対処法

環境変数のPATHには、実行したいプログラムのあるフォルダのパスを複数登録することができるので、そこに追加する、といったものです。

今回ローカルにインストールしたプログラム(nodemon)なので、できれば汎用的なパスだけの登録にしておきたいです。

env コマンドで環境変数(PATHなど)を確認できるということは覚えておきたいです。

以下はこちらを参考にしながらまとめていきます。
どうもありがとうございます。

知らないのは損!npmに同梱されているnpxがすごい便利なコマンドだった | Developers.IO

対処法その2:npm binを使って直接叩く

npm binはカレントプロジェクトのローカルパッケージPATHを返してくれるコマンドです。

実際にプロジェクトのディレクトリ内で npm bin と叩くと、ルートディレクトリから node_module/.bin までのパスが返ってきました。

$(npm bin)/nodemon app.js

でうまくいきました。

$() の書き方は初めて知りました。

Linuxでのドル記号「$(...)」の意味と使い方 | UX MILK

対処法3:package.jsonにscriptを追加する

nodemon のコマンドをpackage.jsonのscriptに登録して使う方法です。

npmのrun-scriptというしくみを利用します。
こちら↓には npm-script とあります。
「npmのrun-script=npm-script」なのでしょうか。

Node.jsユーザーなら押さえておきたいnpm-scriptsのタスク実行方法まとめ - ICS MEDIA

npm-scriptsとは、package.jsonファイルに記述可能なシェルスクリプトエイリアスです。エイリアスとはコマンド名を別のコマンド名に置き換えることです。

gulpを使わなくても、scriptフィールドでもりもりタスクを設定できることが分かりました。

package.json

 "scripts": {
    "nodemon": "nodemon"
  },

ターミナル

npm run nodemon app.js

で動きました。

また
package.json

 "scripts": {
    "nodemon": "nodemon app.js"
  },

ターミナル

npm run nodemon

でもOKです。

毎回サーバーを起動させるので、できる限りコマンドを短くしたい、となれば
package.json

 "scripts": {
    "start": "nodemon app.js"
  },

ターミナル

npm start

でしょうか。

ところでなぜコマンド名だけのシェルスクリプトの登録でうまく実行できるのでしょうか。

scriptsフィールドではローカルインストールしたパッケージのコマンドを直接実行できるテクニックを使用したものです。

npmのパッケージの構成ファイルであるpackage.jsonに書いたものなので、そう言われたらそうですね。

対処法4:npxをつかう

npx とは

npxはnpmパッケージを簡単に実行できるコマンドです。具体的には次のようなことができます。

  • run-scriptを使用せずにローカルインストールしたコマンドを実行する
  • グローバルインストールせずに一度だけコマンドを実行する
  • GitHubやGistで公開されているスクリプトを実行する

他の記事でも出てきた、遊び心いっぱいのパッケージで私も試してみました。

npx yosay Hello!

f:id:yokoyoko_115:20201017011821p:plain

npxでは、事前インストールせずに一度だけコマンド実行でき、実行後には削除されます。

便利便利と書かれているので便利なのでしょうが、残念ながらまだ実感できず...。パッケージをお手軽に使いたくなる日が来ますように。

気になったこと

ここまで書いていて追加で気になったことをまとめました。

パッケージとモジュールの違いについて

未だに「パッケージ」と「モジュール」の差がよくわかっていません。同じだと思っていました。

どうやら違うようなので、こちらの記事を見て自分の言葉に替えてみました。

【npm】パッケージとモジュールの違いって何? - Qiita

パッケージ

パッケージとはpackage.jsonによって記述されるファイルもしくはディレクトリのことを指します。

なので、package.jsonがある、node_moduleディレクトリ内のディレクトリたちは各パッケージなのだと思います。

モジュール

モジュールとは、Node.jsの require 機能によって呼び出すことができる node_modules 内のファイルまたはディレクトリのことを指します。

この「Node.jsの require 機能によって呼び出す」というのは、今のところgulpfile.jsで見たことがあります。

モジュールとして require 機能によって読み込まれる為には、次のいずれかである必要があります。

  • package.json を含むフォルダーであり、mainフィールドを含むファイルであること。
  • index.js というファイルが入っているフォルダであること。
  • JavaScript ファイルであること。

package.jsonname フィールドはパッケージ名、 main フィールドはメインエントリー(?)といいjsファイルやディレクトリ名が入るようです。

package.jsonの内容をまとめてみました - Qiita

これらからnodemonはパッケージでありモジュールであることが分かりました。

パッケージを特にrequire 機能によって読み込まれるものをモジュールという
考え方でいいかと思いました。

自分たちもパッケージを作っているんだ、という意識を持ちました。
いろいろなパッケージを組み合わせてオリジナルのパッケージを作っているって改めてすごい。

パッケージにはコマンドを提供されているものとされていないものがある

コマンドが提供されている場合、node_modules/.bin/ 配下にコマンドが配置されます。

このことを覚えておけば、のちのち腑に落ちそうです。

実行ファイルに拡張子がついていないのは「コマンド」として打ちやすいからなのでしょうか...。中身はjsファイルですね。 そもそも .bin とは?ってなりますが、別の機会に調べます。

最後に

今までこのような「ローカルでインストールしたのにコマンドが見つからない」、といった問題にぶつかったことないのはなぜなのだろう、と考えたところ、直接コマンドを叩く機会がなかったからだと気づきました。

Node.jsのrequireでインストールしたモジュールを読み込んで、処理のコマンドをpackage.jsonでnpm-scriptとして実行していたからです。

npm-scriptで gulp sass と何の疑問を持たずに書いてきましたが、 ここにきて gulp コマンドって何でしょうか...気になります。

なにはともあれNode.jsの理解が深まってよかったです。

これまでNode.jsは単にgulpを使うために必要なものものぐらいにしか思っていなかったので、Progateのスライドも勉強になりました。

もう少し詳しく知りたいです!

おしまい。

PHPのメール送信を考える(前編)

先日WordPressプラグイン「ContactForm7 」と「WP Mail SMTP」を使ったメールフォームを作りました。
「WP Mail SMTP」には送信元アドレスやメーラーSMTP ホストなどを設定できますが、このプラグインを使わなくても「ContactForm7 」でメールフォームを作って送信できたはず、一体何が起こっているのだろう...と気になったので調べました。

メールは奥が深い

初心者(?)がイチから調べるにはあまりにも必要な知識が多すぎる! 気になることが後から後から出てきていつも以上に収拾がつかなさそうなので、ひとまずメール送信機能を作ってみます。

環境

  • MacMAMP(ローカル環境)でメールフォームを作る
  • SMTPサーバーはMAMP内に入っていれば(?)それを使って、なければGmailを使う
  • Gmailが送信側で絡むかもしれないので、送信先アドレスはyahooにする

↑書いていることも正しいのか今の時点では怪しいですが、これでスタートします。

フォームの作り方

まずはプラグインなしのPHPでメールフォームの作り方を学びます。

お問い合わせフォームを作る | GRAYCODE PHPプログラミング

きっとこちらが一般的な作り方なのだろうと信じます。

要点は

  • form要素をaction="" と空の値の属性を入れることで、1つのPHPファイル(index.php)で入力画面、確認画面、送信完了画面を用意する
  • 入力・確認はそれぞれPOST通信でデータを送る。
  • 確認・送信ボタンにそれぞれname属性を付け、その値($_POST['name名'])で入力・確認・送信完了画面の判別をする
  • メール送信は mb_send_mail関数を使う

です。

今回は入力画面、確認画面や見た目は考えず、送信だけできるページを作ります。

index.phpの一部

<?php if(empty($_POST["btn_submit"])): ?>
  <h1>ボタンを押すと送信</h1>
  <form method="post" action="">
      <input type="submit" name="btn_submit" value="送信">
  </form>
<?php else: ?>
  <h1>送信!</h1>
  <?php mySendMail(); ?>
<?php endif; ?>

<?php
function mySendMail() {
  // 変数の設定
  $to = "xxx@yahoo.co.jp";
  $subject = "メール送信のテスト";
  $text = "メール本文です。";

  // メール送信
  mb_send_mail($to, $subject, $text);
}
?>

f:id:yokoyoko_115:20200916132118p:plain
表側はとてもかんたんなつくり

送信してみる

送信先のメールアドレスが間違っていないか、いつも以上に確認して送信ボタンを押すと...

なんと送受信ができた!ダメ元だったのに。

yahooのメールアドレス宛に送信すると迷惑メール扱いすらされず受信箱に入っていました。
gmailのメールアドレスでは迷惑メールになっていました)

index.php では設定していなかった送信者情報がメールに入っていたので、送信時にどこかで設定された値が使われたと考えられます。

mb_send_mail関数について

mb_send_mail関数は、日本語などマルチバイトの文字をメール送信する時に使う関数で、中で mail関数を呼んでいます。

mb_send_mail( $to, $subject, $text, $header, $parameter);

mb_send_mail関数の引数 $header (省略できる)には、メールヘッダーに追加する送信者情報を入れる部分があります

送ったメールがスパム判定(迷惑メール)されないためのヘッダー設定 | GRAYCODE PHPプログラミング

送信者情報(抜粋)

・Content-Type – メール形式 ・Return-Path – 送信先メールアドレスが受け取り不可の場合に、エラー通知のいくメールアドレス
・From – 送信者の名前(または組織名)とメールアドレス
・Sender – 送信者の名前(または組織名)とメールアドレス
・Reply-To – 受け取った人に表示される返信の宛先
・Organization – 送信者名(または組織名)
・X-Sender – 送信者のメールアドレス
・X-Priority – メールの重要度を表す

これらの情報は、改行コードを入れながら一つの文字列にします。

MAMPのどこかで送信者情報が設定されているはずなので調べました。

PHPのメール送信に関する設定値

MAMPのスタートページから「TOOLS > PHOINFO」のページを見るとメール送信に関連する設定がありました。

Core(一部抜粋) PHP Version 7.4.2

Directive Local Value Master Value
sendmail_from no value no value
sendmail_path /usr/sbin/sendmail -t -i /usr/sbin/sendmail -t -i
SMTP localhost localhost
smtp_port 25 25

このページは phpinfo() を実行した結果を表示させたページです。
phpinfo() では、php.ini(拡張子の読みは「イニ」が多そう)ファイルなどで設定した、PHPの設定値を見ることができます。
設定値の変更はphp.iniだけではなく、Apache側からや.htaccessからもできます。優先順位があるそうです。

ちなみに読み込んでいるphp.iniの場所は、phpinfoの「Loaded Configuration File」にあります。

phpinfo関数による設定内容の確認 | PHPインストールと初期設定

php.iniファイルの確認と修正 | XAMPPの使い方

sendmailとは

phpinfoにもあった sendmail についてです。
mb_send_mail関数では内部でsendmailコマンドが実行されます。
sendmail」というのはメール転送エージェント(MTA)というメール配信用プログラムです。「postfix」というのも同じくMTAです。

メール転送エージェント:
https://wa3.i-3-i.info/word11134.html

sendmail コマンドの実行は、phpinfoにある「sendmail_path」の値を見て行われるのだと思います。

途中結果

ということは、今のところ

SMTPlocalhost ←ローカル環境にSMTPサーバがある?
SMTPのポート番号:25
送信者情報:sendmail の設定値?

と推測しました。

このsendmailpostfixの設定、何やら難しそうです...。

次回でsendmailについて調べられたらいいと思います。

挫折せずに後編を書けるといいです...!

新しく覚えた(使った)cssまとめ - 2020年春・夏

調べてその場で納得して終わりのケースが多いcss。いつでも振り返られるようにメモしました。

floatの解除に display: flow-root

【2017年最新】clearfix一番短い書き方は親要素にdisplay:flow-root;を書き加えるだけ - 自動化厨のプログラミングメモブログ│CODE-LIFE

最近あまり使う機会が減った float を使ったときに解除をどうしようかな、と思って調べました。
親要素に clearfix をかけるように、display: flow-root とするだけです。 結論、display: flow-root は2020年4月時点でIE11非対応なので、使用は断念しました(迷いどころ)。

現在:
Can I use... Support tables for HTML5, CSS3, etc

ちなみに、親要素に overflow: hidden をかける方法は非推奨と言われることが多いそうです。
本来の使い方(はみ出たら隠す)とは違うからでしょうか。

clearfix も時代を経て設定が少しずつ変わっているのですね。

最新のcleafix(2020年4月)

.clearfix::after {
    content: "";
    display: block;
    clear: both;
}

それにしても display はいろいろな値がありますね。
html5の概念からおさらいして gridlist-item は覚えておきたいなと思いました。

flotのおさらい:
CSSの【float】についてちょっと本気出して説明してみた。 | たねっぱ!

「clearプロパティを与えた要素にはmargin-topが効かない」
(※端折った表現です)

そうでしたか!

imgを指定の大きさに配置できる object-fit: cover

【CSS】object-fitはCSSだけで画像をコンテナーにフィットさせてトリミングもできるとっても素晴らしいプロパティー | WEBDESIGNDAY

このプロパティは、WordPressなどで画像を投稿してもらう際に、いろいろなサイズの画像を揃えて表示させるのに便利です。

ざっくりいうと object-fit: cover は背景画像の background-size: cover の普通の画像版です。
忘れそうになりますが、直接画像や動画要素に指定します。

また object-position では、画像の配置を指定することができます(初期値は上下左右中央)。

現在:
Can I use... Support tables for HTML5, CSS3, etc

flexコンテナの子要素、フレックスアイテムに直接指定できる align-self

align-selfプロパティの意味と使い方 | CSS | できるネット

どんな状況でこのプロパティを知ったのかもう忘れてしまいましたが、このようにボタンを下に配置したカードを横に並べたら揃ってきれいかもしれません!?

...と思ったのにalign-self 使っていません...。
イメージではボタン要素に align-self: flex-end かな、と思ったのですが、そうすると、高さの指定のない他の要素が justify-content: space-around の縦方向版みたいに等間隔の隙間を持つように配置されてしまいました。

ポイントはボックスの下に配置したい要素を margin-top: auto とすることです。

横並びレイアウトの中の一番下のボタンの位置をCSSでそろえる方法|トピックス|STEP UP WEB|大阪のホームページ制作・作成サービス

原理はどういうことなのだろう...。
ちなみに、

align-selfプロパティは、フレックスアイテムのクロス軸方向の揃え位置を指定します。

ということなので、 flex-direction: column でフレックスアイテムの並びを縦方向にすると、 align-self はクロスした、フレックスアイテムの左右の位置調整ができることになります。

そしてもしかしたらと思ったら、やはり justify-self というものがありました。

【CSS】flexboxにjustify-selfは効かない - Qiita

こちらも解決策は margin: auto みたいです。なんと...。

角の取れた四角

というか、「四角から角の取れた図形」です。

cssで少しデザインしたくなって、四角形から2つの角が取れた図形を作りました。
自力ではお手上げだったので、具体的なコードはこちらを参考にしました。

角の欠けた枠。つくるよ。 | パンスールブログ | 株式会社Penseur パンスール|東京・大阪のデザイン会社

border 絡みの図形はいつも図におこさないと混乱します。
cssの書き方は正確ではないのですが、ざっくりとしたメモの図です。

f:id:yokoyoko_115:20200825010530p:plain

border-color: transparent というのはしっかり色(透明)を指定している、ということです。borderの太さとスタイルを合わせて指定すれば透明な枠線です。隣り合う他の線と色が違えば、その境目は斜めに区切られます。

幅があって高さが0の疑似要素、というのも、今後いろいろ応用ができそうです。

a要素の疑似クラスの指定順をそろそろ覚える

毎回調べているのですが、今度こそ理屈まで覚えようと思います。

:link、:visited、:hover、:active の記述順序とその覚え方 - jmblog.jp

覚え方は「LOVE and HATE」が有名みたいです。
以下の順で書くと、状態ごとに異なるスタイルのa要素にできます。

擬似クラス 状態
link 未訪問のリンク
visited 訪問済みのリンク
hover 要素にカーソルが重なっている
active 要素がクリックされている押し始めから離す時まで

:hover:active はa要素に限らず指定できます。

図にしたら腑に落ちました!

f:id:yokoyoko_115:20200830020617j:plain

  • ちなみに、link と visited は打ち消しあうことがないので順番はどっちでも OK
  • :hover 擬似クラスと:active 擬似クラスは一連の動作である

これらがポイントだと思いました。
そしてcssでは下に書いたものが優先されることを考えて...。

  • 未訪問
  • 未訪問で要素にマウスカーソルを合わせている
  • 未訪問で要素をクリックしている
  • 訪問済み
  • 訪問済みで要素にマウスカーソルを合わせている
  • 訪問済みで要素をクリックしている

これら6つの状態のうち、より限定的であるクリックしている状態の :active が最後にきます。

:focus の扱い(PCの場合)

a要素に指定できる擬似クラスでもう一つ、 :focus があります。 :focus は主にform関連の要素に指定できます。
a要素もPCではtabキーを押すとフォーカスしますし、クリックしてもフォーカスします。
(returnキーでリンク先に遷移できますが、キーを押すことは、:active の対象ではないみたいです)

状態は、他の要素にフォーカスが移る(他の要素をクリックする)までの間です。
ただ、a要素に :focus を設定しても、クリック後、ほどなくしてページ遷移する事が多いため、フォーカスの状態は一瞬です。

ページ遷移の話はさておき、フォーカスできるある要素に
マウスを合わせる→クリック→他の要素をクリック
という操作をした場合、こんなイメージになるかと思います。

f:id:yokoyoko_115:20200830000509j:plain

そう考えると、a要素で :focus を指定したい場合は、
:hover:active の間
が適当かなと思います。

:active:focus どちらを先に指定したらいいか、下記でも試してみました。

a要素、form関連要素以外で要素をフォーカスさせる方法

フォーカスさせたい要素にtabindex 属性を指定します。

aタグ以外にもキーボードフォーカスをあてる方法 - Qiita

↑のCodepenでも検証してみました。

このクリック関連、今回はPCを想定してまとめています。
スマホの場合はマウスカーソルを要素に合わせる、という操作がないので、:hover:action:focus の扱いがまた違ってきます。

PCとスマホでクリック時のスタイルを揃えたいときなどにまた掘り下げようと思います。

最後に

あといくつかありましたが、a要素の擬似クラスの話が膨らんでしまい、ここで一度おしまいにします。 またまとまったらcssの記事書こうと思います!

コンパイルとcssを考える

ソースマップの記事を書いていたら「コンパイル」が気になってしまいました。

scss→cssコンパイルなの?

過去の記事でも混乱していました(笑)
調べているとコンパイラ言語からプログラムの実行をする過程の中でコンパイルが出てくるので図にしました。

f:id:yokoyoko_115:20200804003940p:plain

図は正確にはあってないと思います。
コンパイルによってできたオブジェクトファイルというのは中間語なのか、機械語なのか。このあたりはいろいろな記事があってうまくまとめられませんでした。
C言語を勉強してみようか...。

コンパイラとは

コンパイラ - Wikipedia

コンピュータ・プログラミング言語の処理系(言語処理系)の一種で、高水準言語によるソースコードから、機械語あるいは元のプログラムよりも低い水準のコードに変換(コンパイル)するプログラムである。

なんとオブジェクトコードに変換する以外にも広い意味で「変換」するということなんですね!
そう考えれば、scssファイルからプログラミング言語ではない、スタイルシート言語のcssへの変換も「コンパイル」と言えると。
そう解釈しないとこの一度モヤモヤした気持ちはどうすればいいのか...。

CSSプリプロセッサ

そんなときプリプロセッサという存在を知りました。

プリプロセッサとは

プリプロセッサ(プリコンパイラ)とは - IT用語辞典 e-Words

プリプロセッサとは、ソフトウェアの役割による分類の一つで、ある中心的な処理を行うプログラムに対して、その前処理(preprocess)を行うプログラムのこと。プログラミング言語コンパイラの前処理を行うものが非常に有名。一方、メインの処理に対する後処理を行うものは「ポストプロセッサ」(postprosessor)という。

「ビルド」機能とは?仕組みやコンパイルとの違いを解説 | サービス | プロエンジニア

コンパイルまでには静的解析とプリプロセッサの処理が行われます。

プリプロセッサの別名は「プリコンパイラ」のようなので、そこからscss→cssを「コンパイル」と呼ばれるようになったのではないかと思いました。

CSSプリプロセッサの種類

CSSプリプロセッサにはいくつかあります。

  • Sass (Syntactically Awesome Style Sheets)
  • Scss (Sassy CSS)
  • Less (The Dynamic Stylesheet Language)
  • Stylus
  • PostCSS

プリプロセッサはプログラムのことを指したり、言語のことを指したり(これらはメタ言語)、どちらもあるようです。
混乱しそうですが、「Sass(言語)を使うにはSass(プログラム)をインストールする必要があります」という解釈でいいかなと思いました。

おまけ

いろいろ脱線したので、副産物の中からある程度まとめられた部分をメモします。

スクリプト言語インタプリタ言語の違い

ここでもどうしても「〜言語」がよく出てくるので調べました。
コンパイラ言語(型)とインタプリタ言語(型)は対義語的だなと理解しましたがスクリプト言語というのもあるとは。

スクリプト言語とは?インタプリタ型言語との違いは? | じゃぱざむ

今まで「スクリプト言語」だと思っていたものは「インタプリタ言語」でした。

図にしようと思いましたが、雰囲気で覚えておこうと諦めました。

コンパイラ言語でかつスクリプト言語であるというjavaを勉強してみようか...。

ブラウザでのレンダリングについて考える

今度は"コンパイル後"のcssファイルがどのようにブラウザで使われているか調べました。

ブラウザでは最初にDOM ツリー、CSSOM ツリーを構築する

オブジェクト モデルの構築  |  Web  |  Google Developers

CSSはHTML同様、CSSOM ツリーという、ツリー構造のオブジェクトモデルを構築します。

CSS のバイトが文字、トークン、ノードへと変換されていき、最終的に「CSS オブジェクト モデル」(CSSOM)というツリー構造にリンクされます。

とあるので、ソースを読み込んだ後に「バイト」になっているようです。 ↑のページの図を見ると3C 62 6F...とあります。

これはいわゆる機械語です。0と1だけのもののみを指すのかと思いきや、16進数で表されるものも機械語というのですね。

この後、DOM ツリー、CSSOM ツリーができて、
→ DOM と CSSOM を組み合わせてレンダリング ツリーを作る → Layout → Paint...

と続きます。この後の処理については別の機会に学びます。

フロントエンジニアなら知っておきたいブラウザレンダリングの仕組みをわかりやすく解説! | LeapIn

HTMLの書き方を見直し

W3CのMarkup Validation Service(マークアップバリデーションサービス)でウェブページを確認する機会がありました。
これって警告・エラーなんだ!という新しい発見がありましたのでメモします。

※2020年7月現在の内容です。

コメントの中にハイフン2つが出てくると警告

<!-- --←これがよくない -->

です。
BEMで書いているとクラス名に「--」がでてきて、その要素をコメントアウトしていたので警告を受けていました。

正しいコメントを書こう

見出しタグ(h2など)はsectionタグ内では孫要素とかでも良い

<!-- NG -->
<section>
  <div>
    <p>見出しテキスト</p>
  </div>
</section>

<!-- OK -->
<section>
  <h2>見出しテキスト</h2>
  <div>
    <p>テキスト</p>
  </div>
</section>

<!-- これもOK -->
<section>
  <div>
    <h2>見出しテキスト</h2>
  </div>
</section>

section要素のすぐの子要素でなければならないと思っていました。divを使いたいことがよくあるので一安心です。

iframe要素の廃止された属性をつかうとエラー

  • frameborder
  • scrolling
  • marginheight
  • marginwidth

これらは代わりにcssで設定するように、と書かれていました。

しかし、エラーを受けている該当のコード、yahooの!タグマネージャーの部分なんですよね...。

<noscript>
<iframe src="//b.yjtag.jp/iframe?c=XXXXXXX" width="1" height="1" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"></iframe>
</noscript>

公式に配布されているコードって弄りづらいのでこのままにしています。

ところでjavascripが無効のときに表示する <noscript>
どういう動きをするのか確認されている記事がありました。

HTML、noscriptタグの挙動について。(非表示なのか未解釈なのか)|マコトのおもちゃ箱 ~ぼへぼへ自営業者の技術メモ~

Unicode正規化フォームCでないとエラー

Unicodeユニコード)とは「符号化文字集合」というもので、UTF-8などの「文字符号化方式」とは別ものです。

分かりやすい記事です!
https://wa3.i-3-i.info/word11422.html

上記を踏まえて「正規化形式C」とは合成済み文字(例:が)のことをいいます。
結合文字列は文字列を結合したもの(例:か゛←「か」+「゛」)です。

「Text run is not in Unicode Normalization Form C.」というHTML Validation Serviceの警告について: 小粋空間

「正規化フォーム(形式)C」を使わないとエラーになるんですね。
これはどこでそう決定されるのでしょうか...。

ユーザーが画面拡大できないビューポートの設定だと警告

<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">

これで

Consider avoiding viewport values that prevent users from resizing documents.

という警告が出ました。
content属性の値から、 maximum-scale=1.0user-scalable=no を削除すると、ユーザーが画面サイズを変更することができます。

ビューポートもコピペで済ませている部分があるので、ちゃんと理解しないとと思います。

番外:CSSの警告・エラー

cssもチェックしたので少し載せます。

background-color と border-color は同じ色です

警告です。
同じ色だと同化してしまって背景と枠線がわからないですよ、と教えてくれているそうです。
ありがた迷惑のような気もしますが、優しさと受け取ってスルーします。

-webkit-animation is an unknown vendor extension

「-webkit-animationは不明なベンダー拡張です(Google翻訳)」という警告です。
ベンダープレフィックス関連の警告は多い印象です。
ブラウザのバージョンアップとともに -webkit- がいらなくなったりなど、刻々と変化しそうな部分なので、Autoprefixerを使っていきたいです。

CSSベンダープレフィックス-webkit-を今この瞬間に辞める為のAutoprefixerの導入 - Qiita

異なる環境でも同じ表示(クロスブラウザ)と正しいcss、どちらを取るか天秤にかけたら、前者かなぁと思います。

最後に

なかなかちゃんとhtml、cssの文法と向き合うことはないのでよかったです。
でもエラーチェック・対応はたまにがいいですね。