編集

Bloggerの記事一覧を自分好みに整えました【F-lightをFlexbox化】

これまでと変わらなく見える記事一覧ですが、内部のレイアウトを大きく作り直しました。目的は、「ブラウザの幅を変えた時に画像が切れないようにすること」です。

F-lightの記事一覧をFlexbox

きっかけは偶然の違和感

PCで自分のブログを眺めていたときに、何気なくブラウザの幅を細くしてみて、驚きました。

アイキャッチ画像の端が切れている😨

アイキャッチ画像両端が切れたスクリーンショット
横幅620px付近

もっと細くしていったらタイトルも切れた😱

アイキャッチ画像上下が切れたスクリーンショット
横幅570px付近

オリジナルから画像サイズを変更してるから余計に目立つ。いつも、ブラウザ最大かスマホで見ていたから気が付かなかった。

いつもどおりAIに相談

こうなると気になってしかたありません。AIに相談してみました。この時点では、「ちょっと幅を直す」くらいで済むと思ってました。

Geminiに聞いてみた

  • Gemini:「このコードに書き換えてください」
  • 👉わたし:「特に変わらないよ」
  • Gemini:「失礼しました、もっと強力なコードにしました」
  • 👉わたし:「レイアウトが崩れたよ」
  • Gemini:「力業の最終手段です、これに書き換えてください」

コードをこねくり回しても、こちらを直せばあちらが崩れ、広げればこちらが消える。その度に、コードの行数と !important だけが増えていく泥沼状態になりました。

こうなるともうだめなことは、経験で知っているので、ChatGPTに聞きます。

ChatGPTに聞いてみた

  • ChatGPT:「absolute使ってるなら、設計思想が違うので無理です」
  • 👉わたし:「あ、そうなの・・・」

F-lightの設計は、配置が正確に決まる「absolute」がベース。この構造を崩さないまま、横幅だけを調整しようと試行錯誤していたようです。

 

absolute(絶対配置)のままでは、今回やりたかったレスポンシブ対応は難しいと分かりました。軽量な構造はそのままに、表示レイアウトだけをFlexboxに置き換えることに挑戦します。

フレックス化の始まり

初めは、HTMLをいじらずにFlexboxで並べようとしたけど、共通の親要素がない構造ではどうにもなりませんでした。

目には見えないけど、箱の中に title, snippet, category, header とバラバラに入っている状態のようです。

flexboxが横に3つ並んでレイアウトが崩れたスクリーンショット
テキストが横に3つ並んでしまった

縦に並べ直しても、titleの枠が画像の枠と同じ高さになるため、親枠が大きくなってしまいます。

flexboxを縦に3つ並べたら親枠が大きすぎてレイアウトが崩れたスクリーンショット
CSSだけではどうにもならなかった

最終カスタマイズコード

触りたくなかったけど、構造を変えないと解決できなかったのでHTMLも変更しました。

⚠️ バックアップを取ってからお試し下さい。

HTMLの構造を変更する

まずは、HTMLにラップ(囲い)を入れ、テキストをグループでまとめます。これで、画像とテキストをそれぞれ独立したブロックとして扱えるようになります。

こうする👇

<div class='article-img'>.........</div>
<div class='article-text'>
<h2 class='article-title'>.........</h2>
<p class='article-snippet'>.........</p>
<p class='article-category'>.........</p>
<p class='article-header'>.........</p>
</div>

CSSを書き換える

absoluteだったCSSを消して、flexのCSSに書き換えます。高さ・影・ホバーなどは、以前の数値を継続してます。

ブレイクポイントも増やしました

  • @media (min-width: 601px) and (max-width: 750px)
  • @media(max-width: 600px)
/*==== 記事一覧 Flexbox対応版 ====*/

.article {
  display: flex !important;
  align-items: stretch;
  height: 180px;
  position: relative;
  margin-bottom: 20px;
  background: var(--light-bg);
  border-radius: 5px;
  box-shadow: 1px 1px 2px var(--shadow);
  transition: .3s;
  overflow: hidden;
}

[data-theme-mode="dark"] .article,
html:not([data-theme-mode="light"]) .article {
  background:var(--light-bg);
}

/* 1. 画像エリア */
.article-img {
  flex: 0 0 320px;
  position: relative;
  overflow: hidden;
  transition: .3s;
}

.article-img img {
  position: absolute;
  top: 0; left: 0;
  width: 100% !important;
  height: 100% !important;
  object-fit: cover;
  border-radius: 5px 0 0 5px;
}

/* 2. テキストエリア */
.article-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 8px 10px 0 13px;
  min-width: 0;
  position: relative;
}

/* 3. 中身のリセット */
.article-title, .article-snippet, .article-category {
  position: static !important;
  width: auto !important;
  left: auto !important;
  margin: 0 !important;
}

.article-title {
  display: flex !important;
  align-items: flex-start;
  font-size: 1.82rem;
  font-weight: normal;
  line-height: 1.35;
  overflow: hidden;
}

.article-title::before {
  content: "\25A0";
  color: var(--brand);
  flex-shrink: 0; 
  padding-right: 3px;
  display: inline-block;
  line-height: 1.4;
  transition: .3s;
}

.article-snippet {
  font-size: 1.4rem;
  line-height: 1.5;
  margin-top: 15px !important;
  
  color: var(--dark-color);
  display: -webkit-box !important;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.article-header {
  position: absolute !important;
  bottom: 5px;
  right: 10px;
  font-size: 1.3rem;
}

/* 4. 中間サイズ(601px 〜 750px) */
@media (min-width: 601px) and (max-width: 750px) {
  .article {
    height: 150px;
  }
  .article-img {
    flex: 0 0 266px !important; 
  }
  .article-text {
    padding: 10px 15px;
  }
  .article-title {
    font-size: 1.6rem !important;
    line-height: 1.35 !important;
    -webkit-line-clamp: 3 !important;
  }
  .article-snippet {
    display: none !important; 
  }
}

/* 5. スマホ対応(600px以下) */

@media(max-width: 600px) {
  .article {
    height: 110px;
  }
  .article-text {
    padding: 6px 8px 0 10px;    
  }
.article-img {
    flex: 0 0 185px ;
  }
  .article-title {
    font-size: 1.5rem !important;
    -webkit-line-clamp: 4;
    line-height: 1.25 !important;
  }
  .article-snippet {
    display: none !important;
  }
}

/* 6. ホバー効果 */
.article:hover {
  box-shadow: 8px 8px 10px var(--shadow);
}
.article:hover .article-img {
  opacity: .7;
}
.article:hover .article-title::before {
  color: var(--sub-brand);
}

動きがレスポンシブになった

簡単に書いたけど、GeminiとChatGPTを行き来して6時間以上かかりました。一見すると何も変わらない。誰にも気づかれないので、完全に自己満足でしょうか。

どこも切れてないスクリーンショット(PCサイズ)
横幅770px付近
どこも切れてないスクリーンショット(スマホサイズ)
横幅640px付近

ぜひ、ブラウザの横幅をグーッと縮めてみてください。

試行錯誤の末にやっと完成しました。分解してみると、緻密な計算で組まれたレイアウトだったのが理解できます。他の箇所に影響が出ないか心配ですが、しばらく様子をうかがいながら使ってみたいと思います。

safariやiPhoneで試せていません。レイアウト崩れがあったら教えてくれると嬉しいです。

💖 読んでいただき有難うございました。

コメントを投稿

別ページに移動します