教材だけでは分からない、案件でよく要求される細かいコーディングのテクニック13選

HTML/CSS

こんにちは。昨今プログラミングやコーディングにおいて様々な情報が見られるようになりました。しかし、そんな環境でもまだまだ学習と仕事、案件には差があるように思います。

そこでこの記事では、実際に案件で求められることの多い細かなコーディングのテクニックをまとめていこうと思います。

それぞれデモサイトを載せており(説明することが少ない場合を除く)、紹介したテクニックを「使っていない状態」と「使った状態」を対比させる形になっています。紹介するコードもこのデモサイトのものです。

コードは全部をベタで載せると記事が非常に長くなるので一部開閉する形式にしています。解説も長くなりがちなので、場合によっては後々別記事にまとめ直すかもしれません。

項目は思いつき次第、または要望次第で追加していくつもりですのでよろしくお願いします。ブックマークして時々見てもらうと情報が増えてるかも?

9/9 追記
項目と内容を大幅に加筆、修正したものをzennさんの本として公開しました。ぜひお手に取ってみてください。
https://zenn.dev/hideki_climax/books/3af4f0fd5b40a9

要素の比率を維持する

少し古いSafariを無視できるならaspect-ratioを使いましょう。

.Sample {
  aspect-ratio: 16 / 9; /* 横幅:高さを16:9にしたい場合 */
}

しかし残念ながら、多くの場合そうもいかないでしょう。そこでpadding-topを使った方法を紹介します。padding-topは%で指定を行う時、親要素の横幅を基準にします。よって以下のように指定すると比率を維持した要素が作れます。ただし、padding-topを使っているということは中の要素はその分下に押し出されます。そこでpositionを使って中の要素の位置を調整します。

見た目

コード

index.html

<div class="Box">
  <div class="Box__Inner">
    <div class="Box-Content">
      <div class="Box-Content-Text">ダミーテキスト</div>
    </div>
  </div>
</div>
style.css

.Box {
  width: 50%; /* この横幅が.Box__Innerのpadding-topの基準になります */
  background-color: #ddd;
}

.Box__Inner {
  position: relative;
  width: 100%;
  padding-top: 100%;
}

