文章の横に写真を配置するレイアウトはよくあります。
CSSでフロートを右または左に設定すれば実現できます。
固定記述であればどうということはありませんが、PHPを使って入力されたテキストと画像を表示する場合、勝手が異なってきます。
なぜならば、画像がある場合、画像がない場合があるからです。
画像がない場合はCSSのフロートは不要で、画像がある場合はCSSのフロートをそのままにしておく。
そんな局面がありました。
いろいろ試して実現できましたので、忘備録として記録いたします。
現象はこのような感じです。
左側にテキスト、右側に画像です。
これ自体はよくあるパターンです。
問題なのは、画像がない場合にテキストを途中で折り返ししている点です。
画像がない場合は、テキストを横幅いっぱいにしたいのです。
なぜそのような処理が必要なのか?
固定ページならば、テキストのみの場合と、画像がある場合でスタイルシートを分ければよい話です。
なぜそうしないかというと、「PHPで記事を表示」するためです。
投稿したデータを使って、画像投稿があれば画像付きで表示するため、スタイルシート自体は共通でなければいけないのです。
疑問:画像側をフロート設定にすれば解決するのではないか?
画像側を右または左のフロートを指定すれば、共通CSSで、画像がない場合テキストを横幅いっぱいに配置できます。
しかしこの方法には一つ欠点があります。
それは、レスポンシブでスマホ表示した場合、画像が上になる点です。
逆を言えば、画像が上でもよい場合は、画像をフロート指定し、テキストはそれなり表示でよいのです。
でも今回は、スマホ表示時は、テキストの下に画像が来るようにしたいのです。
そのため、画像フロート指定だけでは実現できないのです。
疑問:ではどうすれば実現できるのか?
CSSは事前記述のため、後出し判定ができません。
そこで、後出しでも判断ができるJqueryを使用して、CSSの書き換えを行います。
論より証拠で、実際に実現ができたこちらをご覧ください。
テキストの後に画像指定で、画像がない場合にテキストを横幅いっぱいに表示できています。
この方法について解説いたします。
ソース
実現ができているソースを以下に記載します。
<!doctype html>
<html>
<head>
<meta charset="shift_jis">
<title>スマホ表示対応</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style type="text/css">
img
{
max-width: 100%;
}
article
{
width: 1000px;
margin-right: auto;
margin-left: auto;
}
section
{
_zoom: 1;
overflow: hidden;
padding: 10px;
margin-bottom: 30px;
border: 1px solid #ccc;
}
.text
{
float: left;
width: 560px;
}
.photo
{
float: right;
}
.clr
{
clear: both;
float: none;
width: auto;
}
@media screen and (max-width:767px)
{
article
{
width: auto;
}
.text,
.photo
{
float: none;
clear: both;
width: auto;
}
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function()
{
$.each($("section"), function(count, value_data)
{
if ($("section:eq("+count+") div").is(".photo") == false)
{
$("section:eq("+count+") .text").addClass("clr");
}
});
});
</script>
</head>
<body>
<article>
<h1>修正後:画像がない場合はテキストが横幅いっぱいに表示される</h1>
<section>
<div class="text">
<p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
</div>
<div class="photo"><img src="sample.jpg" width="400" height="300"></div>
</section>
<section>
<div class="text">
<p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
<strong>※画像がない場合にテキストが横幅いっぱいになりました。</strong>
</div>
</section>
<section>
<div class="text">
<p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
</div>
<div class="photo"><img src="sample.jpg" width="400" height="300"></div>
</section>
</article>
</body>
</html>
テキストの後ろに画像があることがわかります。
Jquery画像のあり・なしを判断します。
Jquery部分の記述は以下のようになっています。
<script>
$(document).ready(function()
{
// 1.の部分(ループでsection毎にチェック)
$.each($("section"), function(count, value_data)
{
// 2.の部分(画像のありなしをチェック)
if ($("section:eq("+count+") div").is(".photo") == false)
{
// 3.の部分(テキスト部分の横幅をクリア)
$("section:eq("+count+") .text").addClass("clr");
}
});
});
</script>
これだけ見ると、はて?
かと思います。
順を追って説明いたします。
1.連続部分をループで一つ一つ確認
今回のソースは、1つの記事が1つのsectionタグで囲まれています。
10記事の場合はsectionタグが10個。
15記事の場合はsectionタグが15個になります。
なので、each文でsectionタグの数だけループします。
※ループ処理についてはこちらで解説しております。
またご参照いただければ幸いです。
2.is関数で、画像のあり/なしを判断
Jqueryのis関数は、真ならばture、偽ならばfalseが返ります。
今回は、画像指定にスタイルシート「.photo」を設定しています。
そこで、
- 「.photo」があれば画像あり。
- 「.photo」が無ければ画像なし。
と判断します。
具体的には「sectionタグの中のDIVタグに、.photoスタイルシートが存在しているかどうか?」
ということを、sectionタグ毎にチェックします。
3.画像が無かったらテキスト部分の横幅指定をクリア
is関数で画像がない場合に、「.text」に指定されている「横幅」をクリアします。
直接CSSを書き換える方法もありますが、今回はaddClass関数を使用して、解除CSSを付加しています。
疑問:「”+count+”」ってなに?
私は最初理屈では理解できても、「記述」でよくわからない部分がありました。
それは、+count+の部分です。
結論から言うと「何個目のsectionか?」を示しています。
記述例では、「$(“section:eq(“+count+”)”)」となっています。
これは書き換えると「$(“section:eq(0)”)~$(“section:eq(n)”)」ということです。
:eqは、何個目の要素であるかを指定する方法です。
countは、$.each文の要素でループ毎にカウントが1つずつ加算されてゆきます。
この2つの特性を利用して、ループ内でsectionタグが何個目であるかを指定しています。
ちなみに「+」は、Javascriptの結合子です。
例えば「”変数Aの値は:” + a」という風に記述します。
PHPならば「”変数Aの値は:” . a」と記述します。
countは変数のため””(ダブルクォーテーション)内に記述すると、文字列として判断されてしまい、エラーとなります。そうならないようにするため、+で文字列と結合して使用します。
私は最初この部分がわからず「$(“section:eq(count)”)」という記述をしてしまい、エラーが発生していました。
しかも、なぜエラーなのかよくわからず苦労しました。
Jqueryは使わなくて済むならばそれに越したことはありませんが、使わなければいけないときは使いましょう。
Jqueryとはそんな重たいものではありませんが、処理をする以上一瞬間が空きます。
間が空くと表示に一瞬チラ見えが発生する場合があります。
なので、やたらJqueryを使用するとかえって見栄えが悪くなることがあります。
しかし、今回のようにCSSだけで実現できない場合は躊躇せずJqueryを使用しましょう。
要は「奥の手は必要な時に使う」です。
また本記事がお役に立てば幸いです。