SASSでアンパサンドを後置できるって知らんかった

こんにちは!
またちょっと間があいてしまいました、有村です!!
日々コードレビューをしていると、新しい考え方や「ほうほうそりゃ知らんかった」って書き方に出会えて楽しいですね!
というわけで、今日のテーマはSASSでアンパサンドを後置できるって知らんかったです!

私がアンパサンド(&)を使うのは、だいたい

こういう、MindBEMdingの記法的な、「前のclass名と連結させる」ときです。

なので、アンパサンドって「前置しかできない」って思い込んでたんですが…。
普通に後置できるらしいですね。

ここで振り返り。
アンパサンドは「親セレクタの参照」。
そして、後置もできるってことは…

みたいな、「基本は display: block; だけど、fugaの子孫要素として居る場合は display: inline;」みたいなこともできるわけですね!

そこで私は期待した………

みたいに、子孫要素じゃなくて、要素セレクタ + class名指定で、限定指定みたいなことできるんじゃね?と…。
↑で言うと、「基本は .btn は display: flex; だけど、button要素の時だけは display: block;」みたいな。

それを考えた理由は、かつてのbutton要素に display: flex; が効かねぇの記事から。

そこでこんなコード書いてみた。

お気付きの方も多いでしょう……

ってなった。そりゃそうか。惜しい。

次は、こういう書き方をしてみた。

アンパサンド前のスペースを削ってみた。そしたらこうなった。

「”&” may only be used at the beginning of a compound selector.」

コンパイルすらできなかった!!!!
「&__」はいいけど、「__&」はダメってことね……。

ちょっと調べてみたけど、SASS側でどうこうはできなそう…
なので、実現方法としては

で対応しました…。

ん〜結果は同じなんですけど、この書き方だと「基本は display: block; で、button要素じゃないときだけ display: flex;」って、
「基本と例外」が逆転しちゃってるのが、目的に合ってないような気がするんですよね…。
とはいえ、今はこれしか思いつかなかったので、↑の実装で落ち着かせてます。
それ以外は、視認性も特段悪いわけではないと思うので…。

というわけで!
やりたかったことが完全に実現できたわけではないのですが、アンパサンド後置できる!って学んだことは大きな収穫です!
適材適所で活用していきたいと思いまーす!!

それでは、きょうはこのへんで。

inlineで隙間が発生してしまうのはなぜ?

こんにちは、有村です!
体調崩し気味ですが、比較的元気なうちに記事を書くぞ!!

今日のテーマは、inlineで隙間が発生してしまうのはなぜ?
です!
最近これを人に説明することが多いな〜と思ったので、メモしておくことにしました。
(うまく書けたら 「これ見といて^^」 でやり過ごせるかもしれない!やったね!)

たとえば、このようなコードがあったとしましょう。

これで、実際にレンダリングされるときには、liは横並びで表示されますね。

が!!!!
横並びに表示されたけど………なんかそれぞれの要素に隙間ができるんですケド!?!?
という経験、皆さんおありじゃないですか。
こんなかんじ。
戦士 白魔道士 黒魔道士 竜騎士

なんかよくわかんねーけどスペース空くわーってことで、

みたいに ul のfont-sizeを0にしてみたりとか、

のように繋げて書いてみたりとかしてましたが。。

そもそもなんで勝手に隙間が空くんだ?

てことで、その理由。
Enterキーで改行を行うと、改行が空白類文字として扱われるから。
ということは…実態は、
戦士(ulのfont-sizeで空白類文字)白魔道士(ulのfont-sizeで以下略)黒魔道士(ulのfont以下略)竜騎士(ulの以下略)
こうなっていたということですね!!
だから、ulのfont-sizeを0にしてみたり、繋げて書いて改行を無くすと、不要な隙間が生まれなくなるんですね!

