20210607のCSSに関する記事は13件です。

HTML,CSSのよく使うものまとめ

HTMLとCSSでよく使うものまとめ(雑)            リンク             画像を表示        リスト(先頭に黒点)  , リスト            , 文字色            color:色; 文字の大きさ       font-size:大きさpx; 書体            font-family:種類; 背景色            background-color:色; 高さ            height:数字px; 幅            width:数字px; 特定の要素にCSSを適用 ○○ クラス名を与える            .selected { } DOCTYPE宣言       <!DOCTYPE html> 設定に関する情報       headの中の要素        (文字コードの設定)※文字化け防止            (ブラウザのタブに表示される)            (CSSの読み込み) リストの黒点削除       li{ list-style:none; } 文字を横並びにする       float: left; 余白            padding: 数字px;この場合全ての方向に余白 上方向に余白       padding-top: 数字px; 下            padding-bottom 左            padding-left 右            padding-right 余白まとめて書く       padding: ○px ○px ○px ○px 上→右→下→左            padding:○px ○px 上下 左右 特定のliにCSSを適用  .header-list li{ } 右から順に横並びにする  float: right 文中の一部だけCSS適用させる  文字            span{ } ボーダー(下線)       border-bottom:太さpx 線の種類 色 ボーダー(囲い)       border:太さpx 線の種類 色 ボーダーの内側全体の余白  padding:○px ; "paddingみたいにまとめられる ボーダーの外側全体の余白  margin:○px 一行のテキストボックス   終了タグ不要 複数行のテキストボックス  , 送信ボタン        ↑の送信ボタンを別の文字に変更       背景画像を設定       background-image:url(); コンテナを中央寄せ       width: ○パーセント コンテナを中央寄せ       margin :0 auto; 透明度            opacity:○○; (0.0〜1.0) 文字間隔            letter-spacing:○px; ボタン作成       タグで作成→display: inline-block;で要素を変える。(block(ブロック要素), inline-block(インラインブロック要素), inline(インライン要素)がある カーソル乗ったとき色変更  セレクタ:hover { background-color:red等 } 角を丸くする       border-radius: ○px 要素の配置変更       text-align:left; テキスト、ボタンとかのインライン、インラインブロック要素はmarginじゃなくてこっち使う フォント(head要素に入れる)        ※ タグにfaクラスとfa-アイコン名クラスを指定する 色を透明            rgba(○, ○, ○, ○) opacityプロパティは要素全体を透過 rgbaを使うとその色だけを透明にすることが出来る(最後の数値が透明度) 文字にアニメーション付ける   transition: all 0.5s; 行の高さ             line-height:○px; 文字の太さ        font-weight:normal; normalまたはbold 配置(%)         width:25%; (pxじゃなくて%表示にすると親要素に対しての%になる) 要素同士を重ねて表示(全体左上基準)    position: absolute; top: px; left:px; 活用するすると要素の移動にも使える 要素同士を重ねて表示(指定場所左上基準)  position: relative; ボックスに影を付ける    box-shadow:0px 7px #1a7940; 水平 垂直 色 クリック時に変化        セレクタ:active { } クリック時ボタンを凹ませる   ・box-shadowをnoneにする            ・position: relative;とtopによって影の分だけ位置を下げる ヘッダーを画面上部に固定   position:fixed; top:0px; 重なり順序        z-index:10; 背景画像ぴったり        background-size: cover; ボタン作成                     
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

それでも私がTailwind CSSではなく、CSS Modulesを推す理由