.Box-Content {
  position: absolute; 
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  /* 中のレイアウトは自由 */
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 中の要素も自由にレイアウトできる */
.Box-Content-Text {
  width: 80%;
  padding-top: 15px;
  padding-bottom: 15px;
  background-color: #707070;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
}

どんな画像が投稿されても崩れないような実装

例えばブログサイトの記事一覧におけるサムネイル画像ですね。管理画面から投稿される画像は、まちまちのサイズになります。どんなサイズの画像が投稿されても比率が崩れたりしない方がいいですね。その方法です。

見た目

コード

index.html
<article class="ArticleCard">
  <div class="ArticleCard__ImageWrapper">
    <img src="./images/view1.jpg" alt="" class="ArticleCard-Image" />
    <!-- 画像は任意のものを参照してください -->
  </div>
  <h2 class="ArticleCard-Title">ダミータイトル</h2>
</article>
style.css
.ArticleCard {
  box-shadow: 0 0 12px 0px rgba(0,0,0,0.2);
}

.ArticleCard-Image {
  width: 100%;
  height: 300px;
  object-fit: cover;
  object-position: center;
}

.ArticleCard-Title {
  width: 100%;
  padding: 20px;
}

まずimgタグのサイズを決めます。次にobject-fitで画像のサイズを、object-positionで画像の位置を決めます。ほとんどの場合object-fitはcoverが望ましいでしょう、imgタグに余白が出ないように画像が広がります。object-positionは要件によりけりですね。

前述の比率維持の方法と組み合わせても良いです。

index.html
<article class="ArticleCard">
  <div class="ArticleCard__ImageWrapper">
    <img src="./images/view4.jpg" alt="" class="ArticleCard-Image2" />
  </div>
  <h2 class="ArticleCard-Title">ダミータイトル</h2>
</article>
style.css
.ArticleCard {
  box-shadow: 0 0 12px 0px rgba(0,0,0,0.2);
}

.ArticleCard__ImageWrapper {
  position: relative;
  width: 100%;
  padding-top: calc(9 / 16 * 100%);
}

.ArticleCard-Image2 {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.ArticleCard-Title {
  width: 100%;
  padding: 20px;
}

長いアルファベットの文字列でも改行させる

長いアルファベットは、それで1単語と見なされてしまい改行が起こりません。デフォルトでは単語の途中で改行するルールになっていないからです。

このケースは記事のタイトルなど、ユーザーが投稿できうるコンテンツにありがちです。こういう場合では改行ルールをCSSによって指定しましょう。overflow-wrapというプロパティを使います。

見た目

コード

<p class="Text">
  abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef
</p>

<p class="Text">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
.Text {
  width: 100%;
  overflow-wrap: break-word;
}

overflow-wrap: break-word;を指定すると長いアルファベットでも強制的に改行を行います。

これまではword-break: break-all;という指定もよく紹介されていたと思いますが(この記事でも元々はそちらでした)、その指定では単語の途中でも問答無用で改行してしまいます。

一方overflow-wrap: break-word;はなるべく単語の途中では改行しないようにします。読みやすさの観点でこちらの方が良さそうですね。

3点リーダーによる文章の省略

これも記事一覧のタイトル、ないしは抜粋部分にありがちな要求ですね。文章が長くても、レイアウトを崩さないようにしたい場合があります。

そういう時は、行数を指定してそれ以上の部分は3点リーダーで省略することができます。

見た目

コード

<div class="Text">
  親譲りの無鉄砲で小供の時から損ばかりしている。小学校に居る時分学校の二階から飛び降りて一週間ほど腰を抜かした事がある。なぜそんな無闇をしたと聞く人があるかも知れぬ。別段深い理由でもない。新築の二階から首を出していたら、同級生の一人が冗談に、いくら威張っても、そこから飛び降りる事は出来まい。弱虫やーい。と囃したからである。小使に負ぶさって帰って来た時、おやじが大きな眼をして二階ぐらいから飛び降りて腰を抜かす奴があるかと云ったから、この次は抜かさずに飛んで見せますと答えた。(青空文庫より)
</div>
.Text {
  margin: auto;
  border: 1px solid #000;
  width: 100%;
  max-width: 800px;
  line-height: 1.5;

  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3; /* ここで行数を決める */
}

後ろ4行が省略のためのコードです。-webkit-line-clampが行数を決めていて、1行で省略させたければ1を、3行で省略させたければ3を指定しましょう。

詳しくはこちらの記事をご覧ください。

改行を考慮したline-heightの指定

これは記事や利用規約ページの見出しにありがちです。

見出しは、ある程度のサイズの画面で見れば1行だが幅を縮めていくと2行になる、というケースがよく起きます。

その場合にline-heightが指定していないと見栄えが微妙になることがあります。改行もきちんと想定しておきましょう。

見た目

コード

コードはただline-heightを指定するだけなので、割愛します。

line-heightの余白を打ち消す

line-heightは文章の上下に余白を作ります。例えばfont-size: 16px, line-height: 24px;とすると、24 – 16 = 8px分を上下に分けます。つまり4pxづつ余白が生まれます。

しかし、デザインファイル上では上下の余白がない形で置かれているケースが多いです。

そういうわけで、この余白分を考慮しないとデザイン通りの数値を使ってもズレが発生することになります。

やり方は説明すると大変長いので詳細は別記事に譲る(後述)として、まずは見た目とコードをご覧ください。

見た目

コード

index.html
<section class="Section">
  <h2 class="Headline">余白の調整なし</h2>
  <p class="Text">
    親譲りの無鉄砲で小供の時から損ばかりしている。小学校に居る時分学校の二階から飛び降りて一週間ほど腰を抜かした事がある。なぜそんな無闇をしたと聞く人があるかも知れぬ。別段深い理由でもない。(青空文庫より)
  </p>
</section>
<section class="Section">
  <h2 class="Headline">余白の調整あり</h2>
  <div class="Text2">
    <p class="Text2__Inner">
      親譲りの無鉄砲で小供の時から損ばかりしている。小学校に居る時分学校の二階から飛び降りて一週間ほど腰を抜かした事がある。なぜそんな無闇をしたと聞く人があるかも知れぬ。別段深い理由でもない。(青空文庫より)
    </p>
  </div>
</section>
style.css
.Section {
  width: 100%;
  border: 1px solid #000;
  padding: 12px;
}

.Headline {
  font-size: 24px;
  font-weight: bold;
}

.Text {
  margin-top: 20px;
  line-height: 3;
  background-color: #ddd;
}

.Text2 {
  margin-top: 20px;
  border-top: 1px solid rgba(0,0,0,0);
  border-bottom: 1px solid rgba(0,0,0,0);
  background-color: #ddd;
}

.Text2__Inner {
  margin-top: calc((((16px * 3 - 16px) / 2) - 1px) * -1);
  margin-bottom: calc((((16px * 3 - 16px) / 2) - 1px) * -1);
  width: 100%;
  line-height: 3;
}

解説

見た目の部分、特にグレー背景の上下をよく見てください。

余白の調整をしたパターンは文章部分の上下の余白がなくなり、背景色がぴったりになっています。

htmlを2重にして、親側(=.Text2)には上下に透明のborderを指定します。子側(=.Text2__Inner)には打ち消したい余白分の負のmarginを上下に設定します。

これの計算がまあややこしいんですが、以下の形です。

打ち消したい余白分の値
=(((font-size * line-height - font-size) / 2) - borderの太さ) * -1;

詳しい解説は以下の記事から。

inline-blockによる改行制御

記事の見出しや、トップページの各セクションにおける見出しでありがちな実装です。

通常、日本語の文章の場合改行は1文字づつ起きます。しかし文章の内容によっては、できれば単語の途中で改行はしない方がいいケースがあります。

例えば、利用規約ページがイメージしやすいでしょうか。(参照:https://qiita.com/terms

利用規約ページのような、おしゃれさやデザイン性が重視されないページでどこまで改行を気にすべきかはさておき、「本規約に」と「ついて」の間で改行してくれた方が読みやすくはなるでしょう。要するにこのようなケースのことを指します。

見た目

このように、任意のブロックごとに改行させることができます。

コード

<h1 class="Headline"
  >とても長い文章を見出しに使いたい場合に、今回の方法は使えます。</h1
>

<h1 class="Headline"
  ><span class="InlineBlock">とても</span
  ><span class="InlineBlock">長い</span
  ><span class="InlineBlock">文章を</span
  ><span class="InlineBlock">見出しに</span
  ><span class="InlineBlock">使いたい</span
  ><span class="InlineBlock">場合に、</span
  ><span class="InlineBlock">今回の</span
  ><span class="InlineBlock">方法は</span
  ><span class="InlineBlock">使えます。</span>
</h1>
.Headline {
  font-size: 24px;
  line-height: 1.5;
}

.InlineBlock {
  display: inline-block;
}

このように、改行の単位にしたいものをspanタグで囲いinline-blockにします。これで改行をうまく制御できます。

マークアップ的にも問題ないはずです。ただしアクセシビリティ面で若干問題があり、読み上げツールがspanタグで区切った部分をそのまま変に間を空けて読んでしまうようです。

よって、現状は改行の見やすさと読み上げのスムーズさがトレードオフになってしまっているのでその点だけ注意してください。(両取りできる方法があればぜひコメントで教えてください。)

文章を両端揃えする

要するに、こういうことです。

コード

text-align: justify;

一部注意しないと見た目が崩れるケースもありますが、詳しくは以下の記事をご覧ください。

letter-spacingを使った時のズレ

letter-spacingといえば文字の余白を調整するプロパティですが、文字の右側に余白を作る仕様になっています。

最後の文字でも余白を作るので、単にletter-spacingだけを指定すると中央に揃わなくなります。

中央揃えにする場合は、padding-leftで同等の余白を追加しましょう。

見た目

コード

<p class="Text">ダミーテキスト</p>
<p class="Text2">ダミーテキスト</p>
.Text {
  border: 1px solid #000;
  width: fit-content;
  font-size: 24px;
  letter-spacing: 3em;
}

.Text2 {
  border: 1px solid #000;
  width: fit-content;
  padding-left: 3em;
  font-size: 24px;
  letter-spacing: 3em;
}

このように、letter-spacingと同じ数値をpadding-leftに指定すれば文字の位置がいい感じに揃っていますね。実際はここまで大きいサイズのletter-spacingを指定することはないので、微調整してあげるような形になります。

フォントを日本語/英語/数字などで出し分けたい場合

デザインに力を入れていくと、日本語の文字と英字・数字でフォントを使い分けるような場面が出てきます。

そういった場合に、いちいち数字の部分だけをspanで囲って別のフォントを適用するというやり方は非常に面倒です。ページが増えれば増えるほどその手間も増えますから、何か工夫したいところです。

見た目

コード

<body>
  <main class="Main">
    <p class="Text"
      >8月1日、きょうはなんにもないすばらしい1日だった。ーーHideki.</p
    >
  </main>
</body>
body {
  font-family: 'Noto Sans JP', sans-serif;
}

.Main {
  margin: auto;
  width: 100%;
  max-width: 800px;
  padding: 20px;
  font-family: 'Roboto', sans-serif;
}

このように、bodyに日本語フォント、.Mainに英字フォントとすると文字ごとにうまく適用されます。

親で指定したフォントを、子要素で指定したフォントが上書きするようなイメージです。

ちなみに、1つのプロパティとして複数のフォントを設定する書き方もあります。

font-family: 'Noto Sans JP', 'Roboto', sans-serif;

しかし、この書き方の場合はあくまで「先に書かれたフォントが対応していない文字があった場合に順番に適用していく」挙動になります。日本語フォントは英字、特に数字はほとんど含まれていますからこの書き方では出し分けになりません。注意しましょう。

ハンバーガーメニューが開いている時に裏のスクロールを止める

ハンバーガーメニューの開閉自体は作れるという方は多いと思いますが、裏のスクロールを止める実装はちゃんと毎回していますか?

意外と世の中のサイトでも、この実装がされていないケースはよく見ます。まあ裏のスクロールを止めた方が絶対的に良いとまで言い切るのはちょっと怪しいのですが、せっかくなら覚えておきましょう。

ちなみに、ハンバーガーメニュー自体の作り方も解説しているので以下からご覧ください。

以下で紹介する方法も上記の記事で詳しく解説しています。

コード

body {
  overflow: hidden
}

やることとしては、ハンバーガーメニューの開閉に合わせてbodyタグへのoverflow: hidden付け外しです。メニューが開いている時はoverflow: visible;(初期値)にし、閉じているときはoverflow: hidden;になるようにします。この実装にはJavaScriptが必要です。

bodyタグがoverflow: hidden;になるとスクロールができなくなるため、それを利用しています。

画像のlazy loading

これはいわゆる画像の遅延読み込みです。近くまでスクロールされて初めて画像を読み込むことにより、全体の表示速度を改善するための手法です。

昔はJavaScriptのライブラリなどでなんとか実現していましたが、今はHTML側が進歩し非常に簡単に実現できるようになりました。

コード

<img src="image/to/path" loading="lazy" />

このようにimgタグのloading属性にlazyを指定するだけです。

また他にも実装方法があり、content-visibilityプロパティを使う方法などがあるようです。参考:https://techblog.yahoo.co.jp/entry/2020090830016393/

なお、どの方法でもSafariは非対応の模様。

要素のサイズを完璧にレスポンシブにする

レスポンシブ対応する時に、どうしても綺麗に要素が収まらない時ってあると思います。

そういう時にブレイクポイントを追加しないで綺麗に表示できる方法があります。結論から言えば以下の形です。

clamp(下限, デザインファイル上のサイズ / アートボードの横幅 * 100vw, 上限);

例)
横幅375pxのアートボード上で30pxの文字
font-size: clamp(24px, 30 / 375 * 100vw, 30px)

例)
横幅1440pxのアートボード上で650pxの画像
width: clamp(0px, 650 / 1440 * 100vw, 650px)

詳しくはこちらの記事をご覧ください。

まとめ

というわけでコーディングテクニックのまとめでした。他にこんなケースの解説があったら嬉しいというものがあればぜひコメントでお知らせください。

コメント

  1. […] […]

タイトルとURLをコピーしました