Why does CSS3 right aligned background image appear in the wrong place? - html

I am using CSS3 background-position to position a background image 3% from the right edge of the container. However it appears in a different position compared to if i have an equivalent container that is 97% wide with the background image right aligned. You can see what i mean at http://jsfiddle.net/deshg/9qveqdcu/2/, the logo in the black row is further to the right than the one in the green row but surely they should be in the same horizontal position?
If anyone could shed some light on why this is happening it would be massively appreciated.
For reference, code is below.
Thanks all!
#container {
width: 100%;
background-color: #ffcc00;
}
#d1 {
background-color: #cccc00;
background-image: url('http://jsfiddle.net/img/logo.png');
background-position: right 3% center;
background-repeat: no-repeat;
width: 100%;
}
#d2 {
background-color: #000000;
color: #ffffff;
background-image: url('http://jsfiddle.net/img/logo.png');
background-position: right center;
background-repeat: no-repeat;
width: 97%;
margin-right: 3%;
}
<div id="container">
<div id="d1">
abvc
</div>
<div id="d2">
def
</div>
</div>

The background image itself is being offset 3% of it's own width
From the docs:
Percentages refer to the size of the background positioning area minus
size of background image; size refers to the width for horizontal
offsets and to the height for vertical offsets
Here's an illustration when using 25% 25% (from CSS Tricks):

Background position is not working as you thinking.
It's different than if you, say, had an and positioned it at left: 50%; in that scenario, the left edge of the image would be at the halfway point. If you want to center it, you'll need to pull it back to the left (negative translate or negative margin)
For better understanding refer Link And Link
For what you trying to achieve you have to set
background-position: 96% 0px, center center;
Fiddle

Related

Center fixed background of container

I want to create a header with a fixed background. So I defined the following properties:
header {
margin: 0;
padding: 0;
width: 100%;
height: 300px;
display: block;
background-image: url('...');
background-repeat: no-repeat;
background-size: cover;
background-position: center;
background-attachment: fixed;
}
Now I have the following problem. Currently, the background is centered according to the Screen Width and Height. Since the header is at the top, the actual background of the header is just the top of the image. In addition, the header image section changes every time I change the screen height, which is not my goal.
I want the image to be centered within the header (center of the image is at the center of the header, but only if I have not scrolled down). In addition, the header image section should only change if I change the header width, height or screen width but not if the screen height is changed.
You can rely on vh unit combined with some calc(). The center is initally 50vh and you want it to be 150px from the top so we need a translation of 50vh - 150px. You should also get rid of cover if you want the image to not change when the screen height change but it may not render like you want.
I replaced 300px with 100px for the demo.
.header {
height:100px;
border:1px solid;
background:
url(https://picsum.photos/id/1014/1200/800) 50% calc(50% - (50vh - 50px)) fixed;
}
.not-fixed {
background-attachment:initial;
background-position:center;
margin-top:20px;
}
body {
min-height:200vh;
margin:0;
}
<div class="header">
</div>
<div class="header not-fixed">
</div>
With the use of cover
.header {
height:100px;
border:1px solid;
background:
url(https://picsum.photos/id/1014/1200/800) 50% calc(50% - (50vh - 50px))/cover fixed;
}
.not-fixed {
background-attachment:initial;
background-position:center;
margin-top:20px;
}
body {
min-height:200vh;
margin:0;
}
<div class="header">
</div>
<div class="header not-fixed">
</div>
You can clearly see how the first image is centred exactly like the second one without fixed
To get more details about the caluclation check this: Using percentage values with background-position on a linear gradient (the section Combining pixel and percentage values)
Try to wrap the img (outside the header div) and header div and play with position relative/absolute to superimpose header on top of the image.
Having done that, you can use z-index to push image backwards

Dynamic resizing of images

So i have this image right here
"http://i.imgur.com/eh71foN.png"
My problem is that whenever i resize the window the Mass Effect image doesnt resize with it.
It becomes like this
"http://i.imgur.com/jaDV7jG.png"
I've been trying to figure this out for a while. Can anyone point me in the right direction?
#MassEffectSign {
background: url(masseffect12.png) center top no-repeat;
top: 25px; left: 750px; z-index: 2;
padding: 250px;
position: absolute;
}
My blue background
#bodyBorder {
background: url(navyblue.jpg) center top repeat-y;
padding: 1000px;
opacity: 0.7;
background-attachment: fixed; }
Use img tag instead background image in CSS.
img {width: 100%}
Use percents for the relevent values.
top: 25px; left: 45%;
This makes the amount of space between the left edge and the image relative to the window size. Play around with the value a little to center it and you should be good.
Your positioning is absolute, so it will move independently of the scale. Put that inside a relatively positioned div and then it will work.
For instance,
<div style="position:relative;">
<div id="MassEffectSign"> </div>
</div>
Hope this helps.

