I am building a webpage where I want the background image to scale to fit the whole screen, maintain aspect ratio and be fixed (so if you scroll down, the background image stays in the same place).
I have achieved this in desktop browsers with the CSS below, but it doesn't work on an iPhone or iPad. On those devices the background is too big (it continues below the fold) and if you scroll down far enough, the image will start repeating. Anyone have a fix? THanks!
HTML {
background: url(photos/2452.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
I have found a great solution for fixed backgrounds on mobile devices requiring no JavaScript at all.
body:before {
content: "";
display: block;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: -10;
background: url(photos/2452.jpg) no-repeat center center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
Please be aware of the negative z-index
value of -10
. html
root element default z-index
is 0
. This value must be the smallest z-index
to have it as background.
You could use this tag to make 'fixed' positionned element well working on mobile:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
See my answer to this question: Detect support for background-attachment: fixed?
This is what i do and it works everythere :)
.container {
background: url(${myImage})
background-attachment: fixed;
background-size: cover;
transform: scale(1.1, 1.1);
}
then...
@media only screen and (max-width: 768px){
background-size: 100% 100vh;
}
I had a very simple solution for this, after struggling with all the methods of fixing this.
i had the problem on my mobile IOS devices.
css (desktop)
#ci-hero-11 .widget-wrap , #ci-hero-12 .widget-wrap {
background-size: auto;
background-attachment: fixed;
}
.widget-wrap {
background-attachment: scroll;
}
Then i overwrite it with media query removing "fixed" as background attachment.
css (mobile)
@media (max-width: 767px) {
#ci-hero-11 .widget-wrap , #ci-hero-12 .widget-wrap {
background-attachment: initial;
}
}
initial - Sets this property to its default value. I think because IOS doesn't accept 'fixed' it falls back to a default value it accepts, scroll.
This worked for me on every device. Hope it helps someone else as well.
Found a perfect solution for the problem 100% working on mobile as well as desktop
https://codepen.io/mrinaljain/pen/YObgEP
.jpx-is-wrapper {_x000D_
display: block;_x000D_
margin: 0 auto;_x000D_
overflow: hidden;_x000D_
position: relative;_x000D_
z-index: 314749261;_x000D_
width: 100vw;_x000D_
height: 300px_x000D_
}_x000D_
_x000D_
.jpx-is-wrapper>.jpx-is-container {_x000D_
background-color: transparent;_x000D_
border: 0;_x000D_
box-sizing: content-box;_x000D_
clip: rect(auto auto auto auto);_x000D_
color: black;_x000D_
left: 0;_x000D_
margin: 0 auto;_x000D_
overflow: visible;_x000D_
position: absolute;_x000D_
text-align: left;_x000D_
top: 0;_x000D_
visibility: visible;_x000D_
width: 100%;_x000D_
z-index: auto;_x000D_
height: 300px_x000D_
}_x000D_
_x000D_
.jpx-is-wrapper>.jpx-is-container>.jpx-is-content {_x000D_
left: 0;_x000D_
overflow: hidden;_x000D_
right: 0;_x000D_
top: 0;_x000D_
visibility: visible;_x000D_
width: 100%;_x000D_
position: relative;_x000D_
height: 300px;_x000D_
display: block_x000D_
}_x000D_
_x000D_
.jpx-is-wrapper>.jpx-is-container>.jpx-is-content>.jpx-is-ad {_x000D_
-webkit-box-shadow: rgba(0,0,0,0.65) 0 0 4px 2px;_x000D_
-moz-box-shadow: rgba(0,0,0,0.65) 0 0 4px 2px;_x000D_
box-shadow: rgba(0,0,0,0.65) 0 0 4px 2px;_x000D_
bottom: 26px;_x000D_
left: 0;_x000D_
margin: 0 auto;_x000D_
right: 0;_x000D_
text-align: center;_x000D_
height: 588px;_x000D_
top: 49px;_x000D_
bottom: auto;_x000D_
-webkit-transform: translateZ(0);_x000D_
-moz-transform: translateZ(0);_x000D_
-ms-transform: translateZ(0);_x000D_
-o-transform: translateZ(0);_x000D_
transform: translateZ(0)_x000D_
}_x000D_
_x000D_
.jpx-position-fixed {_x000D_
position: fixed_x000D_
}_x000D_
_x000D_
.jpx-is-wrapper>.jpx-is-container>.jpx-is-content>.jpx-is-ad>.jpx-is-ad-frame {_x000D_
width: 100%;_x000D_
height: 100%_x000D_
}_x000D_
_x000D_
.black-fader {_x000D_
position: absolute;_x000D_
z-index: 1;_x000D_
width: 100%;_x000D_
height: 100%;_x000D_
opacity: 0.75_x000D_
}_x000D_
_x000D_
.video-containers {_x000D_
position: absolute;_x000D_
top: 0;_x000D_
bottom: 0;_x000D_
width: 100%;_x000D_
height: 100%;_x000D_
overflow: hidden;_x000D_
z-index: 0_x000D_
}_x000D_
_x000D_
.video-containers video,.video-containers img {_x000D_
min-width: 100%;_x000D_
min-height: 100%;_x000D_
width: auto;_x000D_
height: auto;_x000D_
position: absolute;_x000D_
top: 50%;_x000D_
left: 50%;_x000D_
transform: translate(-50%, -50%)_x000D_
}
_x000D_
<p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p>_x000D_
_x000D_
<div class="jpx-is-wrapper">_x000D_
<div class="jpx-is-container">_x000D_
<div class="jpx-is-content">_x000D_
<div class="jpx-is-ad jpx-position-fixed">_x000D_
<div scrolling="no" width="100%" height="100%" class="jcl-wrapper" style="border: 0px; display: block; width: 100%; height: 100%;">_x000D_
<div class="video-containers" id="video-container">_x000D_
<img src="https://via.placeholder.com/350x150" alt="" class="">_x000D_
</div>_x000D_
</div>_x000D_
</div>_x000D_
</div>_x000D_
</div>_x000D_
</div>_x000D_
_x000D_
<p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p><p>Salman's arrest has created a wave of tension in Bollywood because of all his projects that were lined up, especially his most awaited film.</p>
_x000D_
Fixed positioning is supported on mobile since Android 2.2 and iOS 5.
You need to use device-with viewport on meta and give the background image with somewhere with an id. Then you will get that id with jquery and give that a height. And of course 100% width
<html>
<head>
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#main {
background: url(1.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
width: 100%;
overflow: hidden;
}
</style>
</head>
<body id="main">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
var hgt = $(window).height();
$("#main").css("height", hgt)
</script>
background-attachment:fixed
in IOS Safari has been a known bug for as long as I can recall.
Here's some other options for you:
https://stackoverflow.com/a/23420490/1004312
Since the fixed position in general is not all that stable on touch (some more than others, Chrome works great), it is still acting up in Safari IOS 8 in situations that used to work in IOS 7, therefore I generally just use JS to detect touch devices, including Windows mobile.
/* ============== SUPPORTS TOUCH OR NOT ========= */
/*! Detects touch support and adds appropriate classes to html and returns a JS object
Copyright (c) 2013 Izilla Partners Pty Ltd | http://www.izilla.com.au
Licensed under the MIT license | https://coderwall.com/p/egbgdw
*/
var supports = (function() {
var d = document.documentElement,
c = "ontouchstart" in window || navigator.msMaxTouchPoints;
if (c) {
d.className += " touch";
return {
touch: true
}
} else {
d.className += " no-touch";
return {
touch: false
}
}
})();
CSS example assumes mobile first:
.myBackgroundPrecious {
background: url(1.jpg) no-repeat center center;
background-size: cover;
}
.no-touch .myBackgroundPrecious {
background-attachment:fixed;
}
"background-size: cover;" causes a lot of issues on all mobile browsers except Firefox!
This fixed my issue:
/* Mobile first */
body{
background-image: url(bg_mobile.jpg);
background-attachment: fixed;
background-repeat: no-repeat;
}
/* Then tablets, laptops and desktops (768px and up) */
@media screen and (min-width:768px) {
body{
background-image: url(bg.jpg);
background-size: cover;
}
}
I found maybe best solution for parallax effect which work on all devices.
Main thing is to set all sections with z-index greater than parallax section.
And parallax image element to set fixed with max width and height
body, html { margin: 0px; }_x000D_
section {_x000D_
position: relative; /* Important */_x000D_
z-index: 1; /* Important */_x000D_
width: 100%;_x000D_
height: 100px;_x000D_
}_x000D_
_x000D_
section.blue { background-color: blue; }_x000D_
section.red { background-color: red; }_x000D_
_x000D_
section.parallax {_x000D_
z-index: 0; /* Important */_x000D_
}_x000D_
_x000D_
section.parallax .image {_x000D_
position: fixed; /* Important */_x000D_
top: 0; /* Important */_x000D_
left: 0; /* Important */_x000D_
width: 100%; /* Important */_x000D_
height: 100%; /* Important */_x000D_
background-image: url(https://www.w3schools.com/css/img_fjords.jpg);_x000D_
background-repeat: no-repeat;_x000D_
background-position: center;_x000D_
-webkit-background-size: cover;_x000D_
-moz-background-size: cover;_x000D_
-o-background-size: cover;_x000D_
background-size: cover;_x000D_
}
_x000D_
<section class="blue"></section>_x000D_
<section class="parallax">_x000D_
<div class="image"></div>_x000D_
</section>_x000D_
<section class="red"></section>
_x000D_
I have been busy using different posts and methods for two days trying to figure it out. I urge anyone to START by looking at the post by Eggs, and mess around with the codepen he and others have built.
This has been the only solution to work properly for me that I have found. I recommend his answer as a solution/ a good starting point at minimum for those of us still figuring out this problem in our own web applications.
I haven't gotten enough reputation yet to comment on his post, otherwise I would. I can't even vote on it yet or I would do that too.
This is the actual code I used:
html::before {
content: ' ';
display: block;
background-image: url('path-to-your-image');
background-position: bottom left;
/*For my instance this is how I have built my bg image. Indexes off the
bottom left for consistency*/
background-size: cover;
top: 0;
bottom: 0;
left: 0;
right: 0;
position: fixed;
z-index: -10;
/*I haven't tested my full app functionality after changing the z-index, but everything appears to work flawlessly right now.*/
}
I tried everything with his original code. When I had
background-position: center;
chrome (on latest android update as of 1/8/18) would lag with updating the image's position, so when scrolling through the website there would be a patch of color where my navbar/URL bar of the browser was. Then it would disappear after the browser recalculated the image center(is what I assume was happening).
So, I recommend making an image around your footer or header like I did, and setting either top left/right or bottom left/right for your position.
In summary, THIS WORKS for me. So try it out if you're reading down this far and nothing has worked yet. Though you should've already hit the original post by now.
Thank you Eggs, and the other fellows you collaborated with on your Codepen.
I'm late to the party, but this is (unbelievably) still a problem as of the 11.05.2017. Here is a simple solution which will also work cross-platform with linear gradients:
.backgroundFixed {_x000D_
background: linear-gradient(160deg, #2db4a8 0%, #13af3d 100%);_x000D_
background-size: 100vw 100vh;_x000D_
position: fixed;_x000D_
top: 0;_x000D_
left: 0;_x000D_
height: 100vh;_x000D_
width: 100vw;_x000D_
z-index: -1000;_x000D_
}
_x000D_
<!DOCTYPE html>_x000D_
<html>_x000D_
<head>_x000D_
<meta charset="UTF-8">_x000D_
<title>title</title>_x000D_
</head>_x000D_
<body>_x000D_
<div class="backgroundFixed"></div>_x000D_
<div class="paragraphContainer">_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
<p>We're here to make the body scroll</p>_x000D_
</div>_x000D_
</body>_x000D_
</html>
_x000D_
Thanks to the efforts of Vincent and work by Joey Hayes, I have this codepen working on android mobile that supports multiple fixed backgrounds
HTML:
<html>
<body>
<nav>Nav to nowhere</nav>
<article>
<section class="bg-img bg-img1">
<div class="content">
<h1>Fixed backgrounds on a mobile browser</h1>
</div>
</section>
<section class="solid">
<h3>Scrolling Foreground Here</h3>
</section>
<section>
<div class="content">
<p>Quid securi etiam tamquam eu fugiat nulla pariatur. Cum ceteris in veneratione tui montes, nascetur mus. Quisque placerat facilisis egestas cillum dolore. Ambitioni dedisse scripsisse iudicaretur. Quisque ut dolor gravida, placerat libero vel,
euismod.
</p>
</div>
</section>
<section class="solid">
<h3>Scrolling Foreground Here</h3>
</section>
<section class="footer">
<div class="content">
<h3>The end is nigh.</h3>
</div>
</section>
</article>
</body>
CSS:
* {
box-sizing: border-box;
}
body {
font-family: "source sans pro";
font-weight: 400;
color: #fdfdfd;
}
body > section >.footer {
overflow: hidden;
}
nav {
position: fixed;
top: 0;
left: 0;
height: 70px;
width: 100%;
background-color: silver;
z-index: 999;
text-align: center;
font-size: 2em;
opacity: 0.8;
}
article {
position: relative;
font-size: 1em;
}
section {
height: 100vh;
padding-top: 5em;
}
.bg-img::before {
position: fixed;
content: ' ';
display: block;
width: 100vw;
min-height: 100vh;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-position: center;
background-size: cover;
z-index: -10;
}
.bg-img1:before {
background-image: url('https://res.cloudinary.com/djhkdplck/image/upload/v1491326836/3balls_1280.jpg');
}
.bg-img2::before {
background-image: url('https://res.cloudinary.com/djhkdplck/image/upload/v1491326840/icebubble-1280.jpg');
}
.bg-img3::before {
background-image: url('https://res.cloudinary.com/djhkdplck/image/upload/v1491326844/soap-bubbles_1280.jpg');
}
h1, h2, h3 {
font-family: lato;
font-weight: 300;
text-transform: uppercase;
letter-spacing: 1px;
}
.content {
max-width: 50rem;
margin: 0 auto;
}
.solid {
min-height: 100vh;
width: 100%;
margin: auto;
border: 1px solid white;
background: rgba(255, 255, 255, 0.6);
}
.footer {
background: rgba(2, 2, 2, 0.5);
}
JS/JQUERY
window.onload = function() {
// Alternate Background Page with scrolling content (Bg Pages are odd#s)
var $bgImg = $('.bg-img');
var $nav = $('nav');
var winh = window.innerHeight;
var scrollPos = 0;
var page = 1;
var page1Bottom = winh;
var page3Top = winh;
var page3Bottom = winh * 3;
var page5Top = winh * 3;
var page5Bottom = winh * 5;
$(window).on('scroll', function() {
scrollPos = Number($(window).scrollTop().toFixed(2));
page = Math.floor(Number(scrollPos / winh) +1);
if (scrollPos >= 0 && scrollPos < page1Bottom ) {
if (! $bgImg.hasClass('bg-img1')) {
removeBg( $bgImg, 2, 3, 1 ); // element, low, high, current
$bgImg.addClass('bg-img1');
}
} else if (scrollPos >= page3Top && scrollPos <= page3Bottom) {
if (! $bgImg.hasClass('bg-img2')) {
removeBg( $bgImg, 1, 3, 2 ); // element, low, high, current
$bgImg.addClass('bg-img2');
}
} else if (scrollPos >= page5Top && scrollPos <= page5Bottom) {
if (! $bgImg.hasClass('bg-img3')) {
removeBg( $bgImg, 1, 2, 3 ); // element, low, high, current
$bgImg.addClass('bg-img3');
}
}
$nav.html("Page# " + page + " window position: " + scrollPos);
});
}
// This function was created to fix a problem where the mouse moves off the
// screen, this results in improper removal of background image class. Fix
// by removing any background class not applicable to current page.
function removeBg( el, low, high, current ) {
if (low > high || low <= 0 || high <= 0) {
console.log ("bad low/high parameters in removeBg");
}
for (var i=low; i<=high; i++) {
if ( i != current ) { // avoid removing class we are trying to add
if (el.hasClass('bg-img' +i )) {
el.removeClass('bg-img' +i );
}
}
}
} // removeBg()
I think that mobile devices dont work with fixed positions. You should try with some js plugin like skrollr.js (for example). With this kind of plugin you can select the position of your div (or whatever) in function of scrollbar position.
I've been having the same problem, but now it works.
All I had to do was add background-size: cover !important;
and it works on my Android device!
The entire code looks like this:
body.page-id-8 #art-main {
background: #000000 url("link to image") !important;
background-repeat: no-repeat !important;
background-position: 50% 50% !important;
background-attachment: fixed !important;
background-color: transparent !important;
background-size: cover !important;
}
Thanks a lot @taylan derinbay and @Vincent!
Source: Stackoverflow.com