じゃあdisplayがblockのときはどうなるの?と思って調べてみましたが、MDNやW3Cで答えを探し当てることができず…。
が、先人の方々の説明等を読み漁ってみて、実際の挙動と照らし合わせてこうかな?と思いました。

blockの場合、開始と終了タグ前後の改行は無視される。
ただ、

としたときは、黒魔道士の項と白魔道士の項の先頭には空白が入らないものの、レンダリングしてみると、
「黒魔道士は いちばんつよいよ!」
「白魔道士も すきだよ!」
と文章中にスペースが空いてしまいます。なぜなら、開始と終了タグの前後の改行ではないから。

また、もはやブロックレベル要素というものはHTML5に存在しませんが、MDNのブロックレベル要素のページの、

ブラウザは一般的に、前後に新しい行を伴ってブロックレベル要素を表示します。

が理由のひとつなのかなと思いました。
「前後に新しい行を伴う」ことが前提であれば、そこに改行があろうともなかろうとも、

みたいな書き方をしても強制的に行が変わるので、「無視をする」という挙動になるのかな?と推測しました。

このあたりは自分もかなり悩んだので、今回記事にすることで頭の整理ができてよかったです!
それでは、きょうはこのへんで。

ボタン作成で失敗したこと

こんばんは、有村です。
新年度を迎えても、実装でうんうん唸ってます。いつになったら立派になれるんだろうか。

さて、今日は備忘録としてボタン作成で失敗したことを残しておきたいと思いまーす!

何に失敗したかというと、ボタンに当てるCSSの選択と、HTML側の構造です。
(全然まだ最適解だとは思ってないのですが)

簡単に要所だけ書きますが、私こんな感じのソースを書いてました。

やりたかったのは、ボタンの中身を天地中央にするということ。
最初はline-heigetとpaddingを使っていたのですが、font-sizeとの兼ね合いもあったりとかで、「それだと高さを意識してボタン作るのが若干面倒だなぁ…」と思い、上のような形に作り変えました。

flexだとalign-itemsがあるじゃないですか。
そりゃ使うじゃないですか。
そしたらですよ。
実機(iPhone)で見たら崩れてた。

具体的にどう崩れていたかというと、ボタンの文言が思いっきり左に寄ってました。
普段はchromeのエミュレータで実装しているので、全く気付かなかったんですよね…。

なんでー!?って調べてみたら、どうやらブラウザのデフォルトスタイルとdisplay: flex;が干渉し合っており、flexのほうが競り負けているようだと知りました…。
いやらしいのがchromeは問題なく見れるということ。まだ見れてないですけど、IE11も大丈夫らしい。Edgeはダメだとかなんとか。

そこで有村は色々考えました。

1. かつてのpadding方式に戻す。
paddingを駆使して高さを設定するのはやはり面倒では?
高さを設定したいなら素直にheigetを使うべきじゃないか?
よって却下。

2. ボタンってもともと天地中央だから何もしなくてよくない?
わざわざflexを使った理由は、それがbuttonだけではなく、aタグなど他の要素でも使用されるため。
よって、buttonのデフォルトスタイルに頼ればいいや〜が使えない。
これも却下。

3. buttonがダメならinputは?
そもそも試していないけども、inputは空要素なのでbeforeやafterが使えなかったり、小回りが効かない時点で却下。

4. HTMLとCSSを書き換える

みたいな。要は間にspanをかませる。
デメリットとしては、本来ひとつで完結するはずなのに、buttonとspan(場合によってはaとspanなども)のようにHTML側の記述が増えてしまうということ…
けれども、現時点ではこれ以上の策は無さそうだし、「ボタンを配置する時はspanもセットで」というルールがあればいい話なのかなと思ったので、この案を採用しました。

form系はどうも痒いところに手が届かない感がありますね…
いつか「そんな日もあったね〜www」という時代が来ればいいのですが。
ひとまず締めとしては、Appleさん早くなんとかして!!!!

それでは、きょうはこのへんで。

迷いながらボタンを作っている。

