フロントエンドプロジェクトの一般的なCSSの問題

公開: 2022-03-10
クイックサマリー↬レンダリングとインタラクションは、近年、ブラウザ間ではるかに一貫性があります。 ただし、まだ完全に均一ではなく、小さな問題がたくさんあると、つまずく可能性があります。 これらの問題に加えて、さまざまな画面サイズ、言語設定、および単純な人為的エラーの変数を追加すると、開発者をつまずかせる小さなことがたくさん見つかります。

ブラウザにユーザーインターフェイスを実装するときは、UIを予測できるように、可能な限りこれらの違いや問題を最小限に抑えることをお勧めします。 これらすべての違いを追跡するのは難しいので、新しいプロジェクトに取り組んでいるときの便利なリファレンスガイドとして、一般的な問題のリストとその解決策をまとめました。

さぁ、始めよう。

1. buttoninput要素の背景をリセットします

ボタンを追加するときは、背景をリセットしてください。そうしないと、ブラウザによって外観が異なります。 以下の例では、同じボタンがChromeとSafariに表示されています。 後者はデフォルトの灰色の背景を追加します。

(大プレビュー)

背景をリセットすると、この問題が解決します。

 button { appearance: none; background: transparent; /* Other styles */ } 

CodePenのAhmadShadeed(@shadeed)によるペンボタンと入力を参照してください。

CodePenのAhmadShadeed(@shadeed)によるペンボタンと入力を参照してください。
ジャンプした後もっと! 以下を読み続けてください↓

2.オーバーフロー: scrollauto

要素の高さを制限し、ユーザーが要素内をスクロールできるようにするには、 overflow: scroll-y 。 これは、macOS上のChromeで見栄えがします。 ただし、Chrome Windowsでは、スクロールバーは常に表示されます(コンテンツが短い場合でも)。 これは、 scroll-yはコンテンツに関係なくスクロールバーを表示するのに対し、 overflow: autoは必要な場合にのみスクロールバーを表示するためです。

左:macOS上のChrome。 右:Windows上のChrome。 (大プレビュー)
 .element { height: 300px; overflow-y: auto; } 

CodePenのAhmadShadeed(@shadeed)によるペンオーバーフロー-yを参照してください。

CodePenのAhmadShadeed(@shadeed)によるペンオーバーフロー-yを参照してください。

3. flex-wrapを追加します

display: flexを追加するだけで、要素をフレックスコンテナとして動作させることができます。 ただし、画面サイズが縮小すると、 flex-wrapが追加されていない場合に備えて、ブラウザに水平スクロールバーが表示されます。

 <div class="wrapper"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div>
 .wrapper { display: flex; } .item { flex: 0 0 120px; height: 100px; }

上記の例は、大画面でうまく機能します。 モバイルでは、ブラウザに水平スクロールバーが表示されます。

左:水平スクロールバーが表示されており、アイテムは折り返されていません。 右:アイテムは2行に折り返されています。 (大プレビュー)

解決策は非常に簡単です。 ラッパーは、スペースが利用できない場合、アイテムをラップする必要があることを認識している必要があります。

 .wrapper { display: flex; flex-wrap: wrap; } 

CodePenのAhmadShadeed(@shadeed)によるペンフレックスラップを参照してください。

CodePenのAhmadShadeed(@shadeed)によるペンフレックスラップを参照してください。

4. justify-content: space-betweenを使用しないでください。Flexアイテムの数が動的である場合

justify-content: space-betweenがフレックスコンテナに適用されると、要素が分散され、要素間に同じ量のスペースが残されます。 この例には8つのカードアイテムがあり、見栄えがします。 なんらかの理由でアイテム数が7だったら? 要素の2行目は、最初の行とは異なって見えます。

8つのアイテムを持つラッパー。 (大プレビュー)
7つのアイテムを持つラッパー。 (大プレビュー)

CodePenのAhmadShadeed(@shadeed)によるPenjustify-contentを参照してください。

CodePenのAhmadShadeed(@shadeed)によるPenjustify-contentを参照してください。

この場合、CSSグリッドを使用する方が適しています。

5.長い言葉とリンク

記事がモバイル画面で表示されているときに、長い単語またはインラインリンクが原因で、水平スクロールバーが表示される場合があります。 CSSのword-breakを使用すると、それが発生するのを防ぐことができます。