色々書き比べた結果Tailwind CSSにしたという話 こちらの記事がバズっていた(6/9現在 over 200likes)為、読ませて頂きました。 これまで主観的な印象と薄い議論で賛否が分かれていたTailwind CSSについてこれまでのcssの技術の変遷を踏まえて技術的にかなり踏み込まれた考察の上で選定の理由が書かれており、Tailwind CSSアンチ派の私にとっても非常に勉強になる記事でありました。リスペクト。 その上で、こちらの記事では私が『それでもCSS Modulesを推す理由』について書かせていただきたいと思います。 *2021 6/9追記 「Tailwind CSSこそCSSのあるべき姿でありフロントエンドの未来である」というフロントエンド界隈の感情が「急激に」高まりつつある現状に対しての一つの問題提起となれば幸いです。 Next.js,Gatsby などのフレームワークでBuild-inサポートされている CSS Modulesは上述のフレームワークなどを用いて開発をスタートした際、デフォルトでサポートされている為、追加のライブラリなどは不要です(とはいえsassなどはほとんどの場合追加すると思います)。 ちなみにNext.jsの開発元のVercelはstyled-jsxというCSS in JSライブラリーを管理しており、こちらもNext.jsではbuild-inでサポートされています。 とはいえ、Next.jsの公式サイトなどを見る限りあくまで公式の推しはCSS Modulesっぽいです。 CSS in JSと CSS Modulesの比較になりますが、CSS Modulesの方が、『ロードタイム・ランタイムともに、パフォーマンス面で有利』なようです。ソース ピュアなcssの知識さえあれば設定不要で書き始めることができるCSS Modulesですが、これ自体がTailwind CSSに対するCSS Modulesの一つのメリットとなります。 CSS Modulesを書くのに当たっては、Tailwind CSSのコンフィグ方法や、クラス名などを覚える必要がありません。また、Tailwind CSSそのものが今後進化していった場合などに、それらの変更に追従する保守コストもかかりません。 冒頭で紹介した記事では、webpack依存技術である点や、『ファイルが増えてめんどくさい』点についてCSS Modulesのデメリットとして述べられています。 しかし、webpack依存に関しては現代的なフロントエンド環境の95%以上がwebpackを使用している現状などから考えてそれほど憂慮することでもないのかなと思っています。 また、次世代のbuildツールとして話題になりつつあるViteなどでもCSS Modulesはサポートされているようです。 .BemTailwindBlock__Inner { @apply lg:flex w-full; } また、セマンティックなクラス名(上のコードではBEM命名方)とTailwind CSSを併用する例として、@applyを使用した例を載せていただいておりますが、@applyはTailwind CSSを使用しているときのみ機能します。ビルドプロセスからTailwind CSSを削除すると、そのCSSは機能せず、レイアウトは壊れてしまいます。つまり、@applyメソッドなどでセマンティックな命名をユーティリティクラスと使い分けたとしても、cssはtailwind依存になってしまうので、仮に将来cssフレームワークの交換などが発生してしまった場合、多大な作業コストがかかると思われます。 『ファイルが増えてめんどくさい』点に関してですが、これは『めんどくさい』です。CSS Modulesは一々CSSファイルをつくらないといけないという『めんどくささ』から逃れることは出来ません。 『状態管理とレンダリングロジック』と『スタイル』 の責務をそれぞれのファイルに分割するというアーキテクチャは、『ファイル分割のめんどくささ』とトレードオフになります。 しかし、個人的にですがjsxファイルは出来るだけ、『state,propsのデータの流れとレンダリングロジック』に集中できる見通しのいい状態が好ましいと考えています。 <button type="button" className=" relative py-2 w-1/2 sm:w-auto sm:px-8 text-gray-900 bg-white text-sm font-medium whitespace-nowrap border-gray-200 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:z-10 " > このようなTailwindのクラス名で数行視界が奪われてしまうのは、私は絶対に避けたいと思っています。 Tailwindはコードのクリーンさと引き換えに、初速と最低限のデザインシステムを保障しますが、それは保守性の悪化というコストを将来に残すリスクを孕んでいることは選定の際に、考慮しなければならないと思います。 CSSファイルを増やさなければならないめんどくささと、jsxがtailwindのclass名に圧せられるツラミを天秤にかけると私はCSSファイルへの分割を選びます。 また、Tailwind CSSでユーティリティクラスをバンバン生やして快速にコーディングを進めていても、background-imageの画像パスを指定したり、::beforeや::afterなどの擬似要素を使用したくなったり、あるいはちょっとしたマイクロインタラクション的アニメーションの実装など、ピンポイントでcssを書きたくなる場面は出てくるのではないでしょうか?そのときは諦めてglobalにcssを書きますか?必要になったときだけCSSファイルをつくるというのも行き当たりばったり的でアーキテクチャとしては弱い感じがします。 モーダルなど、classの付け替えで見た目が大きく変更するuiなどcssの記述量が多くなるコンポーネントについてもTailwind CSSのユーティリティクラスだけでの対処はしんどくなりそうなので、例外的な処理をしたくなるのではないでしょうか。Tailwindを使っていると、『Tailwindだけではしんどい場面』の回避方が必要になり、その度にハック的な処理が増えていくのではないでしょうか。 css modulesだとそういう場面的な対処は必要なく、一気通貫したアプローチが可能です。 Tailwindで出来ることはCSSで出来る(当たり前 Tailwind CSS好きな人が挙げるメリットとして、あらかじめ汎用クラスでサイズなどが設定されているので、クラスをどんどん当て込んでいったらある程度、統一性のあるデザインにまとまるというのがあるのではないでしょうか? Tailwind CSSのfont-sizeに関係するクラスの中身は例えば、このようなものになります。 .text-xs { font-size: .75rem; } .text-sm { font-size: .875rem; } .text-base { font-size: 1rem; } これは、SCSSなどで変数として定義して、要素に入れると次のように書けます $text-xs = .75em; $text-sm = .875em; .object-text{ font-size:$text-xs; } あるいは、Tailwind CSSのフォントサイズ周りのユーティリティクラスが便利ならそれだけコピーしてユーティリティクラスとしてそのまま使うのもアリです。ブレイクポイント、色、マージンなども同様です。変数・mixinだけのimport専用の共通cssファイルをうまく設計すれば、デザインシステムはTailwindを使わなくてもつくれます。 まぁ当たり前っちゃ当たり前なんですが、Tailwind CSSで出来ることはCSSで出来ます。(Ruby on Railsで出来ることはRubyで出来るくらい意味のない文章かもしれません) Tailwind CSSが流行した背景を考える しかし、これだけTailwind CSSが盛り上がってるのには何かそれ以前のReactなどのコンポーネントによるUI設計とCSSの設計によくある落とし穴というか問題があったのではと考えます。 私が推測するのは、『CSSクラスによるスタイルの過度の共通化』です。 あるいは、『CSSコンポーネントとReactコンポーネントの衝突』と言ってもいいかもしれない。 つまり、例えばCSSで .sample-button{ display: block; width: 100px; background: red; } というcssのクラスで見た目を定義し、そのクラスをそのまま複数のReactコンポーネントに適用すると問題は生じます。 スタイルは共通でも、機能の違うReactコンポーネントに同じCSSクラスを使い回してスタイルを当ててしまうと、後々、変更が入ったときに、CSSの影響範囲がわからなくなって、設計が破綻します。 そのような事態を招くくらいならば、もちろん、Tailwindのような汎用ユーティリティティクラスを全てのコンポーネントに個別で指定していった方がマシです。 このような問題を引き起こさないためにCSS ModulesでのCSS運用にはルールを設けた方がいいでしょう。 『Reactコンポーネント1つあたり、1つの紐づくCSSファイルを必ずつくり、別のコンポーネントのCSSファイルは絶対に使用しない。共通スタイルはmixinで定義し、それをインポートして使う。』などを提案させていただきます。 Tailwind CSSはスタート速度と、最低品質を保証した? 確かにTailwind CSSを使うとCSS設計そのものが不要なので『設計の破綻によるカオス』は防げますし、デザインシステムの設定なしにある程度の見た目を保証してくれるといったメリットはあるのかなと思います。それによってヨーイドンでUIをつくっていく効率は確かに高まるのかもしれない…。 しかし、Tailwind はやはり『理想』ではない‥ TailwindCSSの上述のメリットは、『コードが汚くなる・スタイリングが完全にTailwind依存になる』という『将来的な保守性の悪化リスク』とトレードオフになっています。 結局、Tailwindは、ありがちなCSSにまつわる問題を解決し、最低品質は保障してくれるかもしれない一方で、必ずしも『理想のフロントエンド』への道筋にあるものではないのかなと思っています。 しかし、『CSSを絶対に書きたくない』『CSSを書かないで済む世界線が理想』と考えている開発者にはTailwindこそ理想の方向を向いているのかもしれません。 Webのスタイリングは異なったサイズのディスプレイの対応などもあって、ボリュームが大きくなることが多いです。私は、スタイリング要素を完全にUI構造と紐づけて記述していく未来よりは、やはりCSSは分離して書く方が筋かなぁと思っているのですが、確信はありません。Tailwindがこれからより普及してスタンダードになっていく可能性もあると思っています。JS強い方々でTailwindを推している人が多いのは事実です。しかし、私はどうしてもTailwindをスッキリ飲み込めません。この記事が一つの意見として、ある種の『ブレーキ』として働いてくれると幸いです。 参考 Tailwind CSSが私には合わなかった理由
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React+Material UIで、スタイルをJS in CSSで書く方法まとめ

株式会社ユニフェイスの大竹です。 製造実行システムIB-MesのWebアプリ版・IB-Mes SaaSのフロントエンドを担当しています。 IB-Mes SaaSではReact,TypescriptとMaterial UIを使っているのですが、毎回JS in CSSの書き方に詰まってしまうので、まとめました 以下の内容を読んで、 わかること:JS in CSSを利用したCSSの書き方 わからないこと:上記以外の時のCSSの書き方 記事を書いているときの各種ツールのバージョンは、Material UI v4、React 17.0.2ですReact 16.8で追加されたフック(Hook)を利用しています グローバルにCSSを当てる グローバルにCSSを当てるときは、'@global'を使います以下の例では、MuiPickersSlideTransition-transitionContainerというクラスに、グローバルにCSSを適用しています 参考:https://stackoverflow.com/questions/58755118/global-styles-with-react-and-material-ui const useStyles = makeStyles((theme) => ({ "@global": { ".MuiPickersSlideTransition-transitionContainer.MuiPickersCalendarHeader-transitionContainer": { order: -1, }, ".MuiTypography-root.MuiTypography-body1.MuiTypography-alignCenter": { fontWeight: "bold", }, }, })) 子要素を指定してスタイルを当てる ol(番号付き箇条書き)の先頭を(1)のようなカッコつきの表記にするCSSで説明しますolの子要素のliを指定する時は、ol:{}の中に"& li":{}を入れます疑似要素を指定する時は、"&::before"のように書きますカッコつきの表記にするポイントは、contentに`"(" counter(cnt) ") "`を指定することです 参考:https://www.websuccess.jp/blog/archives/2711/の技 調整する①の内容をJS in CSSに書き換えました const useStyles = makeStyles((theme: Theme) => createStyles({ ol: { paddingLeft: 0, marginLeft: theme.spacing(4), "& li": { listStyleType: "none", counterIncrement: "cnt", display: "block", position: "relative", "&::before": { content: `"(" counter(cnt) ") "`, marginLeft: -theme.spacing(4), width: theme.spacing(5), position: "absolute", top: 0, left: 0, }, }, }, }) ) スタイルを当てる部分では以下のように指定します const classes = useStyles() <ol className={classes.ol}> <li>hoge</li> <li>bra</li> </ol> 直下の階層の子要素を指定する 直下の階層の子要素を指定する時は、子セレクタ > を利用することができます const classes = makeStyles((theme: Theme) => createStyles({ editButton: { flexGrow: 1, textAlign: "center", "& > *": { margin: theme.spacing(1), }, }, }) ) 疑似クラスの指定 疑似クラスの指定は、:(セミコロン1個)を利用します例えばホバー時の処理を書く場合は、"&:hover"となります以下のように指定すると、マウスカーソルを載せた時だけ背景の色が変わります。 const useStyles = makeStyles((theme: Theme) => createStyles({ icon: { "&:hover": { background: theme.palette.action.active, }, }, }) ) もし間違いなどありましたら、ご指導ご鞭撻のほどよろしくお願いしますReactとMaterial UIなどについて勉強中なので、お手柔らかにお願いします
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者でもわかる】borderは直線を引くだけじゃない!borderを使って出来ること6選+おまけ2つ

どうも7noteです。borderを使って直線を引く以外のできることをまとめました div { border: solid 1px #000; } これ以外使ったことない・・・なんてことありませんか? 知ってるようで知らないかもしれない、borderでできることをいろいろまとめました。 「直線以外も引ける」 わりと基本的な事ですが一応。 borderのスタイルをsolid以外に指定すると、点線や波線も引くことができます。 style.css div { border: dotted 1px #000; /* 点線を引く */ border: dashed 1px #000; /* 破線を引く */ border: double 1px #000; /* 二重線を引く */ } 「曲線も引ける」※波線はちょっと難しい 当たり前の人には当たり前かもしれませんが、border-radiusと組み合わせることで曲線を作れます style.css div { border-top: solid 1px #000; /* 線を引く(※borderを4方向に指定すれば円になる) */ border-radius: 50%; /* 曲線にする */ } 「立体感のある線を引く」 擬似要素を使ったり、影と組み合わせて立体感のある線を引くことができます。 ※見本画像は背景に(background: #666;)を入れています。 「影を使った例」 style.css div { border-bottom: solid 1px #333; box-shadow: 0 1px 0 #ccc; } 「疑似要素を使った例」 style.css div { position: relative; } div::after { content: ''; width: 100%; border-bottom: solid 1px #333; box-shadow: 0 1px 0 #ccc; position: absolute; left: 0; bottom: 0; } 「三角形を作る」 三角形も簡単に作れます。この三角形を使って吹き出しを作ったりなんかもよくある手法ですね。 三角形ジェネレーターがあるので、そのようなWEBツールを使うのがオススメ! style.css div { width: 0; height: 0; border-style: solid; border-width: 0 10px 10px 10px; border-color: transparent transparent #007bff transparent; } 「三角形以外にも台形とかも作れます」 style.css div { width: 20px; /* ここの値で調整可能 */ height: 20px; /* ここの値で調整可能 */ border-style: solid; border-width: 0 10px 10px 10px; border-color: transparent transparent #007bff transparent; } 「矢印を作る」 borderの上と右を作成して、45度回転させればよくボタンについてる矢印も作れます。 style.css div { width: 20px; height: 20px; border-top: 1px solid #000; border-right: 1px solid #000; transform: rotate(45deg); } 「おまけ」 できそうでできない、グラデーションのborderを作る これはborderを使っては再現ができません。 backgroundを使うことで表現できます。 style.css .div{ width: 100%; height: auto; padding: 0; text-align: center; border-left: 2px solid #43C6AC; border-right: 2px solid #d9e653; } div::before, div::after{ content: ""; display: block; height: 2px; background: linear-gradient(to right, #43C6AC 0%, #d9e653 100%); } 要素の占有範囲を確認する どの要素がどこに表示されているのかわからなくなったり、表示場所なんかが思ってた通りにならない時に、とりあえずborderやbackgroundなどを指定して、状況を確認するのに使います。 私自身も始めたての頃は、よくわからなくなったらとりあえずborderを付けて要素の現在置を確認するようにしていました。 ※borderの分だけ要素の横幅が長くなるのでピタピタのデザインだとborderが原因で崩れることなどもあるので注意! 参考: http://sdora.sub.jp/blog/?p=511 http://apps.eky.hk/css-triangle-generator/ja https://www.infocrest.co.jp/blog/category/tips/442/ おそまつ! ~ Qiitaで毎日投稿中!! ~ 【初心者向け】WEB制作のちょいテク詰め合わせ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【jQuery】タブの作成方法

完成形 SCSSを使用 jQueryを使用 See the Pen RwpJKyX by c-koch0514 (@c-koch0514) on CodePen. HTML html <!----------------------- タブ -------------------------> <div id="tab" class="group"> <ul class="tab-group"> <li class="tab is-active">Tab-A</li> <li class="tab">Tab-B</li> <li class="tab">Tab-C</li> </ul> <!--タブを切り替えて表示するコンテンツ--> <div class="panel-group"> <div class="panel is-show"> Content-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-A </div> <div class="panel"> Content-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-B </div> <div class="panel"> Content-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-C </div> </div> </div> <!----------------------- end of タブ -------------------------> SCSS scss /***********************************************************************/ /********** タブの設定 *************/ /***********************************************************************/ .group { .tab-group, .panel-group { display: flex; width: 350px; margin: 0 auto; .tab { width: calc(350px / 3); background-color: pink; text-align: center; border: 1px solid #000; cursor: pointer; } .is-active { background-color: red; } .panel { width: 100%; background-color: yellow; border: 1px solid #000; padding: 10px 20px; display: none; } .is-show { display: block; } } } /********************* ena of タブ **********************************/ /***********************************************************************/ jQuery jQuery $(function(){ /***************** タブ **********************/ $('.tab').click(function(){ // クリックした要素の先祖要素の中で、classの値がgroupの要素を取得 const group = $(this).parents('.group'); group.find('.is-active').removeClass('is-active'); $(this).addClass('is-active'); group.find('.is-show').removeClass('is-show'); // クリックしたタブからインデックス番号を取得 var index = $(this).index(); // クリックしたタブと同じインデックス番号をもつコンテンツを表示 group.find(".panel").eq(index).addClass('is-show'); }); /*********************************************************/ }); 同じHTMLに複数タブが存在するとき HTMLで#tab以外のidを持ち、.groupをもったタブを作ればいい html <!--------------------------1つ目のタブ---------------------------------> <div id="tab" class="group"> <ul class="tab-group"> <li class="tab is-active">Tab-A</li> <li class="tab">Tab-B</li> <li class="tab">Tab-C</li> </ul> <!--タブを切り替えて表示するコンテンツ--> <div class="panel-group"> <div class="panel is-show"> Content-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-A </div> <div class="panel"> Content-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-B </div> <div class="panel"> Content-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-C </div> </div> </div> <!--------------------------2つ目のタブ---------------------------------> <div class="group"> <ul class="tab-group"> <li class="tab is-active">Tab-A</li> <li class="tab">Tab-B</li> <li class="tab">Tab-C</li> </ul> <!--タブを切り替えて表示するコンテンツ--> <div class="panel-group"> <div class="panel is-show"> Content-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-AContent-A </div> <div class="panel"> Content-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-BContent-B </div> <div class="panel"> Content-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-CContent-C </div> </div> </div>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【jQuery】モーダルの作成方法

完成形 SCSSを使用 jQueryを使用 See the Pen MWpXJmm by c-koch0514 (@c-koch0514) on CodePen. HTML html <!------------------- modal -------------------------> <button id="modal-btn">modelを開く</button> <div class="modal"> <div class="modal-bg modal-close"></div> <div class="modal-content"> <h1>モーダルタイトル</h1> <p>モーダルテキストモーダルテキストモーダルテキストモーダルテキストモーダルテキストモーダルテキストモーダルテキストモーダルテキストモーダルテキストモーダルテキストモーダルテキスト</p> <button class="modal-close">閉じる</button> </div> </div> <!------------------- end of modal ------------------> SCSS scss /***********************************************************************/ /********** modalの設定 *************/ /***********************************************************************/ #modal-btn { background-color: #000000; border-radius: 10px; font-size:15px; color: #fff; width: 130px; height: 50px; } .modal { display: none; height: 100%; position: fixed; top: 0; width: 100%; top: 0; left: 0; z-index: 1; .modal-bg { background: rgba(0, 0, 0, 0.6); height: 100vh; width: 100%; } .modal-content{ width: 300px; height: 200px; background: #fff; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); border-radius: 5px; padding: 10px 30px; .modal-close{ position: absolute; top: 0; right: 0; } } } /********************* ena of modal **********************************/ /***********************************************************************/ jQuery jQuery $(function(){ /***************** modal モーダル **********************/ // ウィンドウを開く $('#modal-btn').on('click', function() { $('.modal').fadeIn( 300 ); return false; }); // ウィンドウを閉じる $( '.modal-close' ).on( 'click', function() { $( '.modal' ).fadeOut( 300 ); return false; }); /*********************************************************/ });
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【jQuery】FAQアコーディオンの作成方法

完成形 SCSSを使用 jQueryを使用 See the Pen abJKBrL by c-koch0514 (@c-koch0514) on CodePen. HTML html <section id="faq"> <dl id="faq-item"> <dt class="question"> <p class="question-text">質問1</p> <p class="plus">+</p> </dt> <dd class="answer">回答1</dd> <dt class="question"> <p class="question-text">質問2</p> <p class="plus">+</p> </dt> <dd class="answer">回答2</dd> <dt class="question"> <p class="question-text">質問3</p> <p class="plus">+</p> </dt> <dd class="answer">回答3</dd> </dl> </section> SCSS scss /***********************************************************************/ /********** FAQの全体 *************/ /***********************************************************************/ #faq { #faq-item { width: 250px; margin: 0 auto; background-color: #eee; font-size: 15px; cursor: pointer; .question { display: flex; justify-content: space-between; } .answer { display: none; } } } /*********************** ena of faq ********************************/ jQuery jQuery $(function(){ /***************** FQAアコーディオン **********************/ $('.question').on('click', function () { $(this).next().slideToggle(); if( $(this).hasClass('close')){ $(this).find('.plus').text("+"); } else{ $(this).find('.plus').text("-"); } $(this).toggleClass('close'); }); /*********************************************************/ });
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

基礎中の基礎:HTMLとCSSでwebデザインする際にはここだけを押さえて!!

完全に個人的にマークアップを学習するにあたって、ここさえ押さえておけば、という部分を書き出しました!! 本内容はHTMLとCSSの概念は理解したけど、実際に書いているときのポイントが掴めない方にオススメです。 また先にお伝えしておくと完全に自己満ですので、予めご了承ください? それじゃぁ、早速いきましょう!!! ITリテラシー ローカルとクラウド ファイルは上から下に順に読み込まれる(下にあるものほど優先順位が上) パスを理解すること 順に説明していきます?? ローカルとクラウド みなさんが知っているようで知らない。 ここを理解してないと 「なんで、サイトが公開できないんだーー?????」 ってなったり、 「公開は出来たけど、画像が表示されてない。ローカルでは出来たのに、、」 と嘆きます。 それはローカルとクラウドを理解してないからに他なりません。 簡単に一言で言うと、ローカルはPC本体、クラウドはインターネットだと思ってください。 そして、この二つは常に繋がっているとは限りません。 二回言います。ローカルとクラウドは常に繋がっているわけではない。 想像してみてください。 「Wi-Fiが飛んでいないからページが見れない。」とよく口にすることがありますよね? でも、PCやスマホ本体は開けますよね?? 今、当たり前のことじゃんと思ってませんか? でも、実際にwebサイトを作り、公開するとなると忘れています。 だから、特にサイトを公開する際には、クラウド上で完結するように情報をまとめ、クラウドに情報を保管しておくことが大切なんです。 また、ローカルで情報を編集したら、クラウドで情報は勝手に更新してくれない。再度更新するためにクラウドに送る必要があることを理解しておきましょう? <まとめ> ①ローカルはPCやスマホ本体を指す。 ②クラウドはインターネットを指す。 ③ローカルとクラウドは常に繋がってる訳ではない。 サイトを公開する場合: ①クラウド上で完結するように情報をまとめ、クラウドに情報を保管しておくこと。 ②ローカルで情報を編集したら、クラウドで情報は勝手に更新してくれない。 ファイルは上から下に順に読み込まれる(下にあるものほど優先順位が上) これも当たり前と思う方もいるかもしれません。 しかし、プログラミングやマークアップを学び始めの時は意外と忘れがちです。 基本的、HTMLもCSSといったマークアップ言語も他の言語も基本的に書かれたコードの一番上から読み取られます。 何か指定がされない限りは上から下に読み込まれることを理解しておきましょう! 上から順に読み込まれていることを忘れている方のケースをお伝えします。主にHTML・CSSを例にしています。 * CSSの書いている箇所がバラバラでしっかりと自分で把握できるように整理していない。 * html・CSSをコーディングする際に、無理やりCSSで調整しようとしがち。 以上となります。 これを機にぜひ、 今一度ファイルは上から下に読み込まれてること。 下にあるコードほど優先順位が上であること。 を理解しておきましょう!! パスを理解すること そもそも、パスってなんですか??って話なんですが、若干語弊がありますが、簡単に言い換えるとURLです。 URLを覗いてみると、「/」で区切られている時があるのが分かると思います。 例えば、次のURLがあるとします。 htps://xxxxx.com/teams/sssss/overview URLを言語化すると、htps://xxxxx.com の中のteams の中の sssss の中の overviewというページを開いているということになります。 つまり、どのページや画像を示しているのかを表示するために「/」でフォルダやファイルを区切っています。 そして、これには絶対パスと相対パスがあります。 絶対パス: 直接、指定したい場所を示します。 相対パス: 相対パスは絶対パスとは異なり、ある基準を決めて指定を行ないます。 書き方も含めて例をご覧ください。 例) topフォルダ -secondフォルダA -ファイルA−1 -ファイルA-2     -secondフォルダB -ファイルB 例えば上記のような構造があったとします。 ファイルAー1から、ファイルAー2を呼び出す際は、「./ファイルA-2」と呼び出します。 ファイルAー1から、ファイルBを呼び出す際は「../secondフォルダB/ファイルB」と呼び出します。 つまり、ファイルを呼び出す際はどこを基準にしているかがポイントです。 ファイルAー2を呼び出す際は、共通のフォルダであるsecondフォルダAを基準とし、 ファイルBを呼び出す際には共通のフォルダのtopフォルダを基準にしています。またフォルダを一つ挟んで、違うフォルダを指定する際には「../」と書き始めます。 ※フォルダを二つ挟む場合は「../../」で書き始めます。 HTML 要素の始まりは左上から ブロック要素とインライン要素、インラインブロック要素がある 親子関係を把握すること 要素の始まりは左上から 「ブラウザに表示させる際、要素の始まりは左上からが基準である」は、初学者が意外と理解していない部分ですね? 理解していないとどのようなことを起こるのかお伝えすると、CSSで無理やり調整します。 更には、 CSSで無理やり調整する ーーーー?ーーーー コードの量が増える ーーーー?ーーーー 自分の書いている部分が分からなくなる ーーーー?ーーーー ちょっとブラウザのサイズを変えただけで、サイトが崩れる ーーーー?ーーーー 手がつけられなくなる というような悪循環が発生しかねません? CSSで無理に調整しようとせずに、要素が左上から始まると理解していれば、無理に左上に調整するプロパティなど要りません。 ブロックレベル要素とインライン要素、インラインブロック要素がある これまた、学んでいくうちに忘れがちな知識かなと思っています。軽視しがちとも言いますか、、、。 ともかく、CSSで装飾していくにあたって、ブロックレベル(ブロック要素とも呼ぶ)要素とインライン要素、インラインブロック要素を把握しておけばコードがもっと短くなります。それぞれ把握しておきましょう! | 要素名 | 幅と高さの指定 | 幅の初期値 |高さの初期値|要素同士の並び方|主なHTMLタグ| |:-----------|------------:|:------------:|:------------:|:------------:|:------------:| | ブロック要素 |可能  | 親要素に依存する |内容に依存|縦に並ぶ|div、p、h1~h6、ul、など| | インライン要素 |不可能 | 内容で決まる |内容に依存|横に並ぶ|a、li、input、textarea、spanなど| | インラインブロック要素 |可能  | 内容で決まる |内容に依存|横に並ぶ|--- displayプロパティでinline-blockと指定することがほとんど| 全てのHTMLタグを把握しておく必要はありません。私の場合は、参考サイトで確認することがほとんどです。 しかし、ブロックレベル要素とインライン要素、インラインブロック要素が存在することは意識しておく必要があります?‍♂️ 最低限の親子関係を把握すること こちらの内容は結論、余裕がない場合は把握する必要がありません。徐々に覚えてけば大丈夫です。矛盾しているようですが、意識できているかどうかの話であり、初学者は調べその場で理解できれば良いと思います? ルールとして、よく知られているのは、インライン要素の中にブロック要素は含まないことです。もちろん、例外はありますが、前提として抑えておくことでまず、親子関係が崩れることはないと思います。 親子関係が怪しい際には参考サイトを一度確認した上で使うようにしましょう? また、以下では基本的によくあるページを作る際のタグの使い方・構成をお伝えしていきます。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title>         <link rel="" href=""> </head> <body> <header>ヘッダー</header> <div>キービジュアル(またはファーストビュー)</div> <main> <section>段落(実際に内容を書き込む)</section> <section>段落</section> </main> <footer>フッター</footer> </body> </html> 上記のように基本的はwebサイトのページの構成されていることが多いです。 * 大きくheadタグとbodyタグで分けられている。 * body内では、ヘッダー・キービジュアル・メイン・フッターの四段構成。 * メインでは段落(sectionタグ)で区切られている。 上記の書き方が出来て、実際に内容を書いていきます。たまにサイトでは、 body内では、ヘッダー・キービジュアル・メイン・フッターの四段構成。 メインでは段落(sectionタグ)で区切られている。 がないまたは、全てdivタグで囲っているサイトを見かけます。これでは、他のコーダーが見たときに読みにくく、あまり好ましくありません。人に文章を見せる時と同じで、コードも読み手を意識して書く必要があります?‍♂️ CSS クラス名やタグを一言一句間違えないこと レスポンシブウェブデザインで絶対に間違えない書き方 クラス名やタグを一言一句間違えないこと 正直これが一番CSSを実装する上でよくあるミスかと思います⚠️ タイピングしている際に間違えるのはよくあることです。しかし、常にCSSが効かない原因として意識しておくべきことと言えるでしょう。 個人的に間違えないようにする方法としてオススメなのは常にhtmlファイルとcssファイルを見れる状態にしておくことです? 実際に以下の画像を参考にコードする際に意識してみてください。 必ず、『CSSが反映されてない=スペルミスや全角半角のスペースが無いか確認する』を癖つけておきましょう!!! レスポンシブウェブデザインで絶対に間違えない書き方 初学者がなんとなくCSSが分かってきた❗️となってきてから混乱するのがレスポンシブウェブデザインの実装ですね、、? よく、『レスポンス実装していてPC版のページが崩れた』なんてことがある経験あると思います。事実私も昔はありました? しかし、捉え方を考え方が変わればそこまで難しいことはありません?✨ 一言で言うなら、あるブラウザのサイズ以下(または以上)になったら、プロパティが効くようにするだけです。 基本的なレスポンシブウェブデザインをCSSで実装するにあたって、必要になってくるのがメディアクエリですね。 書き方は cssファイル @media screen and(max-width:〇〇px){ } となります。 ここで注意点はむやみやたらにメディアクエリを乱用しない事です。 ファイルの中を記載する際には、完全に以下のように分けるのがオススメです。 上記のように完全にファイルの中で区分しておけば、自分自身が書いた場所を見失うことも少なくなります。 上記のような分け方はあくまで一例です。ここで一番伝えたいことは、自分で記載したコードをしっかりと把握できるようにしておくことが大事と言うことです? 検証ツールを制するものはコーディングを制す 前提今回はchromに搭載されている検証ツールの仕組みをお伝えします!! windowsやfireFoxでは無いのであらかじめご了承ください。 検証ツールができることを覚える 検証ツールができることを覚える 検証ツールのできることは以下の通りです✌️ 今回はあくまでマークアップを確認する際の主な機能をお伝えします。プログラミングで触る部分は含まれてないものもあります?‍♂️ 1. 実際に反映されているHTML・CSSを確認できる。 * 実験的にCSSを書き込むことができる。 * ブラウザのサイズを変えて確認できる。 * 実際の要素のサイズを確認できる。 * 検証ツールを読み取れると推測ができる。 先に伝えたいことは、あくまで実験的や実際のと言う言葉が多いように検証を行なうツールだと言うことです。 逆を言えば、検証ツールで実装した内容はローカルには自動的に反映されるなどと言うことはありません。 だからこそ、現状を把握することができ、原因の推測ができます? それでは順番に解説していきます。 1.実際に反映されているHTML・CSSを確認できる 以下の画像のようにHTMLとCSSの状態を確認することができます。 2.実験的にCSSを書き込むことができる。 同様に以下の画像のようにCSSを試験的に反映させることができます。 もちろん、プロパティによっては効かないプロパティもありますので、『〇〇プロパティは効くのかどうか』を確認すると言う手段としても使えます? 試験的に試しておけば、わざわざファイルに書き込んでからページをリロードして確認する必要もなくなります。 3.ブラウザのサイズを変えて確認できる。 以下の画像のようにブラウザのサイズを変更することが可能です。 4.実際の要素のサイズを確認できる。 こちらも同様に以下の画像のように情報を確認することができます。 5.検証ツールを読み取れると推測ができる。 例えば、「ブラウザで状態を確認した時にCSSが反映されていない。」と言う状態になったとします?‍♂️ その時、次のことを推測できていますか?? ここは一瞬自分自身で考えていただきたいと思います。 クリック CSSで記載したクラス名または、タグ名が間違えている。(スペルミス) プロパティの書き方のミス(記法ミス) 親要素で指定したプロパティに影響を受けている。(継承のミス) 重複してプロパティの指定をしていたため、ファイルの下部に書いたものが優先されてしまっていた。(重複のミス) いかがだったでしょうか?? 推測できました?ぜひ、ブラウザで反映されていないと言う場合は、参考にしてみてください❗️? 最後に、、。 以上となります!!! 今回、HTMLやCSSを学習を始めて少し知識として身についてきた方向けに書いてみてました!!! 今後もタイミングがあれば、書いていく予定です? よろしくお願いいたします!!!!!!!!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

基礎:HTMLとCSSでwebデザインする際にはここだけを押さえて?!!

完全に個人的にマークアップを学習するにあたって、ここさえ押さえておけば、という部分を書き出しました!! 本内容はHTMLとCSSの概念は理解したけど、実際に書いているときのポイントが掴めない方にオススメです。 また先にお伝えしておくと完全に自己満ですので、予めご了承ください? それじゃぁ、早速いきましょう!!! ITリテラシー ローカルとクラウド ファイルは上から下に順に読み込まれる(下にあるものほど優先順位が上) パスを理解すること 順に説明していきます?? ローカルとクラウド みなさんが知っているようで知らないローカルとクラウドの関係。 ここを理解してないと 「なんで、サイトが公開できないんだーー?????」 ってなったり、 「公開は出来たけど、画像が表示されてない。ローカルでは出来たのに、、」 となります。 それはローカルとクラウドを理解してないからに他なりません。 簡単に一言で言うと、ローカルはPC本体、クラウドはインターネットだと思ってください。 そして、この二つは常に繋がっているとは限りません。 二回言います。ローカルとクラウドは常に繋がっているわけではありません。 想像してみてください。 「Wi-Fiが飛んでいないからページが見れない。」とよく口にすることがありますよね? でも、PCやスマホ本体は開けますよね?? 今、当たり前のことじゃんと思ってませんか? でも、実際にwebサイトを作り、公開するとなると忘れています。 だから、特にサイトを公開する際には、クラウド上で完結するように情報をまとめ、クラウドに情報を保管しておくが大切なんです。 また、ローカルで情報を編集したら、クラウドで情報は勝手に更新してくれない。再度更新するためにクラウドに送る情報を必要があることを理解しておきましょう? <まとめ> ①ローカルはPCやスマホ本体を指す。 ②クラウドはインターネットを指す。 ③ローカルとクラウドは常に繋がってる訳ではない。 サイトを公開する場合: ①クラウド上で完結するように情報をまとめ、クラウドに情報を保管しておくこと。 ②ローカルで情報を編集したら、クラウドで情報は勝手に更新してくれない。 ファイルは上から下に順に読み込まれる(下にあるものほど優先順位が上) これも当たり前と思う方もいるかもしれません。 しかし、プログラミングやマークアップを学び始めの時は意外と忘れがちです。 基本的、HTMLもCSSといったマークアップ言語も他の言語も基本的に書かれたコードの一番上から読み取られます。 何か指定がされない限りは上から下に読み込まれることを理解しておきましょう! 上から順に読み込まれていることを忘れている方のケースをお伝えします。主にHTML・CSSを例にしています。 * CSSの書いている箇所がバラバラでしっかりと自分で把握できるように整理していない。 * html・CSSをコーディングする際に、無理やりCSSで調整しようとしがち。 以上となります。 これを機にぜひ、 今一度ファイルは上から下に読み込まれてること。 下にあるコードほど優先順位が上であること。 を理解しておきましょう!! パスを理解すること そもそも、パスってなんですか??って話なんですが、若干語弊がありますが、簡単に言い換えるとURLです。 URLを覗いてみると、「/」で区切られている時があるのが分かると思います。 例えば、次のURLがあるとします。 htps://xxxxx.com/teams/sssss/overview URLを言語化すると、htps://xxxxx.com の中のteams の中の sssss の中の overviewというページを開いているということになります。 つまり、どのページや画像を示しているのかを表示するために「/」でフォルダやファイルを区切っています。 そして、これには絶対パスと相対パスがあります。 絶対パス: 直接、指定したい場所を示します。 相対パス: 相対パスは絶対パスとは異なり、ある基準を決めて指定を行ないます。 書き方も含めて例をご覧ください。 例) topフォルダ -secondフォルダA -ファイルA−1 -ファイルA-2     -secondフォルダB -ファイルB 例えば上記のような構造があったとします。 ファイルAー1から、ファイルAー2を呼び出す際は、「./ファイルA-2」と呼び出します。 ファイルAー1から、ファイルBを呼び出す際は「../secondフォルダB/ファイルB」と呼び出します。 つまり、ファイルを呼び出す際はどこを基準にしているかがポイントです。 ファイルAー2を呼び出す際は、共通のフォルダであるsecondフォルダAを基準とし、 ファイルBを呼び出す際には共通のフォルダのtopフォルダを基準にしています。またフォルダを一つ挟んで、違うフォルダを指定する際には「../」と書き始めます。 ※フォルダを二つ挟む場合は「../../」で書き始めます。 HTML 要素の始まりは左上から ブロック要素とインライン要素、インラインブロック要素がある 親子関係を把握すること 要素の始まりは左上から 「ブラウザに表示させる際、要素の始まりは左上からが基準である」は、初学者が意外と理解していない部分ですね? 理解していないとどのようなことを起こるのかお伝えすると、CSSで無理やり調整します。 更には、 CSSで無理やり調整する ーーーー?ーーーー コードの量が増える ーーーー?ーーーー 自分の書いている部分が分からなくなる ーーーー?ーーーー ちょっとブラウザのサイズを変えただけで、サイトが崩れる ーーーー?ーーーー 手がつけられなくなる というような悪循環が発生しかねません? CSSで無理に調整しようとせずに、要素が左上から始まると理解していれば、無理に左上に調整するプロパティなど要りません。 ブロックレベル要素とインライン要素、インラインブロック要素がある これまた、学んでいくうちに忘れがちな知識かなと思っています。軽視しがちとも言いますか、、、。 ともかく、CSSで装飾していくにあたって、ブロックレベル(ブロック要素とも呼ぶ)要素とインライン要素、インラインブロック要素を把握しておけばコードがもっと短くなります。それぞれ把握しておきましょう! | 要素名 | 幅と高さの指定 | 幅の初期値 |高さの初期値|要素同士の並び方|主なHTMLタグ| |:-----------|------------:|:------------:|:------------:|:------------:|:------------:| | ブロック要素 |可能  | 親要素に依存する |内容に依存|縦に並ぶ|div、p、h1~h6、ul、など| | インライン要素 |不可能 | 内容で決まる |内容に依存|横に並ぶ|a、li、input、textarea、spanなど| | インラインブロック要素 |可能  | 内容で決まる |内容に依存|横に並ぶ|--- displayプロパティでinline-blockと指定することがほとんど| 全てのHTMLタグを把握しておく必要はありません。私の場合は、参考サイトで確認することがほとんどです。 しかし、ブロックレベル要素とインライン要素、インラインブロック要素が存在することは意識しておく必要があります?‍♂️ 最低限の親子関係を把握すること こちらの内容は結論、余裕がない場合は把握する必要がありません。徐々に覚えてけば大丈夫です。矛盾しているようですが、意識できているかどうかの話であり、初学者は調べその場で理解できれば良いと思います? ルールとして、よく知られているのは、インライン要素の中にブロック要素は含まないことです。もちろん、例外はありますが、前提として抑えておくことでまず、親子関係が崩れることはないと思います。 親子関係が怪しい際には参考サイトを一度確認した上で使うようにしましょう? また、以下では基本的によくあるページを作る際のタグの使い方・構成をお伝えしていきます。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title>         <link rel="" href=""> </head> <body> <header>ヘッダー</header> <div>キービジュアル(またはファーストビュー)</div> <main> <section>段落(実際に内容を書き込む)</section> <section>段落</section> </main> <footer>フッター</footer> </body> </html> 上記のように基本的はwebサイトのページの構成されていることが多いです。 * 大きくheadタグとbodyタグで分けられている。 * body内では、ヘッダー・キービジュアル・メイン・フッターの四段構成。 * メインでは段落(sectionタグ)で区切られている。 上記の書き方が出来て、実際に内容を書いていきます。たまにサイトでは、 body内では、ヘッダー・キービジュアル・メイン・フッターの四段構成。 メインでは段落(sectionタグ)で区切られている。 がないまたは、全てdivタグで囲っているサイトを見かけます。これでは、他のコーダーが見たときに読みにくく、あまり好ましくありません。人に文章を見せる時と同じで、コードも読み手を意識して書く必要があります?‍♂️ CSS クラス名やタグを一言一句間違えないこと レスポンシブウェブデザインで絶対に間違えない書き方 クラス名やタグを一言一句間違えないこと 正直これが一番CSSを実装する上でよくあるミスかと思います⚠️ タイピングしている際に間違えるのはよくあることです。しかし、常にCSSが効かない原因として意識しておくべきことと言えるでしょう。 個人的に間違えないようにする方法としてオススメなのは常にhtmlファイルとcssファイルを見れる状態にしておくことです? 実際に以下の画像を参考にコードする際に意識してみてください。 必ず、『CSSが反映されてない=スペルミスや全角半角のスペースが無いか確認する』を癖つけておきましょう!!! レスポンシブウェブデザインで絶対に間違えない書き方 初学者がなんとなくCSSが分かってきた❗️となってきてから混乱するのがレスポンシブウェブデザインの実装ですね、、? よく、『レスポンス実装していてPC版のページが崩れた』なんてことがある経験あると思います。事実私も昔はありました? しかし、捉え方を考え方が変わればそこまで難しいことはありません?✨ 一言で言うなら、あるブラウザのサイズ以下(または以上)になったら、プロパティが効くようにするだけです。 基本的なレスポンシブウェブデザインをCSSで実装するにあたって、必要になってくるのがメディアクエリですね。 書き方は cssファイル @media screen and(max-width:〇〇px){ } となります。 ここで注意点はむやみやたらにメディアクエリを乱用しない事です。 ファイルの中を記載する際には、完全に以下のように分けるのがオススメです。 上記のように完全にファイルの中で区分しておけば、自分自身が書いた場所を見失うことも少なくなります。 上記のような分け方はあくまで一例です。ここで一番伝えたいことは、自分で記載したコードをしっかりと把握できるようにしておくことが大事と言うことです? 検証ツールを制するものはコーディングを制す 前提今回はchromに搭載されている検証ツールの仕組みをお伝えします!! windowsやfireFoxでは無いのであらかじめご了承ください。 検証ツールができることを覚える 検証ツールができることを覚える 検証ツールのできることは以下の通りです✌️ 今回はあくまでマークアップを確認する際の主な機能をお伝えします。プログラミングで触る部分は含まれてないものもあります?‍♂️ 1. 実際に反映されているHTML・CSSを確認できる。 * 実験的にCSSを書き込むことができる。 * ブラウザのサイズを変えて確認できる。 * 実際の要素のサイズを確認できる。 * 検証ツールを読み取れると推測ができる。 先に伝えたいことは、あくまで実験的や実際のと言う言葉が多いように検証を行なうツールだと言うことです。 逆を言えば、検証ツールで実装した内容はローカルには自動的に反映されるなどと言うことはありません。 だからこそ、現状を把握することができ、原因の推測ができます? それでは順番に解説していきます。 1.実際に反映されているHTML・CSSを確認できる 以下の画像のようにHTMLとCSSの状態を確認することができます。 2.実験的にCSSを書き込むことができる。 同様に以下の画像のようにCSSを試験的に反映させることができます。 もちろん、プロパティによっては効かないプロパティもありますので、『〇〇プロパティは効くのかどうか』を確認すると言う手段としても使えます? 試験的に試しておけば、わざわざファイルに書き込んでからページをリロードして確認する必要もなくなります。 3.ブラウザのサイズを変えて確認できる。 以下の画像のようにブラウザのサイズを変更することが可能です。 4.実際の要素のサイズを確認できる。 こちらも同様に以下の画像のように情報を確認することができます。 5.検証ツールを読み取れると推測ができる。 例えば、「ブラウザで状態を確認した時にCSSが反映されていない。」と言う状態になったとします?‍♂️ その時、次のことを推測できていますか?? ここは一瞬自分自身で考えていただきたいと思います。 クリック CSSで記載したクラス名または、タグ名が間違えている。(スペルミス) プロパティの書き方のミス(記法ミス) 親要素で指定したプロパティに影響を受けている。(継承のミス) 重複してプロパティの指定をしていたため、ファイルの下部に書いたものが優先されてしまっていた。(重複のミス) いかがだったでしょうか?? 推測できました?ぜひ、ブラウザで反映されていないと言う場合は、参考にしてみてください❗️? 最後に、、。 以上となります!!! 今回、HTMLやCSSを学習を始めて少し知識として身についてきた方向けに書いてみてました!!! 今後もタイミングがあれば、書いていく予定です? よろしくお願いいたします!!!!!!!!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

基礎:HTMLとCSSで書くときのコツ

完全に個人的にマークアップを学習するにあたって、ここさえ押さえておけば、という部分を書き出しました!! 本内容はHTMLとCSSの概念は理解したけど、実際に書いているときのポイントが掴めない方にオススメです。 また先にお伝えしておくと完全に自己満ですので、若干偏見もあります。予めご了承ください? それじゃぁ、早速いきましょう!!! ITリテラシー ローカルとクラウド ファイルは上から下に順に読み込まれる(下にあるものほど優先順位が上) パスを理解すること 順に説明していきます?? ローカルとクラウド みなさんが知っているようで知らないローカルとクラウドの関係。 ここを理解してないと 「なんで、サイトが公開できないんだーー?????」 ってなったり、 「公開は出来たけど、画像が表示されてない。ローカルでは出来たのに、、」 となります。 それはローカルとクラウドを理解してないからに他なりません。 簡単に一言で言うと、ローカルはPC本体、クラウドはインターネットだと思ってください。 そして、この二つは常に繋がっているとは限りません。 二回言います。ローカルとクラウドは常に繋がっているわけではありません。 想像してみてください。 「Wi-Fiが飛んでいないからページが見れない。」とよく口にすることがありますよね? でも、PCやスマホ本体は開けますよね?? 今、当たり前のことじゃんと思ってませんか? しかし、実際にwebサイトを作り、公開するとなると忘れガチだったりします。 そのため、特にサイトを公開する際には、クラウド上で完結するように情報をまとめ、クラウドに情報を保管しておくが大切なんです。 また、ローカルで情報を編集したら、クラウドで情報は勝手に更新してくれない。再度更新するためにクラウドに送る情報を必要があることを理解しておきましょう? <まとめ> ①ローカルはPCやスマホ本体を指す。 ②クラウドはインターネットを指す。 ③ローカルとクラウドは常に繋がってる訳ではない。 サイトを公開する場合: ①クラウド上で完結するように情報をまとめ、クラウドに情報を保管しておくこと。 ②ローカルで情報を編集したら、クラウドで情報は勝手に更新してくれない。 ファイルは上から下に順に読み込まれる(下にあるものほど優先順位が上) これも当たり前と思う方もいるかもしれません。 しかし、プログラミングやマークアップを学び始めの時は意外と忘れがちです。 基本的、HTMLもCSSといったマークアップ言語も他の言語も基本的に書かれたコードの一番上から読み取られます。 何か指定がされない限りは上から下に読み込まれることを理解しておきましょう! 上から順に読み込まれていることを忘れている方のケースをお伝えします。主にHTML・CSSを例にしています。 * CSSの書いている箇所がバラバラでしっかりと自分で把握できるように整理していない。 * html・CSSをコーディングする際に、無理やりCSSで調整しようとしがち。 以上となります。 これを機にぜひ、 今一度ファイルは上から下に読み込まれてること。 下にあるコードほど優先順位が上であること。 を理解しておきましょう!! パスを理解すること そもそも、パスってなんですか??って話なんですが、若干語弊がありますが、簡単に言い換えるとURLです。 URLを覗いてみると、「/」で区切られている時があるのが分かると思います。 例えば、次のURLがあるとします。 htps://xxxxx.com/teams/sssss/overview URLを言語化すると、htps://xxxxx.com の中のteams の中の sssss の中の overviewというページを開いているということになります。 つまり、どのページや画像を示しているのかを表示するために「/」でフォルダやファイルを区切っています。 そして、これには絶対パスと相対パスがあります。 絶対パス: 直接、指定したい場所を示します。 相対パス: 相対パスは絶対パスとは異なり、ある基準を決めて指定を行ないます。 書き方も含めて例をご覧ください。 例) topフォルダ -secondフォルダA -ファイルA−1 -ファイルA-2     -secondフォルダB -ファイルB 例えば上記のような構造があったとします。 ファイルAー1から、ファイルAー2を呼び出す際は、「./ファイルA-2」と呼び出します。 ファイルAー1から、ファイルBを呼び出す際は「../secondフォルダB/ファイルB」と呼び出します。 つまり、ファイルを呼び出す際はどこを基準にしているかがポイントです。 ファイルAー2を呼び出す際は、共通のフォルダであるsecondフォルダAを基準とし、 ファイルBを呼び出す際には共通のフォルダのtopフォルダを基準にしています。またフォルダを一つ挟んで、違うフォルダを指定する際には「../」と書き始めます。 ※フォルダを二つ挟む場合は「../../」で書き始めます。 HTML 私個人的に学び始めてから数日経ってる方に抑えておいた方がいいポイントは以下です?? * 要素の始まりは左上から * ブロック要素とインライン要素、インラインブロック要素がある * 親子関係を把握すること 要素の始まりは左上から 「ブラウザに表示させる際、要素の始まりは左上からが基準である」は、初学者が意外と理解していない部分ですね? 理解していないとどのようなことを起こるのかお伝えすると、CSSで無理やり調整します。 更には、 CSSで無理やり調整する ーーーー?ーーーー コードの量が増える ーーーー?ーーーー 自分の書いている部分が分からなくなる ーーーー?ーーーー ちょっとブラウザのサイズを変えただけで、サイトが崩れる ーーーー?ーーーー 手がつけられなくなる というような悪循環が発生しかねません? CSSで無理に調整しようとせずに、要素が左上から始まると理解していれば、無理に左上に調整するプロパティなど要りません。 ブロックレベル要素とインライン要素、インラインブロック要素がある これまた、学んでいくうちに忘れがちな知識かなと思っています。軽視しがちとも言いますか、、、。 ともかく、CSSで装飾していくにあたって、ブロックレベル(ブロック要素とも呼ぶ)要素とインライン要素、インラインブロック要素を把握しておけばコードがもっと短くなります。それぞれ把握しておきましょう! | 要素名 | 幅と高さの指定 | 幅の初期値 |高さの初期値|要素同士の並び方|主なHTMLタグ| |:-----------|------------:|:------------:|:------------:|:------------:|:------------:| | ブロック要素 |可能  | 親要素に依存する |内容に依存|縦に並ぶ|div、p、h1~h6、ul、など| | インライン要素 |不可能 | 内容で決まる |内容に依存|横に並ぶ|a、li、input、textarea、spanなど| | インラインブロック要素 |可能  | 内容で決まる |内容に依存|横に並ぶ|--- displayプロパティでinline-blockと指定することがほとんど| 全てのHTMLタグを把握しておく必要はありません。私の場合は、参考サイトで確認することがほとんどです。 しかし、ブロックレベル要素とインライン要素、インラインブロック要素が存在することは意識しておく必要があります?‍♂️ 最低限の親子関係を把握すること こちらの内容は結論、余裕がない場合は把握する必要がありません。徐々に覚えてけば大丈夫です。矛盾しているようですが、意識できているかどうかの話であり、初学者は調べその場で理解できれば良いと思います? ルールとして、よく知られているのは、インライン要素の中にブロック要素は含まないことです。もちろん、例外はありますが、前提として抑えておくことでまず、親子関係が崩れることはないと思います。 親子関係が怪しい際には参考サイトを一度確認した上で使うようにしましょう? また、以下では基本的によくあるページを作る際のタグの使い方・構成をお伝えしていきます。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title>         <link rel="" href=""> </head> <body> <header>ヘッダー</header> <div>キービジュアル(またはファーストビュー)</div> <main> <section>段落(実際に内容を書き込む)</section> <section>段落</section> </main> <footer>フッター</footer> </body> </html> 上記のように基本的はwebサイトのページの構成されていることが多いです。 * 大きくheadタグとbodyタグで分けられている。 * body内では、ヘッダー・キービジュアル・メイン・フッターの四段構成。 * メインでは段落(sectionタグ)で区切られている。 上記の書き方が出来て、実際に内容を書いていきます。たまにサイトでは、 body内では、ヘッダー・キービジュアル・メイン・フッターの四段構成。 メインでは段落(sectionタグ)で区切られている。 がないまたは、全てdivタグで囲っているサイトを見かけます。これでは、他のコーダーが見たときに読みにくく、あまり好ましくありません。人に文章を見せる時と同じで、コードも読み手を意識して書く必要があります?‍♂️ CSS クラス名やタグを一言一句間違えないこと レスポンシブウェブデザインで絶対に間違えない書き方 クラス名やタグを一言一句間違えないこと 正直これが一番CSSを実装する上でよくあるミスかと思います⚠️ タイピングしている際に間違えるのはよくあることです。しかし、常にCSSが効かない原因として意識しておくべきことと言えるでしょう。 個人的に間違えないようにする方法としてオススメなのは常にhtmlファイルとcssファイルを見れる状態にしておくことです? 実際に以下の画像を参考にコードする際に意識してみてください。 必ず、『CSSが反映されてない=スペルミスや全角半角のスペースが無いか確認する』を癖つけておきましょう!!! レスポンシブウェブデザインで絶対に間違えない書き方 初学者がなんとなくCSSが分かってきた❗️となってきてから混乱するのがレスポンシブウェブデザインの実装ですね、、? よく、『レスポンス実装していてPC版のページが崩れた』なんてことがある経験あると思います。事実私も昔はありました? しかし、捉え方を考え方が変わればそこまで難しいことはありません?✨ 一言で言うなら、あるブラウザのサイズ以下(または以上)になったら、プロパティが効くようにするだけです。 基本的なレスポンシブウェブデザインをCSSで実装するにあたって、必要になってくるのがメディアクエリですね。 書き方は cssファイル @media screen and(max-width:〇〇px){ } となります。 ここで注意点はむやみやたらにメディアクエリを乱用しない事です。 ファイルの中を記載する際には、完全に以下のように分けるのがオススメです。 上記のように完全にファイルの中で区分しておけば、自分自身が書いた場所を見失うことも少なくなります。 上記のような分け方はあくまで一例です。ここで一番伝えたいことは、自分で記載したコードをしっかりと把握できるようにしておくことが大事と言うことです? 検証ツールを制するものはコーディングを制す 前提今回はchromに搭載されている検証ツールの仕組みをお伝えします!! windowsやfireFoxでは無いのであらかじめご了承ください? 検証ツールができることを覚える 検証ツールのできることは以下の通りです✌️ 今回はあくまでマークアップを確認する際の主な機能をお伝えします。プログラミングで触る部分は含まれてないものもあります?‍♂️ 1. 実際に反映されているHTML・CSSを確認できる。 * 実験的にCSSを書き込むことができる。 * ブラウザのサイズを変えて確認できる。 * 実際の要素のサイズを確認できる。 * 検証ツールを読み取れると推測ができる。 先に伝えたいことは、あくまで実験的や実際のと言う言葉が多いように検証を行なうツールだと言うことです。 逆を言えば、検証ツールで実装した内容はローカルには自動的に反映されるなどと言うことはありません。 だからこそ、現状を把握することができ、原因の推測ができます? それでは順番に解説していきます。 1.実際に反映されているHTML・CSSを確認できる 以下の画像のようにHTMLとCSSの状態を確認することができます。 2.実験的にCSSを書き込むことができる。 同様に以下の画像のようにCSSを試験的に反映させることができます。 もちろん、プロパティによっては効かないプロパティもありますので、『〇〇プロパティは効くのかどうか』を確認すると言う手段としても使えます? 試験的に試しておけば、わざわざファイルに書き込んでからページをリロードして確認する必要もなくなります。 3.ブラウザのサイズを変えて確認できる。 以下の画像のようにブラウザのサイズを変更することが可能です。 4.実際の要素のサイズを確認できる。 こちらも同様に以下の画像のように情報を確認することができます。 5.検証ツールを読み取れると推測ができる。 例えば、「ブラウザで状態を確認した時にCSSが反映されていない。」と言う状態になったとします?‍♂️ その時、次のことを推測できていますか?? ここは一瞬自分自身で考えていただきたいと思います。 クリック CSSで記載したクラス名または、タグ名が間違えている。(スペルミス) プロパティの書き方のミス(記法ミス) 親要素で指定したプロパティに影響を受けている。(継承のミス) 重複してプロパティの指定をしていたため、ファイルの下部に書いたものが優先されてしまっていた。(重複のミス) いかがだったでしょうか?? 推測できました?ぜひ、ブラウザで反映されていないと言う場合は、参考にしてみてください❗️? 最後に、、。 以上となります!!! 今回、HTMLやCSSを学習を始めて少し知識として身についてきた方向けに書いてみてました!!! 今後もタイミングがあれば、書いていく予定です? よろしくお願いいたします!!!!!!!!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CSSのcontentプロパティで画像を指定してサイズ調整する方法

使いどころ CSSの中で、画像URLの指定とサイズの指定を同時に行いたいとき。 @media screen and ( max-width: 600px )を使ってpcとモバイルで画像を切り替えたいとき。 imgの「widthとheightが効かない」とき。 方法 display: inline-block;が重要です。 index.html <a href="https://www.google.com/" target="_blank" rel="noreferrer" > <img alt="ロゴだよ" id="mylogo"/> </a> style.css #mylogo{ content: url("./svg/my_logo_line.svg"); display: inline-block; width: 6.5rem; height: auto; } 備考 セマンティックデザイン的に、ロゴなのでbackground-imageではなく、imgにする必要あり。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

テーブルタグについて

テーブルタグを外すと、tdのテーブルの要素がはずれて、 テーブルではなく、列でcssを記載することができた。 列ごとで、しかも奇数の列にだけ色を付けるのをやってたんだけど テーブルタグついてるとテーブルごとだから、テーブルとテーブルの間は白になってて、列全体がその背景色になってくれなかった。 普通にtableタグをはずしたら一列ずつきれいにつくられた。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

色々書き比べた結果Tailwind CSSにしたという話

Twitterでこういう発言を見かけまして Tailwind CSSはデザインに凝ってるサイトでは使えない こだわりが無い場合に向いている は?何いってんの? って思ったので、自分がいろいろ試した結果、Tailwind CSSを選んだ話を書きます。 はじめに 以前、Tailwind CSSは結構いいぞって話を書いたんですが、この記事の立ち位置的にはその続きみたいなものなので、以下の記事を始めにご参照いただけるとより分かりやすいかもしれないです。 この記事では、前回記事を書いた後、個人仕事でWebサイトをGatsbyで作り、その中で、どうやってCSSを書くのが良いのか模索した結果、自分はこれを選んだっていうのを、同じUIを色々な方法で書き比べたコードを並べつつ、どうのこうの筆者の考えを述べていきます。 その仕事はほとんど筆者が「まかせてくださいよーいい感じに作りますよー。デザインそろってないっすね。揃えます!」ってノリで、自分が好き勝手、やりたいようにやったやつです。ちなみにGatsby + Prismicでやりました。Movable Typeでやるとか言ってたので辞めさせてそれにしました。 はじめに、最終的にCSSを書くために使った技術を言っておくと 8割方Tailwind CSS Tailwind CSSで書きづらい部分は @emotion/css + twin.macro です。 サンプルコード なんか書いてたらどんどん長くなってしまって、うわっ、私の記事長すぎ……って思ってるのですが、この記事を書くために書いたコードは以下に置いておきました。 create-react-app で作ってて、以下にデプロイしてあります サンプルコードって言っても、ほぼひたすら同じUIを別の方法で書いたやつが並んでるだけですが。このページに並んでいるのは、 スモールスクリーン時は縦にテキストと画像が積まれる ワイドスクリーン時は横にテキストと画像が並ぶ という、CSSを書いてる人であれば100万回ぐらい書いたであろうものを、色んな方法で書いたものです。ブラウザを縮めたり広げたりしてご確認頂ければと思います。 コンポーネントはこのディレクトリに一通り入ってます。 ピュアにTailwind CSSで書いたモノ それでははじめましょー。ReactでどうCSS設計をしたら良いのかの旅ってことで。 とりあえず初めは、純粋にTailwind CSSで書いたらこうなるぞというものです。 コードとしてはこんな感じになります。 <div className="lg:ml-[-40px]"> <div className="lg:flex w-full"> <div className="pb-[20px] space-y-[20px] lg:pl-[40px] lg:w-1/2"> <p>The quick brown fox...</p> <p>The quick brown fox...</p> <p>The quick brown fox...</p> </div> <div className="lg:pl-[40px] lg:w-1/2"> <img className="block w-full" src="https://placekitten.com/400/300" alt="" /> </div> </div> </div> まず、前回の記事でも書いたことなんですが、ReactやらVueなりで書くわけでもナシに、HTMLとCSSを手書きで書いているような状況だとします。 このUIが1回だけ出てくるんであればこれでいいんですが、このUIなんて汎用的に使われそうなやつですし、2回以上出てくる時に、これで書いてしまうとキツいですね。 Tailwind CSSで書けば、CSS書かなくてもスタイル当てられて楽だ〜ってなるんですが、これをコピペして画面を増やしていったら、使われてる箇所を全部直して回らないといけないです。地獄……。なので、HTML+CSSだけ書いているような人にとっては 「うーんTailwind CSSってこういうやつか〜。私は使わないなー」 って思うんじゃないかと思います。まーそれはそうですね。自分も手でHTMLを量産していくようなケースにおいては、Tailwind CSSは選ばねーなと思います。 救世主BEM そんなこんなでHTML+CSSを書く人たちを救ってくれたと言うか、あ!これこれ!これいいね!って流行ったのがBEMなわけなんですが、そのBEMで書くと、以下のような感じになります。 <div className="BemBlock"> <div className="BemBlock__Inner"> <div className="BemBlock__TextWrapper"> <p>The quick brown fox...</p> <p>The quick brown fox...</p> <p>The quick brown fox...</p> </div> <div className="BemBlock__ImgWrapper"> <img className="BemBlock__Img" src="https://placekitten.com/400/300" alt="" /> </div> </div> </div> /* BemBlock */ .BemBlock__TextWrapper { padding: 0 0 20px; } .BemBlock__TextWrapper > * + * { padding: 20px 0 0; } .BemBlock__Img { display: block; width: 100%; } @media (min-width: 768px) { .BemBlock { margin: 0 0 0 -40px; } .BemBlock__Inner { display: flex; width: 100%; } .BemBlock__TextWrapper { padding: 0 0 0 40px; width: 50%; } .BemBlock__TextWrapper > * + * { padding: 20px 0 0; } .BemBlock__ImgWrapper { padding: 0 0 0 40px; width: 50%; } } BEMについてはここで突っ込んで書かないですが、これでコンポーネントっぽくできたねーという感じです。ただ、色々問題があります。 まずひとつは、このCSSが書かれているのが、サイト全体で読み込んでいるCSSであるということ。色々やりようはありますが、基本的には、多くの画面において、その画面で使っていないCSSのルールが大量に含まれた巨大CSSを読み込むことになります。 そしてもうひとつは、これはコンポーネントらしきモノにすぎないということです。スタイルを変えたかったら、確かにCSSをいじればそれで済むんですが、変えたい内容によってはdivやらspanやらを追加したり、要素の順番を入れ替えたり追加したりしないとならないです。コンポーネントを夢見たHTMLとCSSって感じです。今からすると。 まぁ、色々問題はあるものの、みんながそれぞれの考え方で好き好きにCSSを書いていた時代と比べると、こんな風にわかりやすいルールが広まって、共通言語みたいになったというのは、すごいことだなーとは思います。自分も手書きでHTMLをガンガン書いていくような状況では、積極的にBEMを選ぶと思います。 BEM + Tailwind CSS そんなBEMですが、このBEMベースの設計にTailwind CSSを混ぜることは出来ます。コードとしてはこんな感じです。HTMLはさっきとほぼ一緒な感じ。 <div className="BemTailwindBlock"> <div className="BemTailwindBlock__Inner"> <div className="BemTailwindBlock__TextWrapper"> <p>The quick brown fox...</p> <p>The quick brown fox...</p> <p>The quick brown fox...</p> </div> <div className="BemTailwindBlock__ImgWrapper"> <img className="BemTailwindBlock__Img" src="https://placekitten.com/400/300" alt="" /> </div> </div> </div> /* BemTailwindBlock */ .BemTailwindBlock { @apply lg:ml-[-40px]; } .BemTailwindBlock__Inner { @apply lg:flex w-full; } .BemTailwindBlock__TextWrapper { @apply pb-[20px] space-y-[20px]; @apply lg:pl-[40px] lg:w-1/2; } .BemTailwindBlock__ImgWrapper { @apply lg:pl-[40px] lg:w-1/2; } .BemTailwindBlock__Img { @apply block w-full; } どうでしょう、だいぶスッキリしてます。 この場合のTailwind CSSの役割としては、色々と短く書けるってことですね。あと、Tailwind CSSではデザインシステム的なことをすることができて、それを活かせるというのもあるんですが、これについては後で書きます。 こういう使い方はナシじゃないんですが、Tailwind CSSの指向している「ユーティリティーファースト」とは違うんですよね。はじめはこういう風にTailwind CSSを使うのは違うんですよって思って書いたんですが、なんか実際書いてみると悪くはないですね……。手でHTMLを書いていく場合にはまぁこういう使い方を検討してみてもいいんではないでしょうか。 とはいえ!前述のBEMの問題は何も解決されていないです。このコードでapplyしてる部分はただTailwind CSSで定義されているプロパティと値のセットに置き換わるだけなので、実質、Sass的に言うと「便利なmixinがいっぱい使える」みたいな状態ですね。 なので、こういう使い方を想像されているなら、 「うーん、学習コストそれなりにあるし、別にいっかな〜〜〜」 は、まぁそうだろうなとは思います。 これは主観ですが、Tailwind CSSを書くのって、フツーにCSS書いてる感じとだいぶ感覚が違うんですよね。それはこの後書くTailwind CSSの設計思想によるところが大きいからだと思うんですが、何にせよ、こういう風に書くのはナシではないとは思います。BEMっぽく書いてTailwind CSSを使うなら、PostCSSのプラグインをちょいちょい組み合わせると色々快適になります。 CSS Modules まぁここまでがReactやらVueナシの世界の話でして。 HTMLとCSSだけ書いてると、CSS設計的にはその先に行けないなーというか。筆者的にはその先にあるのがReactだのVueだと思ってるんですよね。これは、ReactとかVueはそういうものだというわけではなく、私はReactやVueを、そういうCSS設計でBEMの先にある存在として扱おうと考えてるってことです。Reactはコンポーネント指向の「ライブラリ」なので、それをそいういう風に扱いたいなーと考えている筆者が居る感じといいますか。まぁこのあたりの話は前回の記事を読んでいただくとして。 ここからは、じゃーReactでどう書く?ってのを、アレやコレやためしたというのを書いていきます。 まずはCSS Modulesです。 まずReactで何かCSS書く時にどうする?って選択肢として挙がるのがCSS Modulesだと思います。GatsbyでもCSS Modulesオススメよって書いてあります。 まぁ筆者的にはもうこれはオススメすべきやつじゃないんじゃないのって感じではあるんですが。 何はともあれ、どんな感じか、例のUIをCSS Modulesで書いてみたコードが以下です。 App.js <CssModulesBlock src="https://placekitten.com/400/300"> <p>The quick brown fox...</p> <p>The quick brown fox...</p> <p>The quick brown fox...</p> </CssModulesBlock> css-modules-block.js import styles from './css-modules-block.module.css'; export const CssModulesBlock = ({ children, src }) => ( <div className={styles.container}> <div className={styles.inner}> <div className={styles.textWrapper}> { children } </div> <div className={styles.imgWrapper}> <img className={styles.img} src={src} alt="" /> </div> </div> </div> ); css-modules-block.module.css .textWrapper { padding: 0 0 20px; } .textWrapper > * + * { padding: 20px 0 0; } .img { display: block; width: 100%; } @media (min-width: 768px) { .container { margin: 0 0 0 -40px; } .inner { display: flex; width: 100%; } .textWrapper { padding: 0 0 0 40px; width: 50%; } .textWrapper > * + * { padding: 20px 0 0; } .imgWrapper { padding: 0 0 0 40px; width: 50%; } } ざっくり言うと、CSSをファイルをimportすると、そのCSSファイルの中にあるクラスセレクタに、ランダムな文字を足してくれて、それを各要素のclassNameに指定していくって感じです。headの中にはそれに対応するセレクタが突っ込まれます。こんな感じに。 <style> .css-modules-block_textWrapper__JEfrZ { padding: 0 0 20px; } .css-modules-block_textWrapper__JEfrZ > * + * { padding: 20px 0 0; } .css-modules-block_img__5jb8q { display: block; width: 100%; } @media (min-width: 768px) { .css-modules-block_container__2xV22 { margin: 0 0 0 -40px; } .css-modules-block_inner__1Fwz- { display: flex; width: 100%; } .css-modules-block_textWrapper__JEfrZ { padding: 0 0 0 40px; width: 50%; } .css-modules-block_textWrapper__JEfrZ > * + * { padding: 20px 0 0; } .css-modules-block_imgWrapper__JeJhQ { padding: 0 0 0 40px; width: 50%; } } </style> そしてHTMLの方はこうなります。 <div class="css-modules-block_container__2xV22"> <div class="css-modules-block_inner__1Fwz-"> <div class="css-modules-block_textWrapper__JEfrZ"> <p>The quick brown fox...</p> <p>The quick brown fox...</p> <p>The quick brown fox...</p> </div> <div class="css-modules-block_imgWrapper__JeJhQ"> <img class="css-modules-block_img__5jb8q" src="https://placekitten.com/400/300" alt=""> </div> </div> </div> この結果、ほとんどこのコンポーネント内でスコープを作ったみたいな状態にできます。 なるほど悪く無さそう。それにこれ、なるべくCSSは純粋なCSSとして扱おうとしているアプローチがいい感じに見えますね。さらに、このCSSの中ではさっきBEM + Tailwind CSSでやったみたいに、@applyが使えたりもします。PostCSSが使えるってことです。CSS in JSとかハックっぽい感じがしますし、そんなことする必要ないでしょ?これでよくない?って思ってました。初めは。 最終的に自分はTailwind CSSとCSS in JSを選ぶんですけど、Tailwind CSSではどうしても書きづらい部分があって、そういう部分はCSS Modulesを使うつもりでいました。どういうやつが書き辛いのかは追って書いていきます。 でも結局CSS Modulesを使うのはやめました。理由としては以下のような感じです。 ファイルが増えてめんどくさい CSS Modulesを使うと、1コンポーネント毎に1つ、CSSファイルを作らないといけないんですよね。「えー?そんなの大したこと無くない?」「CSSなんだからCSSファイルに書くのは当然でしょ」って最初は思ってたんですが、やってみるとこれ、だいぶゴチャゴチャして書き辛いと感じました。特に、ただ3,4行のCSSを書きたいだけの時にファイルが増えていくのがなかなか辛いなーと。CSS Modulesの対抗馬となるのは各種CSS in JSなんですが、これは対抗馬であるCSS in JSの方がスッキリ読みやすいと思ったというのがまずひとつ。 順番が保証されないとか怒られる Gatsbyでやってると、別の画面に遷移した時、その画面でコンポーネントの読み込み順が異なると、「CSSの読み込み順が異なるからスタイルが意図したとおりに反映される保証ねーぞ」みたいにwebpackに怒られました。こんな感じです。 これ、すごいややこしいんですが、CSS Modulesって、CSSを追加で読み込むんで、コンポーネントをimportする順番が違ってると、これはまずいんじゃない? CSSの順序違ったら、想定している描画結果変わっちゃわない? っていちいち警告してくれるんですよね。 なんかこれを回避するには、importの順番を揃えるとかせねばならないらしく、いやーめんどくさい……ってなりました。まぁこれは無視しても良かったんですが、とりあえず筆者的には「うーんCSS Modulesじゃないほうがいいのかなー」って思わされた事件でした。 webpack依存技術である なんか最初はCSS標準技術に近いやつだなって思ってたんですけど、結局の所これ、webpackをゴニョゴニョして無理矢理スコープっぽくしてるだけなんですよね。GatsbyだのNext.jsは、webpackに乗っかっているReactのその上に存在するレイヤーなので、なんかこのwebpackの機能に依存しているCSS Modulesという存在が、フレームワークとうまいこと噛み合ってねーなと感じました。この後書くCSS in JSもほぼほぼ同じことをやっているんですが、JSファイルの中でチョロっと書けてしまって。それに対してCSS Modulesはお行儀よくCSSファイルにしないといけないんですよ。そしてwebpack依存技術だぞっと。 まぁそんなこんなで、端的に言うとCSS in JSのほうがベターであると考え、筆者はCSS Modulesを使うのはやめました。ありがとうさようならCSS Modules。 BEM混ぜます? CSS Modulesじゃないとするとどうしようかなーと思って、その一つの選択肢が、一部だけBEM的に書く。グローバルな感じのCSSに一部BEMで書いたCSSを書いちゃうという方法です。最初はこれで良いんじゃないかなーと思ってやってたんですが、結局やめました。なぜかと言うと、さっき書いたみたいな、グローバルなCSSがどんどん増えるっていう問題がまずあるんですが、それよりも、 Reactコンポーネント化したUI BEMで組んだUI が混在することが、管理上辛いなーと感じたためです。 こっちはReactコンポーネントで完結してて、こっちは一部だけグローバルな部分にCSSが書いてあるみたいな状態、純粋に全部BEMで書いてあるよりカオスな感じがしてきたので、この方法はやめました。設計的によろしくない気がします。さようならBEM。Reactの世界ではやはりいらなかった。 CSS in JSどれがいい選手権 そしたら必然的に選択肢として、CSS in JSにするかなー。あんまり乗り気ではないけど……と思うものの、どれを選んだら良いのかわからぬ。そもそもCSS in JSを選ぶこと自体に筆者はしっくり来ておりません。 CSS in JSどうなのよって思うポイントは色々ありました。 まず種類が多すぎるところ。なんかいっぱいあってどれが良いかよくわからんし、いちいち全部調べたくないんですが……というか。そもそもなんかそういう標準技術でもなんでも無いやつにCSSまるっと任せちゃうのが不安ってのもあります。2年後には無くなってそうだなーとか思っちゃいますね。 そして、そもそもJSでCSSを当てるというアプローチ自体どうなんですか?それイケてる実装なんですか?というのが全然しっくり来ない。昔はCSSが利用できない環境でも使えるようにとかあったけど、ああいうのはもう気にしなくていいの? 直にstyle書いちゃうのってなんかダメな理由無かったっけ? とかなんか色々モヤモヤが。 そんなCSS in JSに対するモヤモヤを解消するべく、なんか色々プレゼンを見たりなどしました。(まじめだな) 見た中で結構良かったやつは以下2つです。 この2つは結構わかりやすいかなーと思ったんで、まぁ興味ある人がいたらオススメです。 1つ目は、Styled Componentsを作ってる人のプレゼン、2つめは何かでかいカンファレンスでCSS in JSと素のCSSを比較してpros and consを話してるやつです。 まずStyled Componentsの人のプレゼンの方は、今に至るまでのCSS in JSの歴史みたいなものを紹介していて、今後どうなるかというのが話されてます。ざっくり内容をまとめると、 今のCSS in JSライブラリはお互いに真似し合ってて同じ様なAPIがある 今後どうなるかはみんなでアイデアを出し合っていこうね みたいな感じです。なんか個人的にはベストワンが知りたかったので、Styled Componentsがいいんだぜ的なノリを期待していたんですが、ライブラリ作ってる側としてもそうかーまぁ先のことは分からんよねということですね。そして、「どのライブラリも真似し合ってて大体同じなんすよね」みたいなことを言っていて、これには深く納得してしまいました。 この後、CSS in JSのコードを紹介していきますが、たしかにどれも似た感じで書けるんですよね。似てるっていうかほぼ同じAPIです。そしてどれも、基本的なCSSの書き方をそこそこリスペクトしたというか、あんまり飛び抜けたAPIにはしていない感じです。 なので、「JSでCSSを書く」っていうよりかは、「JSの中にフツーに書いたCSSを混ぜられる」って感じになってますね。自分の印象としては。このプレゼンを見た後に自分は色々試すんですが、どれを選んでも対して変わらんなというのを思ってます。 CSS in JSのメリット/デメリット CSS in JSを使うことのメリット/デメリットについてサラッと書いておきます。 まず1つ言えるのがscopedな感じにスタイルを当てられること。具体的にどういう感じかはこの後の例で紹介しますが、端的に言うと、さっきCSS ModulesがやってみせたことをJSでやる。ただそれだけです。なのでまぁCSS Modulesと同様、コンポーネント内でスコープを作った感じになります。これは当然、コンポーネント中心で設計するには大きなメリットといえます。 コンポーネント化されることで得られるメリットとして他に挙げられるのが、コンポーネントのスタイルが、そのコンポーネントのコードに内包されるというところです。BEMで書くと、100個のBEMブロックがあれば、そのCSSがグローバルな部分に突っ込まれたり、もしくは自分でうまいこと管理せねばならんですが、CSS in JSで書けば、Reactコンポーネントを書いた、そのJSファイルに内包される形にできるので、このコンポーネントが使われる時に初めて読み込ませる感じにしやすいです。シンプルにcode splittingが実現できます。 個人的に書いてみても、この「JSファイルの中にCSS書けちゃう」という点は、結構デカいと感じました。プレゼンの中では、こういう風にCSSを書けるから、ルールに沿わないCSSの書き方がそもそもできなくなるというような事を言ってたりしました。これは自分も大いに納得です。 どーでしょうか。BEMを理解してくれている人がいたとして、その人にBEMで書いてくださいと伝えても、どのCSSファイルにどうやって書くとかは別途考えねばならんのです。でもCSS in JSなら、フツーに書けばそのコンポーネントのJSファイルの中に書くことになります。こういうケースでは、サイト全体でCSSがカオスになるみたいなことが、そもそも起こらないぞってことなんです。この安心感は大きいですよ。 あとはまぁ、Reactはコンポーネントで考えるように指向して作られているので、その設計思想にも合ってるかなーという雰囲気を感じます。 メリットはそんなところで、デメリットとして挙げられるのは、 標準技術じゃないので寿命がよくわからん 再レンダリングのコストがかかる ランタイムでスタイルを当てることになる JSで混ざってごっちゃになりがち とかです。これら、どれも納得ではあるんですが、レンダリング周りについては、Next.jsとかGatsbyとかでSSG/SSRするようなアプローチでは、発生しない問題なんですよね。 SSGとは、乱暴に言うと、SPAの最初のレンダリング結果で作ったHTMLを作って返すという仕組みなので、CSS in JSで書いたコードは、JSに依存しない、ただのHTMLとCSSとしてブラウザは受け取ります。なので、CSS in JSとは言えども、SSGする上では別にJSが有効になっていなければ使えない訳ではないし、管理面のプラスが大きいので、CSS in JSでいいかなーという感じです。 CSS in JSでいいかなーというよりか、さっき書いたようなCSS Modulesの問題がCSS in JSでは発生しないので、どちらを選ぶかと言われればCSS in JSかなって感じです。あとは、JSの処理を気軽に混ぜられるのもいいですね。Sass scriptみたいなのをいちいち書きたくないですし、そんなのもはやいらんでしょという感じです。ありがとうさようならSass。まぁSassは使おうと思えば使えますが、Reactで書く上で、あえてSassを選ぶ理由はほとんど無いんじゃないでしょうか。 goober 「おうおう、じゃあそのCSS in JSとやら、見てやろうやないかい!」 ってことで、gooberというCSS in JSのライブラリ を使ってさっきのUIを書いたのが以下です。 App.js <GooberBlock src="https://placekitten.com/400/300"> <p>The quick brown fox...</p> <p>The quick brown fox...</p> <p>The quick brown fox...</p> </GooberBlock> goober-block.js import { css } from "goober"; const styles = { container: css` @media (min-width: 768px) { margin: 0 0 0 -40px; } `, inner: css` @media (min-width: 768px) { display: flex; width: 100%; } `, textWrapper: css` padding: 0 0 20px; @media (min-width: 768px) { padding: 0 0 0 40px; width: 50%; } > * + * { padding: 20px 0 0; } `, imgWrapper: css` @media (min-width: 768px) { padding: 0 0 0 40px; width: 50%; } `, img: css` display: block; width: 100%; `, }; export const GooberBlock = ({ children, src }) => ( <div className={styles.container}> <div className={styles.inner}> <div className={styles.textWrapper}>{children}</div> <div className={styles.imgWrapper}> <img className={styles.img} src={src} alt="" /> </div> </div> </div> ); 書いてる内容はCSS Modulesの時と大して変わんないんですが、コンポーネントのJSファイルの中にCSSが入ってる感じになってるのが分かるかと思います。 この結果どういうHTMLができるのかと言うと、こうです。 <div class="go2403310744"> <div class="go3735464671"> <div class="go1875143406"> <p>The quick brown fox...</p> <p>The quick brown fox...</p> <p>The quick brown fox...</p> </div> <div class="go2277549489"><img class="go2950335646" src="https://placekitten.com/400/300" alt=""></div> </div> </div> goうんたらという謎クラスがgooberが作ってくれるやつで、head要素内に以下が追加されます。 <style id="_goober"> @media (min-width: 768px) { .go2403310744 { margin: 0 0 0 -40px; } } @media (min-width: 768px) { .go3735464671 { display: flex; width: 100%; } } .go1875143406 { padding: 0 0 20px; } @media (min-width: 768px) { .go1875143406 { padding: 0 0 0 40px; width: 50%; } } .go1875143406 > * + * { padding: 20px 0 0; } @media (min-width: 768px) { .go2277549489 { padding: 0 0 0 40px; width: 50%; } } .go2950335646 { display: block; width: 100%; } </style> なるほどこれでコンポーネント内だけにスタイルを当てることが可能ということですね。gooberはTagged template literalで、生成したclassNameを返してくれるので、それをdivなりに指定すればスタイルを当てられます。 どーでしょう。これなら素でCSS書いてるのとあんまり変わらない感じでかけるし、スコープ化も実現されているのが分かるかと思います。 ちなみにNext.jsとかGatsbyなんかでSSGした場合、今紹介したHTMLとstyle要素がはじめっからHTMLファイル上に書き出された状態になってます。だから、CSS in JSってJS依存技術なんでしょ?って思っている方がいましたら、SSGする状況ではそれは誤解です。ランタイムでスタイルを当てるわけじゃないってことです。まーややこしい話ですが。 Styled ComponentsなAPI 次、またgooberです。 gooberには別のAPIも用意されていて、同じ内容を以下のように書くことができます。 App.js <GooberStyledBlock src="https://placekitten.com/400/300"> <p>The quick brown fox...</p> <p>The quick brown fox...</p> <p>The quick brown fox...</p> </GooberStyledBlock> goober-styled-block.js import React from "react"; import { styled, setup } from "goober"; setup(React.createElement); const Container = styled("div")` @media (min-width: 768px) { margin: 0 0 0 -40px; } `; const Inner = styled("div")` @media (min-width: 768px) { display: flex; width: 100%; } `; const TextWrapper = styled("div")` padding: 0 0 20px; @media (min-width: 768px) { padding: 0 0 0 40px; width: 50%; } > * + * { padding: 20px 0 0; } `; const ImgWrapper = styled("div")` @media (min-width: 768px) { padding: 0 0 0 40px; width: 50%; } `; const Img = styled("img")` display: block; width: 100%; `; export const GooberStyledBlock = ({ children, src }) => ( <Container> <Inner> <TextWrapper>{children}</TextWrapper> <ImgWrapper> <Img src={src} alt="" /> </ImgWrapper> </Inner> </Container> ); これは、たぶんStyled ComponentsのAPIを真似た書き方だと思います。 一つ前に紹介したやつは、あくまでclassNameを作るというものだったんですが、これはまぁなんというか、どうせ君らはclassNameを指定した要素が欲しいんだろ?ってことで、そこまでをまるっと実装したReactコンポーネントをチョチョイと作ってくれちゃう感じです。 さっき、CSS in JSはお互いに真似しあってるって書いたんですけど、そーなんです。これ、Styled Componentsっていう別の著名なCSS in JSのライブラリで採用されている書き方なんですが、この後紹介するEmotionでも、ほぼ同じ感じで書けるようになっています。 ぐはっ。なんか色々書き方があってCSS in JSめんどくせぇ〜〜 と思うかも知れませんが、まーそうですね……。筆者もそう思います。でも自分で書くぶんには1つ選んで使えばいいだけですし、大差無いので書いていけばすぐ慣れる感じではあると思いますよ。 まぁそんな感じで、CSS in JSでも色々な書き方が用意されてたりしますね。Sassで言えば、scss形式かsass形式かみたいな感じに思ってもらえればいいかなと。 ちなみに筆者はこのStyled Components式の書き方は選びませんでした。基本はTailwind CSSで書いていくことにしたので、classNameを指定してスタイルを当てていくやり方と親和性が薄いと感じたためです。どっちが良いとか悪いとか言う話ではなく、Tailwind CSSと組み合わせるにはイマイチかもなって感じです。 変数とかmixinとかそういうやつ さて、ここまでで色々と紹介してきたわけですが、SassとかPostCSSで書いてた時に使ってたほら、変数とかmixinとか使いたくなりません?なりますよね? あーなった。今なったよ。 ということで、gooberの中で、変数やmixin的なふるまいを書いてみたのが以下です。 App.js <GooberThemeBlock src="https://placekitten.com/400/300"> <p>The quick brown fox...</p> <p>The quick brown fox...</p> <p>The quick brown fox...</p> </GooberThemeBlock> theme.js const normalize = (remValue) => { return remValue.toFixed(4).replace(/\.?0+$/, ""); }; const toRem = (value) => { const px = parseInt(value); const rem = px / 16; return `${normalize(rem)}rem`; }; export const theme = { screen: { lg: `@media (min-width: 768px)`, }, fontSize: { sm: ` font-size: ${toRem("14px")}; line-height: 1.8; `, base: ` font-size: ${toRem("18px")}; line-height: 1.8; `, lg: ` font-size: ${toRem("22px")}; line-height: 1.8; `, xl: ` font-size: ${toRem("30px")}; line-height: 1.8; `, }, colors: { red: "#ff0000", green: "#00ff00", blue: "#0000ff", }, spacing: { xs: toRem("3px"), sm: toRem("5px"), md: toRem("10px"), lg: toRem("20px"), xl: toRem("40px"), "2xl": toRem("60px"), }, }; import { css } from "goober"; import { theme } from "../theme"; const styles = { container: css` ${theme.screen.lg} { margin: 0 0 0 -${theme.spacing.xl}; } `, inner: css` ${theme.screen.lg} { display: flex; width: 100%; } `, textWrapper: css` padding: 0 0 ${theme.spacing.lg}; ${theme.screen.lg} { padding: 0 0 0 ${theme.spacing.xl}; width: 50%; } > * + * { padding: ${theme.spacing.lg} 0 0; } `, imgWrapper: css` ${theme.screen.lg} { padding: 0 0 0 ${theme.spacing.xl}; width: 50%; } `, img: css` display: block; width: 100%; `, }; export const GooberThemeBlock = ({ children, src }) => ( <div className={styles.container}> <div className={styles.inner}> <div className={styles.textWrapper}>{children}</div> <div className={styles.imgWrapper}> <img className={styles.img} src={src} alt="" /> </div> </div> </div> ); theme.jsは、単純にひとつのobjectをexportしてるだけ。色だの文字サイズだの余白だのをまとめ、その中でpxをremに変換したりもしてるんです。これ、別になんかすごいことをしてるわけじゃないです。gooberではCSSとして評価される文字列を作ればいいので、使いまわしたい文字列をまとめとこうぜってだけですね。 どーですか?結構便利じゃないですか?これ。弊社内で、CSS in JSどう書いてるみたいな話をしてたらこう書いたってのを教えてもらったんですが。結構シンプルでしょう? しかしこれ、めっちゃ変数だらけになりますよね。 でもこうなるのって必然だと思うんです。サイト内で何度も共通使用される数値なり色なりを共通化するのって。 Tailwind CSSで書くとこう 次に紹介するのはなんと、じゃじゃーん。 やっとのことでTailwind CSSというフレームワークです。 「フレームワーク」です。ここポイントです。 今みたいな共通化は一旦おいておいて、例のUIをTailwind CSSで書くとこうです。 App.js <TailwindBlock src="https://placekitten.com/400/300"> <p>The quick brown fox...</p> <p>The quick brown fox...</p> <p>The quick brown fox...</p> </TailwindBlock> App.js export const TailwindBlock = ({ children, src }) => ( <div className="lg:ml-[-40px]"> <div className="lg:flex w-full"> <div className=" pb-[20px] space-y-[20px] lg:pl-[40px] lg:w-1/2 "> {children} </div> <div className="lg:pl-[40px] lg:w-1/2"> <img className="block w-full" src={src} alt="" /> </div> </div> </div> ); な、なんて短さ……!CSSはどこいった?って感じなんですが、とりあえず、ここまでであえてスルーしてた、JITモードについて少し触れておきます。JITモードっていうのはこれです。 v2.1にプレビュー版として実装された機能で、ちょっぱやでコンパイルできるやつなんですが、これをオンにすると、pb-[20px]とか、括弧で囲むと、その値が指定されたCSSルールを柔軟に作ってくれます。これで書けばとりあえずその値で好きにお手軽にスタイルが当てられる感じですよ。Tailwind CSSではArbitrary value supportとか呼んでます。以下に例があります。 このAribitary valueで書くことを想定されているのは、そこだけ取り立ててユニークな値とかですね。たとえば、余白は基本30pxにしてるんだけど、1px分ボーダーがあるので29pxにしたいとか、あとは何かアイコンが飛びてて、その飛び出てる距離がそこだけ固有の34pxとかそういうやつです。 最初の話に戻りますけど、デザインにこだわりがある場合に使えないとか言ってる人のは、この機能をきっと知らないですよね?まぁv2.1ではまだプレビューなんですが、このまま入るのはほとんど間違いないかと思います。とりあえずこれで好きな値でもサクサクかけたりするわけです。 Tailwindで変数とかmixinとかヤツ さて、ここからが本題なんですが、Tailwind CSSで、さっきgooberのコードで変数なりを使ったやつを再現するとこうなります。 App.js <TailwindThemeBlock src="https://placekitten.com/400/300"> <p>The quick brown fox...</p> <p>The quick brown fox...</p> <p>The quick brown fox...</p> </TailwindThemeBlock> tailwind.config.js const normalize = (remValue) => { return remValue.toFixed(4).replace(/\.?0+$/, ""); }; const toRem = (value) => { const px = parseInt(value); const rem = px / 16; return `${normalize(rem)}rem`; }; module.exports = { mode: "jit", purge: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"], darkMode: false, // or 'media' or 'class' theme: { extend: { screens: { lg: "768px", }, fontSize: { sm: [toRem("14px"), "1.8"], base: [toRem("18px"), "1.8"], lg: [toRem("22px"), "1.8"], xl: [toRem("30px"), "1.8"], }, colors: { red: "#ff0000", green: "#00ff00", blue: "#0000ff", }, spacing: { xs: toRem("3px"), sm: toRem("5px"), md: toRem("10px"), lg: toRem("20px"), xl: toRem("40px"), "2xl": toRem("60px"), }, }, }, }; tailwind-theme-block.js export const TailwindThemeBlock = ({ children, src }) => ( <div className="lg:-ml-xl"> <div className="lg:flex w-full"> <div className=" pb-lg space-y-lg lg:pl-xl lg:w-1/2 "> {children} </div> <div className="lg:pl-xl lg:w-1/2"> <img className="block w-full" src={src} alt="" /> </div> </div> </div> ); Tailwind CSSって、コンフィグファイルに色々さっきやってたような変数なりを定義し、それがそのままユーティリティークラスになるって感じなんですよ。 この場合だと例えばpb-lgとかいうクラスがありますが、これはコンフィグのspacing.lgとして指定されているtoRem("20px")を参照し、padding-botto: 1.25remになるって感じですね。 こんな風に、Tailwind CSSは、さっきみたいな、デザインシステム的なアプローチがbuilt inなんです。というかむしろ、先にそれがあったんですが、そこでなお、ユニークな値もカバーできるようにJITモードみたいのが加わった感じですね。gooberでほとんど同じことしてますよね? だから、どうせこういうことをするならTailwind CSSを選んでおいたら良いんじゃない?って思うのです。 Tailwind CSSは、そもそもCSS in JSとはちょっと毛色が違いまして、ユーティリティークラスを作る「フレームワーク」なんですよ。 An API for your design system 筆者はこのTailwind CSSが好きで、なんで好きなのかっていうところなんですが、それはこの、 デザインシステムを定義する それを使って画面を作っていく というアプローチをベースにしているからなんですよね。 Taiwind CSSは凝ったデザインに向かないみたいなことをいう人はきっとこうなんでしょう。 「好きにCSSを書くにはいちいちコンフィグをいじらないといけない」 「へんなユーティリティークラスも覚えないといけないし不便なだけでしかない」 「決まった値で作るだけのデザインのこだわりのないサイトなら向いてるんじゃない?」 いやーーちょっとまって〜 お前は何も分かっていない…… Tailwind CSSのことを1mmも分かっていない! と思うわけなんですよね〜〜〜 Tailwind CSSのアプローチは、基本的に用意したユーティリティークラスで組んでいき、その中で例外的にユニークな値を使うということなんですよね。これは束縛です。トップページに書いてあるんですが。 constraint-based An API for your design system. って。これはなかなかいいキャッチコピーだと思いますよ。「制限ベース」「あなたのデザインシステムのAPI」なんですよ。 この制限を「凝ったデザインには向いていない」と感じするその感覚。なんかそれが、あーこの人はデザインに興味ないねって感じてしまいますね〜〜筆者的には。 そんな事言われても現実の仕事では無理じゃん? そ~いうことを書くとですね、あー意識高い人なのねみたいな風に思われるんですが。 「いやーTakazudoさんのおっしゃりたいことは分かりますよ」 「でも私がやってる仕事ってそういうやつじゃないんですよね〜〜」 って。いやーね、デザインの工程と実装の工程は2つで1つなんですよ。余白が揃ってなかったら揃えるし、色がブレてたらまとめるみたいな役割は考えないんですかね? デザインカンプで1pxずれてたら、それをそのまま愚直にCSSに書いちゃうんですか? それがこだわってるデザインだとでも? こだわりがないのはあんたのCSS設計だろー?って。 というわけで、私がTailwind CSSは凝ったデザインに向かないみたいな呟きを見て「は?何いってんの?」と思ったのはそういう理由です。Tailwind CSSが凝ったデザインに向いていないなんていうことは1mmも無い。むしろ、凝ったデザインをうまく実現することを指向して作られていて、あんたはその事に気付いてすらいない。のだ。 まぁ、私が誰かに実装を頼むとしたらそういうところまで見てCSS設計をして欲しいですね。それはそこそこ難しいことは分かっていて書いてますが。 めちゃくちゃclass長くて読みづらいんだけど まー私の個人的な意見はそのくらいにしておくとして、ここで2つほど、Tailwind CSSで書くとここが辛いみたいなのを緩和するTips的な話を2つします。 まず1つ目はクラス名について。 Tailwind CSSで書いていると、className長すぎでやってらんないんだけどと思われることはあると思います。こんな感じ。 <button type="button" className="relative w-1/2 bg-white border-gray-200 rounded-md shadow-sm py-2 text-sm font-medium text-gray-900 whitespace-nowrap focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:z-10 sm:w-auto sm:px-8" > まぁ確かにわからんし嫌になるなというのは分かります。 そういう場合には自分はこうしてます。 <button type="button" className=" relative py-2 w-1/2 sm:w-auto sm:px-8 text-gray-900 bg-white text-sm font-medium whitespace-nowrap border-gray-200 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:z-10 " > なんとなく関わりがあるプロパティ毎に纏めとく感じですね。テキスト周り、幅関係、フォーカス時の処理とかそういう感じで。class属性値に改行とかホワイトスペースとか混ざりまくってていいわけ?ってちょっと気になって調べたんですが、仕様的には問題無さそうです。 それと、Netlifyで、Tailwind CSSを使ってリニューアルしたぞって話があって、 その中で紹介されている@netlify/classnames-template-literalsがいい感じです。 以下みたいに書くと、 import ctl from "@netlify/classnames-template-literals"; const Button = ({ active=false }) => { const buttonClasses = ctl(` bg-black text-white p-1 rounded-sm ${active && 'border border-pink-600`} `); return <button className={buttonClasses}>Go!</button>; } activeがtrueがfalseな時に、buttonClasssesにfalseだとかundefinedだとかが混ざってきたりしてめんどくさいんですが、このctlは、それをpurgeして、余分なホワイトスペース/改行を詰めてくれます。Tailwind CSSのオトモにおすすめです。 そもそもややこしいCSSはコンポーネント分割して良いのでは もひとつ。コンポーネントの書き方についてです。 Tailwind CSSとは直接的に関係無いんですが、こうやってReactコンポーネントでかける環境下に置いて、スモールスクリーン時/ワイドスクリーン時で大きくレイアウトが変わるUIを、mediaquery達人芸みたいな方法で組むのはわかり辛いのでは?というのも考えました。 例えば例のUIは以下のようにも書けます。 App.js <TailwindSeparateBlock src="https://placekitten.com/400/300"> <p>The quick brown fox...</p> <p>The quick brown fox...</p> <p>The quick brown fox...</p> </TailwindSeparateBlock> App.js const VerticalBlock = ({ children, src, className }) => ( <div className={className}> <div className="pb-lg space-y-lg">{children}</div> <img className="block w-full" src={src} alt="" /> </div> ); const HorizontalBlock = ({ children, src, className }) => ( <div className={`-ml-xl ${className}`}> <div className="flex w-full"> <div className="pb-lg space-y-lg pl-xl w-1/2">{children}</div> <div className="pl-xl w-1/2"> <img className="block w-full" src={src} alt="" /> </div> </div> </div> ); export const TailwindSeparateBlock = (props) => ( <> <VerticalBlock className="lg:hidden" {...props} /> <HorizontalBlock className="hidden lg:block" {...props} /> </> ); CSS Grid Layoutを使えばもっと短く書けるぜ?みたいのはあるとは思うんですけど、単純にスクリーンサイズで大きくレイアウトが変わる場合、mediaqueryを使ってあれやこれやを打ち消したりなどするよりか、バッサリ分割してしまったほうが見やすいかとか思ったんですがどうでしょう。なんかアクセシビリティ上の問題とかあるかな?とか考えたけど思いつかなかったので。 コンポーネントの振る舞いというかインターフェースというか、そういう部分は、こういう風に分割されていようと無かろうと変わらないので、こういう書き方法がわかりやすいかな?と思ったのですがどうでしょう。いやそれはまずいぜみたいな事があれば教えていただけるとありがたいです。 まーこう書いたほうが良いんじゃないというよりかは、こう書いてもアリかな?って思ったのでこの記事の内容として混ぜました。 Tailwind CSSで書き辛いヤツら さて、まぁそんなわけでTailwind CSSで書くのが良いというか、CSS in JSなどで書いていっても、最終的にはTailwind CSSのコンフィグのようなしくみを自作することになるであろう故、Tailwind CSSを俺は選ぶぜというのが筆者の技術選択なんですが、最初の方でちょっと触れたように、Tailwind CSSではどうにも書き辛いというのがあります。 それは、WYSIWYGで入力されたHTMLや、markdownをコンバートして作られたHTMLを混ぜるときです。 そういうHTMLはこういう感じになるでしょう。 <h2>heading</h2> <p>paragraph paragraph paragraph...</p> <h3>heading</h3> <p>paragraph paragraph paragraph...</p> <p>paragraph paragraph paragraph...</p> <ol> <li>list</li> <li>list</li> </ol> <p>paragraph paragraph paragraph...</p> ウッ…… classNameが指定できない…… それはそうですね。コンポーネントの中にこういうコードを突っ込む場合、これ、どういうふうにCSSを書きます?フツーに考えれば、子供セレクタとか子孫セレクタでスタイルを当てるんじゃないでしょうか。こんな風に。 .richtext h2 { font-size: ...; padding: ...; } .richtext h3 { font-size: ...; padding: ...; } .richtext p { padding: ...; } Tailwind CSSだとこういうのはできないんですよね。残念ながら。どうしよう。 自分はこういう箇所にだけCSS in JSを使うことにしました。さっきのgooberでやったようにです。しかし、そうすると、Tailwind CSSのコンフィグに定義した諸々を活かしづらいです。そこで便利なのがtwin.macroというちょっとしたライブラリです。 これは何かって言うと、CSS in JSの処理の中にTailwind CSSのユーティリティークラスを混ぜられるというモノです。コードを見たほうが速いので、コードを紹介しましょう。こんな感じです。 App.js <WysiwygBlock src="https://placekitten.com/400/300"> <h2>The quick brown fox</h2> <p>The quick brown fox...</p> <h3>The quick brown fox</h3> <p>The quick brown fox...</p> <ol> <li>The quick brown fox jumps over the lazy dog. </li> <li>The quick brown fox jumps over the lazy dog. </li> <li>The quick brown fox jumps over the lazy dog. </li> </ol> <p>The quick brown fox...</p> <ul> <li>The quick brown fox jumps over the lazy dog. </li> <li>The quick brown fox jumps over the lazy dog. </li> <li>The quick brown fox jumps over the lazy dog. </li> </ul> </WysiwygBlock> 今回はWYSIWYGのコードが突っ込まれるという想定で、Reactコンポーネントは、そんな要素らを受け取ると想定します。 以下、childrenが突っ込まれるdivをルートとし、Emotionでスタイルを当てます。 wysiwyg-block.js import { css } from "@emotion/css"; import tw from "twin.macro"; const richtext = css` h2 { ${tw`text-xl`} ${tw`pb-md`} } h3 { ${tw`text-lg`} ${tw`pb-md pt-md`} } p { ${tw`pb-lg`} } ul { ${tw`ml-xl list-disc`} ${tw`space-y-sm pb-lg`} } ol { ${tw`ml-xl list-decimal`} ${tw`space-y-sm pb-lg`} } `; const Small = ({ children, src, className }) => ( <div className={className}> <div className={`pb-lg ${richtext}`}>{children}</div> <img className="block w-full" src={src} alt="" /> </div> ); const Large = ({ children, src, className }) => ( <div className={`-ml-xl ${className}`}> <div className="flex w-full"> <div className={`pb-lg pl-xl w-1/2 ${richtext}`}> {children} </div> <div className="pl-xl w-1/2"> <img className="block w-full" src={src} alt="" /> </div> </div> </div> ); export const WysiwygBlock = (props) => ( <> <Small className="lg:hidden" {...props} /> <Large className="hidden lg:block" {...props} /> </> ); twin.macroからimportしているtwというTagged functionが、Tailwind CSSのクラスを評価し、その内容を展開してくれるやつです。これを使うことにより、CSS in JSで書きつつも、その中でTailwind CSSのユーティリティーを使うというマジックが実現できます。 twin.macroは主にStyled ComponentsとEmotionに対応しているので、筆者は@emotion/cssを使うことにしました。 Emotionは、端的に言って、さっきのgooberと同じ感じです。Emotionを使うにも色々なAPIが用意されていて選択肢が色々あるんですが、webpack依存がイヤだしclassName管理に合ってるということで、@emotion/css を選びました。この構成なら、twin.macroはnpm installしてimportするだけで使える気がします。たぶん。 これでTailwind CSSで書きつつ、書き辛いコンポーネントもなんとか打倒することができました。BEMコンポーネントがゼロ、全てのスタイルはそれぞれのコンポーネントの中に閉じ込められました。CSS in JSの役割もclassName作ってくれるだけにとどめました。やった! ちなみにtwin.macroやさっき紹介したNetlifyのctlでTailwind CSSのクラスを使うと、VSCodeが補完してくれないんですが、以下設定をすればできるのでVSCodeの人はやるといいです。 とりたててユニークなUI Tailwind CSSで書きづらいなーというのがもう一つ。それは、とりたててユニークな見た目をしているUIです。そのデモを作ってみました。こんな感じです。 なんというか、数値的に具体的に何ピクセルとか何%とか、ここでしか使わない値がボンボン出てきて、className="って書こうとして手が止まる感じのヤツです。 こういうのは、そう思った時点でもう諦めて最初からCSS in JSで書くと良いよって思って自分でも書いてみたんですが、JITモードオンであれば、そこそこTailwind CSSでも書けますね。こんな感じになりました。 App.js <ComplicatedBlock /> complicated-block.js import { css } from "@emotion/css"; const styles = { gradient1: css` background: rgb(34, 193, 195); background: linear-gradient( 0deg, rgba(34, 193, 195, 1) 0%, rgba(253, 187, 45, 1) 100% ); `, gradient2: css` background: rgb(63, 94, 251); background: radial-gradient( circle, rgba(63, 94, 251, 1) 0%, rgba(252, 70, 107, 1) 100% ); `, gradient3: css` background: rgb(238, 174, 202); background: radial-gradient( circle, rgba(238, 174, 202, 1) 0%, rgba(148, 187, 233, 1) 100% ); `, shadow: css` box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px; `, }; export const ComplicatedBlock = () => ( <div className=" relative pb-[20px] mb-[20px] lg:mb-[50px] " > <div className={` mx-auto w-full lg:w-[80%] h-[200px] lg:h-[300px] ${styles.gradient2} ${styles.shadow} `} ></div> <div className={` absolute w-[20%] h-[180px] left-0 bottom-0 hidden lg:block ${styles.gradient1} ${styles.shadow} `} ></div> <div className={` absolute w-[20%] h-[180px] right-0 bottom-0 hidden lg:block ${styles.gradient3} ${styles.shadow} `} ></div> <p className=" absolute top-[40px] right-0 left-0 text-5xl lg:text-7xl font-bold text-center " > Drink Bar is <br /> 299 Yen </p> </div> ); 自分が書いたやり方としては、基本classNameで指定していって、なんかめんどくさそうなやつはCSS in JSの方でやるという感じです。こういうgradientとかって、以下みたいなサイトで作ったりしませんか? そういうのはTailwind CSSの土台に乗せると若干めんどくさいので、こんな風に部分的にCSS in JSでclassNameを作るのが良いかなーと思ってます。あとは次に話す、Tailwind CSSのユーティリティークラスとして自分で追加するかが良いかなと思います。 Tailwind CSSをもうちょい突っ込んで使う ハイ。 そんな感じで、Tailwind CSS8割+2割emotion + twin.macroがいいんではないかなーという結論に今のところはなった自分ですが、そうは言ってもなるべくTailwind CSSで完結させようと、ここまでで触れていないTailwind CSSの機能を試したりしました。それらについても少し触れておきます。 ユーティリティクラスの追加 Tailwind CSSのコンフィグにて、完全オリジナルのユーティリティクラスを追加することが出来ます。以下に書いてあるやつです。 これは、前述した、グラデーションやbox-shadowを共通化する時に使いました。 スモールスクリーン時にだけ表示させる ワイドスクリーン時にだけ表示させる 段階的にフォントサイズを大きくさせる みたいのを作ろうと思ったんですが、ユーティリティを定義する中で、他のユーティリティーを呼ぶやり方がよく分からなかったので断念しました。Tailwind CSSに最初から含まれているユーティリティークラスらは、このAPIを使って書かれている ので、あんまりこう、ユーティリティ同士を組み合わせるような想定では無いのかな?と感じました。できるかも知れないんですが、複雑だしちょっと面倒そうかなと。なので、グラデやbox-shadowとかの、単独で完結しているものらに使うと良さそうです。 コンポーネントの追加 Tailwind CSSでは、ボタンとかのちっさな粒度のCSSルールのまとまりをコンポーネントとして登録できるようになってるんですが、これも使おうとしましたが結局やめました。 なんかこれは、コンフィグの中に書くんですけど、ここで定義するには、いちいち全部JSのオブジェクト形式にしないといけなくて、その時点で書くのがめんどくさいなーという印象です。そして、ここでも他のユーティリティーを使えるのかよくわからず、たとえ使えたとしても、そこまでしたらもはやそれはReactコンポーネントでやるべきであろうと感じたので、少なくともReactで実装するようなプロジェクトでは、この機能を使うことはなかろうと思われました。 疑似要素 ::beforeとか::afterとかでなんかデコりたい時、Tailwind CSSだと書きづらいという問題があります。これは一応解決法があります。そういう記法を有効にするプラグインがあって、それを使うというものです。 これを使えば<li className="before:empty-content">...</li>とかいうノリで書けるらしいんですが、自分はこれはやめて、ただspanを突っ込むことにしました。 今回記事を書くに際し調べたんですが、空っぽのspanを使ってもアクセシビリティ上問題ないみたいです。 筆者的には、疑似要素だろうとspanだろうと大して変わらないのであれば、spanの方が分かり安かろうという判断です。Reactコンポーネントの振る舞い/インターフェースとしては同じだし、疑似要素でデコるのもspanでデコるのも、CSSの表現力を補完するための方法が異なるだけで、どんぐりの背比べかなと思ったため。 子供セレクタ WYSIWYGのところで、そこだけCSS in JSを使うと書きましたが、> *をclassName="children:..."と書けるようになるプラグインがあります。 これは使うかもと思ったんですが、結局使う機会がありませんでした。例えばliを繰り返すような状況は、大抵Reactコンポーネントの内外でArrayにしてからループするので、わざわざ子供セレクタを使ってもややこしくなるだけで、かといってWYSIWYGのように子供のバリエーションが多いと今度はそれだけでは足りなくなるので、結局使わないで終わりました。 あと、あんまり野良のTaiwind CSSプラグインを増やしてしまうと、PostCSSのよくわからんプラグインを増やすみたいで、俺の考えた最強のTailwind感が強くなってよろしくないかと考えました。どうしても子供セレクタを使いたいという時はCSS in JSでやるかなって感じです。 最後に 以上で筆者TakazudoがGatsby上でCSSどうするかを考えた話は終わりです。 Tailwind CSSは、ユーティリティーファーストで画面を実装するためのフレームワークなんで、そのへんを理解して使うと違うんではないでしょうか。 あと、多分特にWeb制作界隈の方は、この記事を読んで、「私はHTMLとCSS書いてるけど使う気機会が無さそうだな」とか思ってしまう方が多いみたいなのですが、いや〜〜自分から何もアクションせず、Tailwind CSSを使うような機会は、この業界でフツーに働いていても、ほとんどの人に訪れないんじゃないかなーと思います。Tailwind CSSがものすごいメジャーなものとならない限り。 この技術を使えば○○が効率的にできる、○○の問題を解決できると考え、自分から動いてアクションした結果、そういう仕事が依頼されたり、高い給与で雇われたり、高品質なWebサイトやWebサービスが完成するだけではないですか? そういうマインドセットがいいんじゃないかなーと筆者は考えております。筆者的にはもう手作りでHTMLを増やしていくのはやめたく、それができるようになったなーって感じてます。 筆者は普段は受託開発をしていてCodeGridというところで記事を書いていたりするので、よろしければよろしくどうぞ。 CodeGrid 株式会社ピクセルグリッド
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む