こんばんは、有村です。
お花見、歓迎会、懇親会……コミュ障には辛い季節がやってきましたね!

さて今日のテーマは、迷いながらボタンを作っているです。
もちろんボタンってウェブサイトのボタンですよ。有村はフロントエンドエンジニアですよ。

で、ボタンなんですけど…何に迷っているかというと、ボタンをどう設計すればいいの?ということ。

私がまずやったこととしては、

  • それぞれのボタンの共通部位を見つける
  • ボタンのデザインと役割の紐付けをする

でした。
たとえば、「先に進む」や「戻る」的なボタンがあったとして…

  • 共通部位 … 角っこが丸い。font-weightがbold。テキストは天地中央。
  • 先に進む系は背景とボーダーが赤、テキストが白。戻る系は背景が白、ボーダーとテキストが灰色。

みたいな感じ。

そこでボタンを設計しようと思ったところ、先輩に強調されたのが、ボタン自身に具体的な幅を持たせるなということ。
私はなんでだろうと思ったのですが、よく分からないなりにアドバイスに従い、こんな感じのextendとmixinとclassを作りました。

なんかいい感じじゃないですか!?
と思っていた時期が私にもありました。

Aページ「ここのbtn_nextは幅100px、高さ20px、font-sizeは13pxやで〜」
Bページ「ここのbtn_backは幅100%、高さ40px、font-sizeは15pxやで〜」
Cページ「ここはbtn_nextとbtn_backは横並びでどっちも幅を均等に、2つの間にはmarginを15px、高さは30px、font-sizeは15pxにするで〜」

ありますね!あると思います!!!!
つまり何が起きたかと言うと、
ページ(というか配置場所)によって、幅や高さやfont-sizeが違う。
うわぁどうしよう!!!!

んん…まぁできないこともない…でもなんだろう、このオーバーライドっぷりは。
最初のうちはこれでもなんとかなったんですけど、たとえば「入力フォーム系に配置するボタンは常にサイズが一定」とか、別のルールとバッティングした時に、収集がつかなくなったんですよね…。

そこで、一度立ち止まって考え直すことにしました。

絶対に変わらないもの = extend
角っこが丸い。font-weightがbold。テキストは天地中央。

それぞれのボタンとして独自のもの = mixin
ボーダー色、背景色、テキスト色

場所によって変わるもの = ボタン自身は具体的な数値を持たない
幅、高さ、font-size

これをソースに起こしてみると…

からの、

からの、

のように、ボタンの大きさがどのようにあるべきかを別のclassに委ねると、変なバッティングも起きなくなる…!
更に、form_btnはサイズ指定しか持っていないので、btn_backやbtn_next以外のボタンが来ても対応できる…!

また、親にサイズ感を委ねるという意味ではカスケードでもいけると思います。

まだ悩みに悩んでいるのですが、今のところたどり着いたのはこんな感じです。
何が正解かは分からないけど…

「あーこれやっぱり違う!」ってなったら、また記事にしようと思います。

それでは、今日はこのへんで。

固定・可変・固定レイアウト?

こんばんは、有村です。
花粉症の人、大変そうですね。私はなったことないので分かりませんが…

で、今日のテーマは「固定・可変・固定レイアウト?」です。

固定幅
←可変幅→
固定幅

みたいなことをやりたかったのです。
こいつらの親はwindowサイズで幅が変わり、かつflexボックス。そして要素が「固定・可変・固定」で並んでるレイアウトです。

で、私は最初、CSSをこう書きました。

やりたいことは宣言した!って感じですね。後はflexちゃんがいい感じに横並びにしてくれるやろ〜って思っていたのですが。。

起こった問題:kotei2の幅が維持されていない。

なぜか、きっちりwidth指定しているはずのkotei2が、デベロッパーツールで見ると70pxだったり80pxだったり可変になってしまっていたんです。
お前が可変になるのかよ!!!!
これは困った…