大きなプレビュー
.article-content p { word-break: break-all; } 
(大プレビュー)

詳細については、CSS-Tricksを確認してください。

6.透明なグラデーション

開始点と終了点が透明なグラデーションを追加すると、Safariでは黒っぽく見えます。 これは、Safariがキーワードtransparentを認識しないためです。 rgba(0, 0, 0, 0)に置き換えると、期待どおりに機能します。 以下のスクリーンショットに注意してください。

上:Chrome70。下:Safari 12.(大きなプレビュー)
 .section-hero { background: linear-gradient(transparent, #d7e0ef), #527ee0; /*Other styles*/ }

代わりに、これは次のようになります。

 .section-hero { background: linear-gradient(rgba(0, 0, 0,0), #d7e0ef), #527ee0; /*Other styles*/ }

7.CSSグリッドauto-fill auto-fitの違いに関する誤解

CSSグリッドでは、 repeat関数を使用すると、メディアクエリを使用せずにレスポンシブな列レイアウトを作成できます。 これを実現するには、 auto-fillまたはauto-fitのいずれかを使用します。

 .wrapper { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); } 
(大プレビュー)

つまり、 auto-fillは幅を拡張せずに列を配置しますが、 auto-fit調整は列をゼロ幅に折りたたむが、空の列がある場合のみです。 Sara Soueidanは、このトピックに関する優れた記事を書いています。

8.ビューポートの高さが十分でない場合に要素を画面の上部に固定する

画面の上部に要素を固定した場合、ビューポートの高さが十分でない場合はどうなりますか? シンプル:画面スペースを占有するため、ユーザーがWebサイトを閲覧できる垂直方向の領域が小さく不快になり、エクスペリエンスが低下します。

 @media (min-height: 500px) { .site-header { position: sticky; top: 0; /*other styles*/ } }

上記のスニペットでは、ビューポートの高さが500ピクセル以上の場合にのみ、ヘッダーを上部に固定するようにブラウザに指示しています。

また重要: position: stickyを使用する場合、 topプロパティを指定しないと機能しません。

大きなプレビュー

CodePenのPenVerticalメディアクエリ:Ahmad Shadeed(@shadeed)による固定ヘッダーを参照してください。

CodePenのPenVerticalメディアクエリ:Ahmad Shadeed(@shadeed)による固定ヘッダーを参照してください。

9.画像max-width設定

画像を追加するときは、 max-width: 100%を定義して、画面が小さいときに画像のサイズが変更されるようにします。 それ以外の場合、ブラウザには水平スクロールバーが表示されます。

 img { max-width: 100%; }

asideグリッドを使用してmain要素とサイド要素を定義する

CSSグリッドを使用して、レイアウトのmainセクションとasideセクションを定義できます。これは、グリッドの最適な使用法です。 その結果、 asideのセクションの高さは、空であってもmain要素の高さと同じになります。

これを修正するには、 aside要素をその親の先頭に揃えて、高さが拡張しないようにします。

 .wrapper { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-gap: 20px; } // align-self will tell the aside element to align itself with the start of its parent. aside { grid-column: 1 / 4; grid-row: 1; align-self: start; } main { grid-column: 4 / 13; } 
(大プレビュー)

CodePenのAhmadShadeed(@shadeed)によるペンのメインと脇を参照してください。

CodePenのAhmadShadeed(@shadeed)によるペンのメインと脇を参照してください。

11.SVG fillを追加する

SVGで作業しているときに、SVGにfill属性がインラインで追加されていると、 fillが期待どおりに機能しない場合があります。 これを解決するには、SVG自体からfill属性を削除するか、 fill: colorオーバーライドします。

この例を見てください:

 .some-icon { fill: #137cbf; }

SVGにインラインフィルがある場合、これは機能しません。 代わりにこれである必要があります:

 .some-icon path { fill: #137cbf; }

12.疑似要素の操作

できる限り疑似要素を使用するのが大好きです。 これらは、HTMLに追加せずに、主に装飾目的で偽の要素を作成する方法を提供します。

それらを操作するとき、作成者は次のいずれかを実行するのを忘れる可能性があります。

  • content: ""プロパティ、
  • displayプロパティを定義せずにwidthheightを設定します。

以下の例では、疑似要素としてバッジが付いたタイトルがあります。 content: ""プロパティを追加する必要があります。 また、要素にはdisplay: inline-blockを設定して、 widthheightを期待どおりに機能させる必要があります。

大きなプレビュー

13. display: inline-block

2つ以上の要素をdisplay: inline-blockまたはdisplay: inlineは、それぞれの間に小さなスペースを作成します。 ブラウザが要素を単語として解釈し、各要素の間に文字スペースを追加するため、スペースが追加されます。

以下の例では、各アイテムの右側に8pxのスペースがありますが、 display: inline-blockを使用することによって生じる小さなスペースにより、 12pxになります。これは、望ましい結果ではありません。

 li:not(:last-child) { margin-right: 8px; } 
(大プレビュー)

これに対する簡単な修正は、親要素にfont-size: 0を設定することです。

 ul { font-size: 0; } li { font-size: 16px; /*The font size should be reassigned here because it will inherit `font-size: 0` from its parent.*/ } 
(大プレビュー)

CodePenのAhmadShadeed(@shadeed)によるペンインラインブロック間隔を参照してください。

CodePenのAhmadShadeed(@shadeed)によるペンインラインブロック間隔を参照してください。

14.入力にラベル要素を割り当てるときにfor="ID"を追加します

フォーム要素を操作するときは、すべてのlabel要素にIDが割り当てられていることを確認してください。 これにより、アクセスしやすくなり、クリックすると、関連する入力にフォーカスが移ります。

 <label for="emailAddress">Email address:</label> <input type="email"> 
大きなプレビュー

15.インタラクティブなHTML要素で機能しないフォント

ドキュメント全体にフォントを割り当てる場合、フォントはinputbuttonselecttextareaなどの要素には適用されません。 ブラウザがデフォルトのシステムフォントを適用するため、デフォルトでは継承されません。

これを修正するには、fontプロパティを手動で割り当てます。

 input, button, select, textarea { font-family: your-awesome-font-name; }

16.水平スクロールバー

一部の要素では、それらの要素の幅が原因で、水平スクロールバーが表示されます。

この問題の原因を見つける最も簡単な方法は、CSSアウトラインを使用することです。 Addy Osmaniは、ページ上のすべての要素の概要を示すためにブラウザコンソールに追加できる非常に便利なスクリプトを共有しています。

 [].forEach.call($$("*"), function(a) { a.style.outline = "1px solid #" + (~~(Math.random() * (1 << 24))).toString(16); }); 
(大プレビュー)

17.圧縮または引き伸ばされた画像

CSSで画像のサイズを変更するときに、アスペクト比が画像の幅と高さと一致しない場合は、画像が圧縮または拡大される可能性があります。

解決策は簡単です。CSSのobject-fitを使用します。 その機能は、 background-size: coverです。

 img { object-fit: cover; } 
(大プレビュー)

object-fitを使用することは、すべての場合において完璧な解決策ではありません。 一部の画像はトリミングやサイズ変更なしで表示する必要があり、一部のプラットフォームでは、ユーザーは定義されたサイズで画像をアップロードまたはトリミングする必要があります。 たとえば、Dribbbleは、800 x600ピクセルのサムネイルのアップロードを受け入れます。

18. input用の正しいtypeを追加します。

inputフィールドには正しいtypeを使用してください。 これにより、モバイルブラウザのユーザーエクスペリエンスが向上し、ユーザーがよりアクセスしやすくなります。

ここにいくつかのHTMLがあります:

 <form action=""> <p> <label for="name">Full name</label> <input type="text" id="name"> </p> <p> <label for="email">Email</label> <input type="email" id="email"> </p> <p> <label for="phone">Phone</label> <input type="tel" id="phone"> </p> </form>

これは、フォーカスされた後の各入力の外観です。

(大プレビュー)

19.RTLレイアウトの電話番号

+ 972-123555777のような電話番号を右から左のレイアウトで追加すると、プラス記号が番号の最後に配置されます。 これを修正するには、電話番号の方向を再割り当てします。

 p { direction: ltr; } 
(大プレビュー)

結論

ここで説明するすべての問題は、フロントエンドの開発作業で直面した最も一般的な問題の1つです。 私の目標は、Webプロジェクトで作業している間、定期的にチェックするリストを保持することです。

CSSで常に直面している問題がありますか? コメントで教えてください!