How to divide a picture into many <div>?

I do this by using that pictrure as the background of a big div, then I make many small div inside covering the whole area of the big div, but I think it seems very unprofessional. Is there anyway to divide a picture into may div ??
Yes. Try background-position.
If your image is: big_picture.png, and it is 100px x 100px, then a super-simplistic example of the solution is:
<div class="top"></div>
<div class="bottom"></div>
css:
div {
width: 100px;
height: 50px;
background-image: url(big_picture.png);
}
/* will only reveal the top 50 pixels */
div.top {
background-position: 0px 0px;
}
/* will only reveal the lower 50 pixels */
div.bottom {
background-position: 0px -50px;
}
You can clearly apply this to as many div elements as you like, in a grid.

Is it possible to achieve this flexible layout without using JS?

What I'm trying to achieve without using JS can be seen on jsfiddle.net/k2h5b/.
Basically I would like to display two images, both centered, one in background and one in foreground:
Background Image: Should cover the whole window without affecting the aspect ratio, which means that the image will always touch two opposite edges of the window, but the image will be cropped.
Forground Image: Should be inside the window without affecting the aspect ratio, which means the image will be always touch two opposite edges of the window, but the image will not be cropped.
It doesn't matter if it's a <div> or an <img> tag, as long as they are displaying the images.
Asume also that the image sizes are known upfront and can be used in CSS or HTML part.
So my question is: is it possible using only CSS or CSS3?
If it's not possible I will accept the answer that will be as close as possible to my goal.
Examples:
When the background image is cropped from the top and bottom:
When the background image when it's cropped from left and right:
After looking at #Kent Brewster's answer, I think I could achieve all the requirements of OP.
This doesn't have the problem of foreground image being cropped and you can also specify constant margin around the foreground image. Also div is being used instead of img tag, because we are using background images. Here is the link and here is the code:
<div id='bg'></div>
<div id='fg'></div>
#bg {
position: absolute;
height: 100%;
width: 100%;
background-image: url(http://i.imgur.com/iOvxJ.jpg);
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: cover;
}
#fg {
position: absolute;
top: 10px;
left: 10px;
bottom: 10px;
right: 10px;
opacity: .7;
background-image: url(http://i.imgur.com/HP9tp.jpg);
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: contain;
}
Try this:
<html>
<style>
body {
margin: 0;
}
#bg {
position: absolute;
height: 100%;
width: 100%;
background: transparent url(bg.jpg) 50% 50% no-repeat;
background-size: cover;
}
#fg {
position: absolute;
height: 90%;
width: 90%;
top: 5%;
left: 5%;
background: transparent url(fg.jpg) 50% 50% no-repeat;
background-size: cover;
opacity: .7;
}
</style>
<body>
<div id="bg"></div>
<div id="fg"></div>
</body>
</html>
If the scaling requirement is flexible, it might work. See http://jsfiddle.net/k2h5b/5/ to see it run.
Yes, it's possible.
Basically I just made the background image the background for the <body> (doesn't have to be the body of course), and then put the image inside that with a small margin.
<body>
<img id='fg' src='http://3.bp.blogspot.com/-OYlUbWqyqog/TeL-gXGx3MI/AAAAAAAAHRc/bdqvvvaeC7c/s1600/bald-eagle3.jpg'></img>
</body>
css:
body {
margin: 0; padding: 0;
overflow: hidden;
background: url('http://wallpaper.zoda.ru/bd/2006/07/21/2c7b4306fd22f049f331d43adb74a5f7.jpg') no-repeat left top;
}
#fg {
margin: 20px 20px;
opacity: 0.7;
}
obviously if the window is too big, there'd be issues. You could (I guess) use media queries to pull in different image sizes based on window size.
edit — OK, well for the image, if you do want it to crop and retain the right aspect ratio, then I think you'll have to know the image size ahead of time to do it so that it works out. Lacking that, here's another revision.
<body>
<div id='fg'> </div>
</body>
css:
body {
margin: 0; padding: 0;
overflow: hidden;
background: url('http://wallpaper.zoda.ru/bd/2006/07/21/2c7b4306fd22f049f331d43adb74a5f7.jpg') no-repeat left top;
}
body, html { width: 100%; height: 100%; }
#fg {
margin: 2%; width: 96%; height: 96%;
opacity: 0.7;
background: url('http://3.bp.blogspot.com/-OYlUbWqyqog/TeL-gXGx3MI/AAAAAAAAHRc/bdqvvvaeC7c/s1600/bald-eagle3.jpg') no-repeat center center;
}
If you know the image dimensions, you could then set max-height and max-width. (I'll try that too :-)
edit again To get the background to crop in a centered way, you'd need to set the position to "center center" instead of "left top". (Or "center top" if you just want it centered horizontally.)
Vertically centering elements with CSS without cutting-edge non-standard features (flexible box layout) is hard. That may be something to do with JavaScript. I'll say that one problem with any JavaScript solution like that is that it really slows the browser down. If you must do it, I would suggest introducing a little time lag so that you don't try to recompute the layout on every resize event. Instead, set a timer for like 200 milliseconds in the future where the work will get done, and each time you do so cancel the previous timer. That way, while a person is dragging the window corner it won't burn up their CPU.
edit even more ooh ooh yes #Kent Brewster's answer with the vertical centering is good - I always forget that trick :-)
There is no way to achieve this effect using only CSS, for two main reasons:
Because you are trying to resize your image, you cannot use the background property and must instead use an <img> tag. Your image will always try to take up as much room as it can if the width and height are not set. Thus, the aspect ratio will not be maintained, or your image will be cropped.
The other caveat of resizing the image is that you will not be able to vertically-align it to the center of your page without knowing its dimensions.

HTML background image offset by x pixels from the center

I'd like to put an image as the background of a webpage but have it offset by some number of pixels with respect to the center.
How can I do this?
I want:
background-image: url("bg.png");
background-position: 25% center;
background-attachment: fixed;
background-repeat: no-repeat;
but instead of 25%, I want something along the lines of "center - 50px". Is there any solution to this?
I believe I have a solution that achieves what you're wanting:
A background image (specifically a page background) offset by a number of pixels with respect to the center.
This works using only HTML & CSS - no javascript required.
Update
This can now be easily achieved using background-position and calc as a CSS unit.
The following CSS will achieve the same outcome as the previous solution (see "Original Solution" below):
#background-container {
width: 100%;
background-image: url("background-image.png");
background-position: calc(50% - 50px) 50%;
background-repeat: no-repeat;
}
Note: Don't use this method if you require support for legacy versions of IE.
Original Solution
#background-container {
width: 100%;
left: -100px; /* this must be TWICE the required offset distance*/
padding-right: 100px; /* must be the same amount as above */
background-image: url("background-image.png");
background-position: center;
background-repeat: no-repeat;
}
What this does is moves the entire container horizontally by the amount specified (in this case to the left 100px). Because the background image is centered relative to the container it moves to the left with the container.
The padding fixes the 100px of blank space that would appear to the right of the container as a result of the move. Background images show through padding). Because browsers use the border-box value instead of the default content-box value to calculate background sizing and positioning, the background image is effectively moved back to the right 50px - half the distance of the padding. (Thanks to ErikE for clarification).
So your offset/padding must be twice the required offset distance.
I have prepared a sample page for you here:
http://www.indieweb.co.nz/testing/background-offset-center.html
Have a play with resizing the window. You will see that the purple and blue background image (laid over a deeper background image marking the center of the page) remains exactly 50px (half the offset/padding distance) to the left of the page center.
Using background-position: center; is the same as background-position: 50% 50%;.
So you can use calc to do some simple math in CSS as a replacement for any length value, for example:
background-position: calc(50% - 50px) 50%;
Will center the background image, but shift it 50 pixels to the left.
So you want it centered by shifted 50 pixels to left. I would add the 50 pixels to the image in the form of a transparent space, unless you are dealing with absolute dimensions.
There's no obvious CSS answer. You would either need to use JavaScript to calculate values or do something tricky. You can try keeping the background-position:25% center and adding position:relative;left:-50px or margin-left:-50px but those might not work depending on how you are using the DOM element.
The only method I've found for this is to have the background inside another div, then use javascript to reposition ...
<style>
body {
width: 100%;
overflow: hidden;
}
#bg {
position: absolute;
background: url(images/background.jpg) center top;
}
</style>
<script>
function recenter(){
var $pos = $('#content').offset().left;
$('#bg').css('left',$pos-580);
}
recenter();
$(window).resize(function(){ recenter(); });
</script>
<body>
<div id="bg"></div>
<div id="content">
blah
</div>
</body>
if you know the width of the image you can use this:
background-position: (BgWidth - 50)px 0px;
Note that you can't have it like that, i.e. you need to calculate (BgWidth - 50) and then write the number there.
If you don't know the width you can use Javascript(with-or-without jQuery) and then use this:
$(#ID).css('background-position', (BgWidth - 50)+'px 0px');
Nice answer Luke,
one more thing, if your block width is larger than screen resolution, your must put your block in another container and do this:
#container{
position:relative;
overflow:hidden;
}
#shadowBox{
width: 100%;
left: -100px; /* this must be TWICE the required offset distance*/
padding-right: 100px; /* must be the same amount as above */
background-image: url("background-image.png");
background-position: center;
background-repeat: no-repeat;
position:absolute: /*this is needed*/
}
My answer gotta be too late but somehow I've found another solution.
padding-left: 100px; /* offset you need */
padding-right: 100%;
or
padding-right: 100px;
padding-left: 100%;
The examples have the same effect.