- 最終更新日
- 記事公開日
position:fixedで複数の背景画像を固定する(iPhone対応)


スクロールしても背景が固定されたままのデザインにしたいの。
でも、position:fixedで固定できるのって一枚の画像だけでしょう?
どうにか複数の画像を背景画像として固定できないかな?
あと、iPhoneで適用されない「background-attachment」での背景画像の固定は使わないで欲しい。

了解です!
①clip-pathを使う方法と②jQueryを使う方法の2種類を紹介します。
①clip-pathで複数の背景固定
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="robots" content="noindex">
<title>clip-pathで複数の背景固定</title>
<style>
body {
background:red;
margin:0;
padding:0;
}
section {
position:relative;
height:100vh;
display:flex;
justify-content:center;
align-items:center;
}
.trim {
width:100%;
height:100%;
position:absolute;
top:0;
left:0;
clip-path:polygon(00% 0%, 100% 0%, 100% 100%, 0% 100%);
z-index:-1;
}
.trim img {
width:100%;
height:auto;
position:fixed;
top:0%;
right:0%;
object-fit:cover;
}
div.contents {
width:50vw;
height:50vh;
background:green;
margin:auto;
display:flex;
justify-content:center;
align-items:center;
color:#fff;
font-weight:bold;
font-size:2rem;
}
.interval {
width:100%;
height:100%;
background:yellow;
display:flex;
justify-content:center;
align-items:center;
color:#000;
font-weight:bold;
font-size:2rem;
}
</style>
</head>
<body>
<section>
<div class="trim">
<img src="fix/1.jpg">
</div>
<div class="contents">ぶどう</div>
</section>
<section>
<div class="interval">コンテンツ</div>
</section>
<section class="company_bg">
<div class="trim">
<img src="fix/2.jpg">
</div>
<div class="contents">メロン</div>
</section>
<section>
<div class="interval">コンテンツ</div>
</section>
<section class="company_bg">
<div class="trim">
<img src="fix/3.jpg">
</div>
<div class="contents">桃</div>
</section>
</body>
</html>
position:fixedで固定した画像を、必要な領域内だけclip-pathでトリミングすることで、他の要素に影響が出ないようになっています。
②jQueryで複数の背景固定
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="robots" content="noindex">
<title>multi_fixed</title>
<style>
html ,
body {
margin:0;
padding:0;
}
body:after {
content:'';
width:100%;
height:100vh;
display:block;
backgrond-repeat:no-repeat;
background-size:cover;
position:fixed;
top:0;
left:0;
z-index:-1;
}
body.apple:after {
background-image:url('apple.jpg');
}
#green_box {
background:green;
margin-top:100svh;
height:100vh;
}
body.melon:after {
background-image:url('melon.jpg');
}
#yellow_box {
background:yellow;
margin:100vh 0;
height:100vh;
}
body.banana:after {
background-image:url('banana.jpg');
}
</style>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body class="apple">
<div id="green_box">
メロン
</div>
<div id="yellow_box">
バナナ
</div>
<!-- **************************************************
JavaScript / jQuery
*************************************************** -->
<script>
$(document).ready(function() {
// ページ途中で更新ボタンを押された場合用
setBg();
// スクロールを検知
$(window).scroll(function() {
setBg();
});
function setBg() {
// スクロールの位置を取得
var scroll = $(window).scrollTop();
// ※順番に注意(下の方にある背景画像から指定してください)
switch (true) {
// スクロールの位置がyellow_boxより下だったらバナナ画像に切り替え
case (scroll >= $("#yellow_box").offset().top):
$('body').removeClass().addClass('banana');
break;
// スクロールの位置がgreen_boxより下だったらメロン画像に切り替え
case (scroll >= $("#green_box").offset().top):
$('body').removeClass().addClass('melon');
break;
// どれにも該当しない場合はリンゴ画像を表示
default:
$('body').removeClass().addClass('apple');
break;
}
}
});
</script>
</body>
</html>
スクロールの位置ごとに背景画像を変更しています。
jQueryでは「:;after」「::before」といった疑似要素を操作できないので、クラスの削除・付与を操作して、背景画像を切り替えています。
なお、switch文で切り替えているところは、重なり順の関係で下の方にある背景画像から指定する必要があるのでご注意ください。