でまぁ早速解決策。

これつけないといけなかった。

でも一体何がいけなかったんだろう?と有村調べました。

まずflexについて。こいつは「余白を埋めるときどうする?」を指定するプロパティ。
flex-growとflex-shrinkとflex-basisのショートハンド。
上の例のように単位なしでひとつだけ値を記述した場合は、flex-growを指定したことになる。

じゃあ次、flex-growって何?という話。
こいつは、要素がflexボックス内での余白をどれくらい占有するかを示すもの。
たとえば、

と指定すると、aとbとで1:2の割合で領域が振られる。

じゃあどういうことだってばよというと、最初の実装例の場合だと、kahenちゃんは「余白をどう扱うか」という指定を何も持っていなかった。
flexボックスちゃんから見れば、幅をどうすべきか分からない要素が中にいるわけで、「あ…じゃあなんかお前には適当に領域取らせるわ…」みたいな処理になったのでしょうか。
それに幅固定の要素も巻き込まれてしまってうまく領域の配分ができなかった。
…という感じかなと思います。

可変だから何も指定しなくていい、という認識は甘かったのですね!
原因分からなくてかなり詰まってしまいました!

それでは、きょうはこのへんで。

MindBEMdingを学んでみた

微妙にご無沙汰しております。有村です。
春を感じるようになりましたね〜、冬が一番好きな私はちょっと寂しいです。

さて今日のテーマはMindBEMdingを学んでみたです。
最近CSS設計を考えるようになったのですが、ひとつひとつの思想をちゃんと理解していないが故、「ARIMURACCS」なる新しいルール(という名の無法地帯)を生み出すようになってしまって…
そこで、やっぱり基本はちゃんと押さえないとねということで、まずはMindBEMdingから学んでいくことにしました。

Q: MindBEMdingって何?
A: CSSの命名規則のこと。
具体的に説明。まず要素を
・ブロック … ひとつのかたまり。箱。
・エレメント … 箱(ブロック)の中に入っている要素。パーツ。ブロック無しでは存在できない。
・モディファイア … ブロックやエレメントを装飾するもの。
の3つで考える。

記法がちゃんと決まっている。
blockとelementを繋ぐときは、アンダースコアを2つ。
modifierを使うときは、ハイフンを2つ。
単語と単語を繋ぐときはハイフンで。

こんなかんじ。
案件やチームによって、アンスコを1つにしたり、単語の繋ぎをキャメルケースにしたり、アレンジを加えるケースもあるらしい。

Q: モディファイアって具体的にいつ使うの?
A: パターンをつけたいときに使う。
例、こんな感じ。

基本形とそのパターンの組み合わせ。
横並びリスト(基本形 + 何個並びなのかのパターン)やボタン(基本形 + 色やサイズのパターン)などでよく使いそう。

Q: ブロックから見て孫要素ができたときは、block__element__elementになったりするの?
A: BEMはHTMLの構造をエレメントによって表す必要はない。
つまりはこういうこと。

photoはブロックから見たら孫要素、さらに言えばphoto-boxの子要素だけれども、ネストの関係性を __element__element などで示す必要はない。

もっとあるけど、基本はこんな感じです。
どうでしょう?MindBEMding。特に複雑なルールでもないので、チーム内で「なんか命名ルール決めないとな〜」となったとき、導入しやすい印象を受けました。

それでは、今日はこのへんで!

mixinで事故った話

こんばんは、有村です。
月曜はみんなのテンションが低めですね。どこもそうなのかな。

で、今日はmixinで事故った件について書きます。
成功したコードなんて書いたことない気がしますが、今回は特に盛大に滑ったので、みんなに笑ってもらおうと思います!

まずは、実際のコードから少し略してはいますが、事故ったコード。
やりたかったことは、
・普通のボタン
・矢印付きのボタン
・アイコン付きのボタン
・アイコンと矢印付きのボタン
の4つがデザインとして頻繁に出てくるので、そのmixinを作ろうとしてたんです。

