【CSS】floatで画像を下に配置してテキストを回り込ませる

floatで画像を下に配置することは難しい点があります

floatを使って画像の下にテキストを回り込ませる実装は、一見シンプルに見えて実は複雑です。以下のような課題があります:

  1. floatは基本的に左右への配置を想定しており、下方向への回り込みは直接的には制御できません
  2. 画像の高さが動的に変わる場合、それに合わせたレイアウト調整が必要になります
  3. レスポンシブ対応時に、画像とテキストの位置関係が崩れやすい

サンプル

ボックス左の「赤いボーダー」を目印にして、実際のレイアウトにあわせて値を調節してください

テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト

テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト

テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト

テキストテキストテキストテキストテキスト テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト

解決策:JavaScriptを使った動的調整

  • レビューボックス内の各要素(1から4まで)のスペースの高さを動的に調整します
  • テキスト部分の高さに基づいて、赤い縦線(.review-space)の高さを計算します
Floatレイアウトの仕組みと課題 一般的なfloat: left Image Text wraps around the image naturally 下方向への回り込み(課題) Desired Position Actual Position Text cannot wrap below naturally JavaScriptによる解決策 1. テキストの高さを取得 2. ビューポート幅から調整値を計算 3. 専用のスペース要素の高さを設定 4. リサイズ時に再計算
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>

<style>
	.review-list {
		display: flex;
		flex-direction: column;
		gap: 1rem;
	}

	.review-box {
		padding: 4px 4px 0 4px;
		border: 4px solid #ccc;
		border-radius: 10px;
		background-color: #f8f8f8;
		box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
		overflow: hidden;
		width: clamp(300px, 48%, 1000px);
		margin: 0 auto;
	}

	.review-space {
		height: 100%;
		width: 1px;
		background-color: red;
	}

	.review-img {
		clear: both;
		float: left;
		width: 14%;
	}

	.review-img img {
		width: 100%;
		height: auto;
		vertical-align: bottom;
	}

	.review-text {
		font-size: clamp(0.5rem, 1.5vw, 1rem);
		padding: clamp(0.5rem, 3vw, 1rem);
		margin: 0;
	}
</style>
<div class="review-list">
	<div class="review-box">
		<div class="review-space fl-space-1"></div>
		<div class="review-img">
				<img src="https://internet.mints.ne.jp/wp/wp-content/uploads/2024/11/staff-1.png" alt="">
		</div>
		<p class="review-text fl-text-1">
			ボックス左の「赤いボーダー」を目印にして、実際のレイアウトにあわせて値を調節してください<br><br>
			テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<br>
			テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
		</p>
	</div>

	<div class="review-box">
		<div class="review-space fl-space-2"></div>
		<div class="review-img">
				<img src="https://internet.mints.ne.jp/wp/wp-content/uploads/2024/11/staff-2.png" alt="">
		</div>
		<p class="review-text fl-text-2">
			テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
			テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<br>
			テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<br>
			テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
		</p>
	</div>

	<div class="review-box">
		<div class="review-space fl-space-3"></div>
		<div class="review-img">
				<img src="https://internet.mints.ne.jp/wp/wp-content/uploads/2024/11/staff-3.png" alt="">
		</div>
		<p class="review-text fl-text-3">
			テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
			テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<br>
			テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
		</p>
	</div>
	<div class="review-box">
		<div class="review-space fl-space-4"></div>
		<div class="review-img">
				<img src="https://internet.mints.ne.jp/wp/wp-content/uploads/2024/11/staff-4.png" alt="">
		</div>
		<p class="review-text fl-text-4">
			テキストテキストテキストテキストテキスト
			テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト<br>
			テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
		</p>
	</div>	
</div>

<script>
	$(function() {
		function floatHeight() {
			// 1から4までの要素に対して処理を行う
			for (var i = 1; i <= 4; i++) {
				var spaceClass = '.fl-space-' + i;
				var textClass = '.fl-text-' + i;

				$(spaceClass).css('float', 'none'); // 一旦.spaceのfloatを解除してから、
				var height = $(textClass).outerHeight(); // float状態のテキストの高さを取得します。
				console.log('height:', height);

				// vwをピクセルに変換し、上限を100に設定
				var vw = Math.min($(window).width() * 0.1, 70);
				$(spaceClass).outerHeight(height - vw).css('float', 'left');
			}
		}

		$(window).on('load resize', function() {
			floatHeight();
		});
	});
</script>