Background with position fixed and size contain, relative to container - css

So I came across this today.
I have a section that is longer than the viewport, which has a background image with background-attachment: fixed;. This background is also using the background-size: cover; property. (needed for responsive purposes)
With the fixed position applied to the background, it crops off the image to fit it within the current viewport height and overflows the top of the tag.
Is there a way to make the image sit in the correct place (i.e. same position as if it wasn't fixed) and maintain the cover propery.
.hero {
background-image: url(http://lorempixel.com/output/food-q-c-1920-1920-1.jpg);
background-size: cover;
background-position: 50% 50%;
/* set the height of the hero. */
height: 125vh;
}
.fixed {
background-attachment: fixed;
}
<h4>With the fixed position</h4>
<section class="hero fixed"></section>
<h4>Without the fixed position</h4>
<section class="hero"></section>
I'm guessing as fixed elements are fixed to the viewport, the answer is no, but wasn't sure as it's a background image.
I wondered if perhaps anyone has found a workaround?

The Problem is, that the background area is fixed to 100% view port if you use fixed - You can enlarge the background area by adding background-size:
.hero {
background-image: url(http://lorempixel.com/output/food-q-c-1920-1920-1.jpg);
/*background-size: cover;*/
background-position: 50% 50%;
/* set the height of the hero. */
background-size: 125vh;
height: 125vh;
}

Related

Set background image in the center for all window size

according to the window size, the picture should both cover the window and even if the window height is greater than the height of the picture, let the picture be centered and fully covered.
But I don't want like this (Because the image is not centered, it just starts from the corner.):
background-size: center cover;
Your attempt looks like you try to do it with a OneLiner.
body {
background: url(https://via.placeholder.com/500/green) transparent no-repeat center center / cover;
height: 100vh;
}
<body>
<div>
hello World
</div>
</body>
background-size sets the size of background images for the element. The size of the image can be constrained, completely or partially in order to maintain its aspect ratio.
then remove the margin and padding from the element's parent
try to separate each term, like this
background-size: cover;
background-position: center;
try using margins
I have defined a css for you
.image{
width: 40%;
height: 40vh;
margin-top:30vh;
margin-left: 30%;
}
u can change the width and height of image but remember change margin top and margin left by half.
I used this for a div with an image inside of it. should work just fine. it will get smaller/larger depending on the window size and it will be in the exact center of the page.
background-image: url(path/to/image);
background-size: cover;
background-position: center center;

Limit max-width of a background image in CSS

I'm making a website and using a background image in a div.
The background image itself is using "cover" as its size. The div itself has a max width, as does its parent div.
However, when I test on larger screens, it continues to stretch. The divs themselves do not, they stay bounded at their upper levels, but the image continues to grow as the window expands.
I've tried using a width of 100%, which has the same problem. I've tried limiting the img.bg size, I've tried changing the background-size to cover contain and 100% cover, but nothing seems to make a difference.
Here's where it's at right now. On 1920x1080 browsers, the image will stretch all the way to 1920, even though I can only see 1300px of it.
img.bg {
max-width: 1300px;
}
.parallax {
background-image: url("images/headerimage2.jpg");
height: 350px;
max-width: 1300px;
min-width: 650px;
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
The HTML where it's going I invoke with just this:
<div class="parallax"></div>

CSS Responsive BG Images

I am trying to create a full width parallax site and having an issue getting background images for sections to scale properly.
How would I get a full width image in desktop view to shrink down and contain a 100% width but the height shrink and image contain proportions to fit the width? The problem I am having is I can't set a background container to have a max height.
I'm really looking for a way for the height to shrink from 100% down when the viewport keeps getting smaller so that the focus of the picture isn't lost and maintains proportions just like a responsive image would.
I have tried background-size: contain as well but even then the container has to a have a fixed height which has to change while the background image shrinks because otherwise the image won't be fluid with the container.
#main-photo {
background-image: url("images/main.jpg");
background-attachment: fixed;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
margin-top: 130px;
height: 100%;
width: 100%;
}
If I remove the height obviously nothing is rendered in the browser and max-height doesn't work like it would for responsive images.
Can someone please help me with this effect?
You need to use background-size: contain instead of background-size: cover. Demo here
#main-photo {
background-image: url('images/main.jpg');
background-repeat: no-repeat;
background-size: contain;
background-position: center;
height: 100%;
width: 100%;
}
I found a solution using a padding trick that adds height and allows the image to maintain its aspect ratio. Thank You!
Just add
padding-bottom: %here
You won't need to specify a height for the background image only a 100% width.
Here is a great article. http://www.outsidethebracket.com/responsive-web-design-fluid-background-images/

CSS background-size: cover + background-attachment: fixed clipping background images

I have a list of figures containing background images. Something like the following:
<ul>
<li>
<figure style="background-image: url(...);"></figure>
</li>
<li>
<figure style="background-image: url(...);"></figure>
</li>
<li>
<figure style="background-image: url(...);"></figure>
</li>
</ul>
Each of these images has their background-size set to cover and background-attachment set to fixed.
figure {
width: 100%;
height: 100%;
background-size: cover;
background-attachment: fixed;
}
When each of the figures takes up the entire viewport, this works fine, but if there is an offset of any kind the background-image gets clipped.
As far as I can tell this is by design (https://developer.mozilla.org/en-US/docs/Web/CSS/background-size#Values).
I would like the images to either clip vertically or horizontally but not both, and be centred by the size of the figure itself.
I know there are javascript solutions but is there a way to do this using CSS?
Here is a working example: http://codepen.io/Godwin/pen/KepiJ
Unfortunately this is simply an artifact of how fixed positioning works in CSS and there is no way around it in pure CSS - you have to use Javascript.
The reason this happens is due to the combination of background-attachment: fixed and background-size: cover. When you specify background-attachment: fixed it essentially causes the background-image to behave as if it were a position: fixed image, meaning that it's taken out of the page flow and positioning context and becomes relative to the viewport rather than the element it's the background image of.
So whenever you use these properties together, the cover value is being calculated relative to the size of the viewport irrespective of the size of the element itself, which is why it works as expected when the element is the same size as the viewport but is cropped in unexpected ways when the element is smaller than the viewport.
To get around this you basically need to use background-attachment: scroll and bind an event listener to the scroll event in JS that manually updates the background-position relative to how far the window has been scrolled in order to simulate fixed positioning but still calculate background-size: cover relative to the container element rather than the viewport.
There's a jQuery fix for this: http://jsfiddle.net/QN9cH/1/
I know it's not optimal but at least it works :)
$(window).scroll(function() {
var scrolledY = $(window).scrollTop();
$('#container').css('background-position', 'left ' + ((scrolledY)) + 'px');
});
Nick Noordijk's answer put me on the right track, but I like to avoid scripts that perform a calculation every time the scroll event happens. Here's my version that only performs the calculation when page loads or screen size changes:
html:
<div class="fake-img"></div>
css:
.fake-img {
display: block;
height: 280px; /* set the height here */
width: 100%;
background-image: url('http://example.com/path/to/image.jpg');
background-repeat: no-repeat;
background-position: center 68px;
background-size: auto 50%; /* make a "best guess" here as a default */
background-attachment: fixed;
position: relative;
}
jQuery:
$(window).on('resize load orientationchange', function(){
responsive_calc();
});
var responsive_calc = function(){
// get the viewport height
var h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
// get the element height
var bannerHeight = $('.fake-img').height();
// get the integer percentage value difference between them
var bgHeightPercent = Math.ceil(bannerHeight/h*100);
// set background-size height to match the element instead of the viewport
$('.fake-img').css('background-size', 'auto ' + bgHeightPercent + '%');
}
Note that this really only works with landscape "banner" images - using background-size: auto nn% doesn't have the same advantage of background-size: cover in working no matter if your image has excess in either direction.
background: url(<image>) center top no-repeat fixed;
background-size: auto <width size in %>;
There is no real solution. However, you could make size height of the image auto instead of cover. And adjust the width size in % in your element until it bites the border.
You see if you resize your window, it won't be clipped. Instead, it will always keep the original image size format. With this above you basically 'zoom' it but doesn't 'cover' it up.
The background-size: cover; property is indeed clipping the image in order for it to fill the area and not have any empty space.
The background-size: contain; property is determining which dimension is larger and scales according to that. So if you have a 100px x 100px block and a background image of 200x150px, setting the background-size to contain will scale the image to 100x75px. In this scenario however, you will have empty space if the element's aspect ratio is different than the image's.
You can also manually control which proportion has priority, assuming you know the image's aspect ratio.
So if you know that your image is always 100x200px, this means that the width is always the small dimension and the height the large one.
Now setting the background-size: 100% auto; will ensure that you will not get empty space but you will end up with clipping. If you set it to background-size: auto 100%; it will ensure that no clipping takes place and the height will never have empty space ( but the width will).
If you do want clipping and just center the image, use background-position: 50%;.
Another very simple solution is to use of the vw and vh units (which, in case you didn't know, has totally passable browser support for most cases). For example, instead of doing background-size: cover, do background-size: auto 100vh.
If you're not familiar with vw and vh, they're viewport units, and they correspond to viewport width and viewport height. The values correspond to a percentage of the viewport height or width. For example, 50vw means 50% of the viewport width.
For our purposes, we can simply tell the background to be 100% of the viewport height.
Here's a fiddle.
If you need to accommodate for different aspect ratios you can take advantage of the aspect-ratio #media rules.
An example of parallax effect for separately arranged elements (not for fullscreen elements):
html:
<div style="background-image: url('/path/to/image.jpg')">Content</div>
css:
#element_to_scroll {
background-repeat: no-repeat;
background-size: cover;
background-position-x: center;
background-position-y: 0;
}
js:
$(window).scroll(function() {
var realImageWidth = 1280;
var realImageHeight = 1024;
var viewportBottom = $(window).scrollTop() + $(window).height();
$('#element_to_scroll').each(function(){
var scrollAmountPx = realImageHeight/(realImageWidth/$(this).outerWidth())-$(this).outerHeight();
var elementOffsetFromBottom = viewportBottom-$(this).offset().top;
var scrollAreaHeight = $(this).outerHeight() + $(window).height();
if(elementOffsetFromBottom>0 && elementOffsetFromBottom<scrollAreaHeight) {
var backgroundPositionOffset = Math.ceil(scrollAmountPx/scrollAreaHeight*elementOffsetFromBottom);
//$(this).css('background-position-y',"-"+backgroundPositionOffset+"px");
$(this).clearQueue().animate({'background-position-y':"-"+backgroundPositionOffset+"px"},50);
}
});
});
Update in July 2018: There is now a 1-line fix for this problem
I had this same problem until I read this article, which taught me that I could add this line to my CSS to make it work:
will-change: transform;
It worked!
Now my CSS looks like this:
.myClass{
position: relative;
background: hsla(300, 100%, 90%, 0.1);
overflow: hidden;
&::before {
background-image: url(/img/bg.jpg);
background-size: cover;
background-size: cover !important;
-webkit-background-size: cover !important;
background-repeat: repeat repeat !important;
background-attachment: scroll !important;//"fixed" is the desired effect, but mobile browsers find it too "expensive" and disabled it, so use "scroll"
background-position: 30% 50%;
#media(min-width: $screen-sm-min){
background-attachment: fixed !important;
background-position: 30% 20%;
will-change: transform;
}//768
content: "";
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.1;
}
}
It's working for me on Windows Chrome, Edge, and Safari. But not Firefox.
I did a version with Responsive background image.
.flexslider .slides > li {
background-position: center center;
background-repeat: no-repeat;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
#slider,
.alink {
min-height: 300px
}
.alink {
display: block
}
http://jsfiddle.net/onigetoc/grpku1gk/

CSS Background fit every resolution

Ok, so I am a newbie. I want my background (which is a image), to fit every resolution of the Web Browser no matter the browser resolution. I found this trick:
html {
background: url(images/bg.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
BUT all it does is fits the background to the full size of the display, not the browser. So if the display is 1366x768 and the browser is maximized, then the background is properly showing as "full". However if I then adjust the browser , the background image is not showing correctly.
So what do I need to do, so the background image is adjusted with the browser? So if the browser is 1300x700, the background image is 1300x700 but if the browser is 900x600 then the backgroud image is 900x600. Again, Im a newbie so please provide some examples.
cover This keyword specifies that the background image should be scaled to be as small as possible while ensuring both its dimensions are greater than or equal to the corresponding dimensions of the background positioning area.
contain This keyword specifies that the background image should be scaled to be as large as possible while ensuring both its dimensions are less than or equal to the corresponding dimensions of the background positioning area. So try using contain instead of cover
100% This will scale 100% to both of height and width without any cropping.
html {
background: url(images/bg.jpg) no-repeat center center fixed;
-webkit-background-size: contain;
-moz-background-size: contain;
-o-background-size: contain;
background-size: contain;
}
This may help you: http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size&preval=contain
And this https://developer.mozilla.org/en-US/docs/Web/CSS/background-size
You can actually work around this by inserting the background image you want with height and width attributes on it and setting 100% width on it. Then you can place your content on top of that image.
<div class="container">
<img class="background-image" src="whatever.png" width="NATURAL WIDTH" height="NATURAL HEIGHT">
<div class="content">
This stuff will be on top of the image.
</div>
</div>
<style>
/* This element will == the height of the image */
.container {
position: relative;
}
/* This element is the background image */
.background-image {
width: 100%;
height: auto;
position: static;
}
/* This element contains the content which will be placed on top of the background image */
.content {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
}
</style>

Resources