なんていうか…「引数、引き回しの刑」って感じですね。書いてて自分で訳が分からなくなっちゃったんです。
mixinをネストして、呼び出すときに引数を指定して、またその親に渡すために引数を受け渡して…ってやっていますが、もはや何が何だかです。

そこで、CSS設計が得意な先輩にお願いして、このコードをぼっこぼこにしてもらいました。
そこでいくつか問題が見えてきました。

もっとシンプルに考える
上のソースでは、アイコン付きのボタンや矢印付きのボタンで、毎回btnをincludeしています。が、本当にはそれは必要なincludeでしょうか?
ざっくり分けると、これらは「ボタン」と「ボタン装飾(矢印とアイコン)」の2つに分かれるはずです。ボタン装飾は装飾に必要なプロパティのみが書かれていれば良くて、「ボタン」そのもののプロパティは持っている必要がありません。
そして、実際にボタンのclassを作るときに、必要なパーツ(mixin)を必要に応じて呼び出して組み合わせればいいのです。includeはひとつじゃなきゃいけない、なんて決まりはないですもんね。
全部まとめなきゃいけない、なんてことはなかったんや!!

引数の名前が分かりにくい
$fo_sizeとか、勘がいい人なら「あぁ…フォントサイズね…」って気付いてくれるかも知れませんが、そうと明記してない以上、それはあくまで推測でしかありません。アノテーションもないし。
$font_sizeとか、分かりやすい名前を付けましょう!

引数が多い割に限定的
例えばborder。色は設定できるようになっていますが、もし2pxのborderが出てきたら…solidではなくdottedが出てきたら…またmixinを更新しなければなりません。
引数は文字列も入れられるので、もちろん「1px solid #000」という値そのものを引数として受け渡すこともできるのです!
なんか勝手に、ショートハンドの値はダメ!と思い込んでたんですよね。失敗。

SASSではmixinとかincludeとか略せるよ
mixinは「=」、includeは「+」で置き換え可能。

アイコンボタンのアイコンってどこで設定してるの?
はい!ボタン内にhtml側で直に指定してました!
具体的には、

みたいな感じで、メールのアイコンフォントを呼び出していたのですが。
これだと「メールアイコンの装飾が付いたボタン」を複数呼び出そうとしたとき、html側にも都度メールアイコン用の記述を書かないといけないのですよね。なんのためにモジュール化するんだろう…ってなります。
それであれば、「メールアイコン装飾のボタン」というclassを作って、それにcontentとしてアイコンフォントを設定する方が汎用性は高いです。
mixin側は、contentを引数として設定できるようにしておく。
CSSとhtmlの住み分けもできていい感じです!

それで最終的にこうなりました。

呼び出すときはこう!

超すっきりしました!!!!
それぞれの役割を明確に、余計なことはしない!という実装って、なんだかJSの設計と同じですね。
CSSとJS、世界は離れているようで実は繋がっています。きっと他の言語もそうなのでしょう…オブジェクト指向の勉強、ちゃんとしよう。

それでは、長くなったので今日はこのへんで!

mixinとextendの違いって?

こんにちは、有村です。
SASSを業務でも使うようになりましたが、使いこなすのは難しいですね!
というわけで、早速今日のテーマ。mixinとextendの違いって?です。

最終的な目的はどちらも同じだと思います。それは、「同じ記述を何度も書きたくない」ということです。以前の原田さんの記事にもありましたが、これもDRYの法則なのでしょうか?
で、その手段として用いられるのがmixinとextendです。両者の違いについて学んだことを残します。

書き方

mixinで目を引くのは、やはり引数ではないでしょうか。基本形は同じだけれど、たとえば文字色だったり背景色だったりが変動する場合、呼び出す側(今回は .fuga)が引数でその値をコントロールすることができます。
実例を挙げると、色違い&サイズ違いのボタンを作る際に重宝しました。

extendはまさに継承で、.hoge の中身がそっくりそのまま .fuga に引き継がれます。以上。

あれ?じゃあこの2つってやっぱり同じじゃん?と私も思っていたのですが、実際にコンパイルされた後のソースがそれぞれ異なります。

はい、見ての通り、mixinは「includeした要素が .fuga のプロパティとして挿入されている」のに対し、extendは「extendした要素と .fuga が同じプロパティを持つclassとしてグルーピングされ、併せて .fuga 独自の記述のみが書かれた定義も生成される」のです。

それぞれ長所と短所があると考えています。
mixinは、引数でプロパティの値を変更できることから、拡張性に優れていると思います。
しかし、呼び出す度に全てのプロパティが呼び出し元のclassに挿入されるので、場合によってはコンパイル後のCSSの肥大化に繋がります。

content以外全部おなじじゃんね、っていう。
DRYが嫌でmixinを使ったのに、結局DRYになっている。

対してextendは、同じプロパティを共有するものとしてグルーピングをしてくれるので、mixinのように同じ内容が2度3度と繰り返されることはありません。
が、その分、継承元のプロパティを1つでも変更すると、それが全てのextendを用いた要素にも反映されてしまいます。
プロパティの変更ってmixinもそうやんけ!と思ったりもしましたが、mixinの場合は変更されることが前提となるプロパティの値を引数で持たせることができ、なおかつデフォルト値の設定もできるので、mixinの方が拡張性や保守性は優れています。

じゃあどっちを使えばいいのよー!となった私に、先輩はヒントをくれました。
・絶対恒久的に何があっても変わらないと断言できるまとまりを使いまわしたければ、extend。
・ベースは変わらないけど場合によって値を変えていきたかったり、将来的にプロパティや値が変わるかもしれなければ、mixin。

一回extend使って失敗してみるのもいいんじゃない?とのアドバイスも貰ったので、それもいい経験になるかもしれません!「あ〜〜〜」ってなったらまた書きます!

それでは、今日はこのへんで。

display:noneとvisiblity:hiddenの違い

どうも。原田です。

今回はフロント側についての記事を書こうと思います。

 

「この時はこれ表示して、そっちの時はそっちを表示させたい」

という、瞬間がありました。

そこで、先輩からjQueryでshow()とhide()にさせちゃいなよと言われ、

言われるがままにしてうまくいったのですが。

 

jQuery書いてる時の私の頭の中は、

「hide()しちゃってる時、その部分が真っ白になって場所だけとっちゃてて不自然に見えないのか・・・」

という不安がありました。

お気付きの通り、visiblity:hiddenの状態になっちゃはないかというバカなことを考えをしてました。

もちろん、hide()はdisplay:noneとなるメソッドです。

 

 

そこで、私の頭の中の整理

display:none  ←hide()の時
エレメントが表示エリアから消える。DOMとしては存在するが描画されない
→場所とらない

 

visiblity:hidden
エレメントは描画されない。しかし表示エリアは「残る」。背景色で塗りつぶした感じ
→場所とっちゃてるまま

 

 

 

巷で噂のSass

巷で噂のSass

公式サイトのアメリカ女子みたいなピンクが可愛いですよね。

Sass公式サイト
http://sass-lang.com/

オンラインエディターも可愛い
http://www.sassmeister.com/

実践的にSassを使ったことないのですが、時代はもう来てるようですね。
イメージ的には入れ子?ネスト?で書きやすいとかとか。

・Sassには記法が2つ
「SCSS記法」と「SASS記法」
聞いた事あるのはパンツを履く履かない・・・。

SCSS記法 (パンツ履かない

ul
margin: 0
li
margin: 5px

SASS記法 (パンツ履く

ul {
margin: 0;
li {
margin: 5px;
}
}

公式としてはSCSS記法みたいだし、主流なのかなー