CSS3 background customize is a powerful tool, but it lacks one feature for me. I can set background-position in few ways, but I need some combinations of those. For example, there is a dynamically re-sized div, and I need a right-center oriented image which is 15px from the right border. I can not find any way to handle this.
I could use two fixes, none of them are elegant.
1. I leave a blank 15px area on the picure's right side.
2. I use this: background-position: 97% 50%
But, in the second case, if the div is re-sized, the calculated right margin will be incorrect.
Or, I use a standard image instead of bg-image, but I try to avoid this.
So, is there any solution?
Thanks!
CSS3 extends background-position to allow for that. For example, you can do:
background-position: right 15px bottom 15px;
Unfortunately, only Opera currently supports this.
However, the common reason you want that, is that you have a 15px padding. If that's the case, you can just do:
background-origin: content-box;
background-position: right bottom;
which is supported by every CSS3 browser.
Related
I've run into an issue when using background-position in a div along with background-size: cover. There seem to be some quirks in the browsers calculations, so I'm looking for a reliable way of doing this.
More detail...
The use case is mostly visual and everything in the interface should scale nicely. In the past I've has good results by either using rem or em units for everything.
At the start or when the screen size changes I'm measuring the available screen space and then set an appropriate font-size on the container. Something like this...
const size = calculateSize();
$("#container").css({fontSize: size + 'px'});
Generally, it works very nicely. Everything scales and positions itself properly - or does it?
I recently added a graphic button - a with a background image.
.button {
background-image: url("img/button.png");
background-size: cover;
width: 10em;
height: 4.5em;
cursor: pointer;
}
.button:hover {
background-position-x: -100%;
}
I did also try background-position-x: -10em, but I prefer the percentage notation as it takes care of itself if I resize the button image.
That's when I started noticing a small, but annoying problem. When I hover over the button, it moves just a little bit. The amount varies depending on how large the available space is. It's usually only a pixel or 2 at the most. It seems equally affected by Chrome, Firefox, and Edge.
It might not seem like much, and maybe I can just accept it as a feature, but I'm wondering if anyone else has experienced this and found a way around it.
One likely solution would be to just use separate images for the different button states, but I prefer keeping the number of images to a minimum.
UPDATE: So, I just tried creating 2 separate images, and then changed the CSS accordingly...
.button {
background-image: url("img/button0.png");
background-size: cover;
width: 10em;
height: 4.5em;
cursor: pointer;
}
.button:hover {
background-image: url("img/button1.png");
/* background-position-x: -100%; */
}
This does make the wobble movement go away, so I'm pretty confident it's some specific issue with how the browser is interpreting background-position-x. Being such a small movement, I suspect it's some sort of rounding error.
Minimal, Reproducible Example:
In an attempt to ensure I wasn't just seeing things, I put together a jsFiddle that illustrates the problem...
https://jsfiddle.net/xtempore/nfLh86sm/8/
I made a simplified version of the button image. It's just black on the left half and very pale grey on the right. Then I put it into 4 different divs each with a different font-size.
When you hover, you should just see the rectangle change from black to grey. And on the 1st and 3rd ones it does. But check out the 2nd and 4th ones! When you hover, there's a sneaky little bit of black appears on the left-hand edge.
The units used are pretty straightforward in this case. The problem seems to appear with odd-numbered pixels. In my case sometimes these font-sizes will also include decimals (e.g. 15.45px).
This problem demonstrates an issue with rendering in the common browsers (Chrome, Firefox, Edge), but I managed to find an alternate method that gives the desired result.
Instead of using...
background-size: cover;
... you can use a percentage, for example ...
background-size: 200%;
If your base image is 2 sprites wide, i.e. contains two images for different states side-by-side, then the specified background-size should be 200%. Similarly, if you have 3 times the size, 300%, and so on.
This gives the desired scaling, even as the div changes size.
You can see that the problem is resolved in the example fiddle by just changing that value from cover to 200%.
With problem: https://jsfiddle.net/xtempore/nfLh86sm/8/
No problem: https://jsfiddle.net/xtempore/2vcg4h1L/
I hope this helps someone else who is getting these weird side-effects.
I've got a blueprint that I want to absolutely position divs on top of in order highlight certain rooms.
Using the alpha channel (rgba), I can still see the blueprint's "ink" underneath, but depending on the color saturation the drawing gets obscured.
I know that I can use background-blend-mode: multiply on the div that contains the blueprint in order to get the desired effect, but it applies it to the entire image because I have to specify the color and the image on the same div. This is hard to explain but easy to show, so I mocked it up with paint.net here:
Again, I can get the desired look using background-blend-mode but would apply it to the entire background image. I want the color from a div to multiply everything that is underneath it.
Well, I started off writing this question and found out that it is a browser support issue. I eventually found mix-blend-mode which is what will apply blending modes to everything "underneath" a div/element, unfortunately, Chrome (as of today) doesn't support it. Firefox, however, does. It is possible to turn it on in chrome going to chrome://flags/ and enable "experimental Web Platform features".
I found the following link pretty helpful in general, I just didn't realize that they talk about both background-blend-mode and mix-blend-mode. http://css-tricks.com/basics-css-blend-modes/
Here is a screenshot of it working in firefox:
An alternative is to use background-blend-mode, and play with the background-image properties.
Not a very nice solution, but can get you going before waiting from Chrome next release
.test {
width: 400px;
height: 200px;
background-image: linear-gradient(lightgreen, lightgreen), url(http://i.stack.imgur.com/DfAyW.png);
background-blend-mode: multiply;
background-size: 100px 140px, cover;
background-position: 10px 40px, 0px 0px;
background-repeat: no-repeat;
}
<div class="test"></div>
I've never before run into a CSS problem I couldn't seem to figure out, but I'm just baffled by this one. I have a element in which I'd like to have a fixed background image, and I'm intentionally using an image that's quite a lot larger than the element because I'm not using media queries for this particular project, but rather just want to have the image scale to the element width. For some reason, however, when I switch the background-attachment to fixed, the image uses the boundary of the parent element as it's reference point.
I'm using the Foundation 4 framework (I use it all the time), and as such the parent element is a row class, so that's worth noting, but I can't figure out what about that might cause this problem. Here's the style definition I'm using (I've broken the background declaration apart for trouble-shooting). Ideas, anyone?
#page-content {
min-height: $publicContentHeight;
background-color:rgba(255,255,255,0.25);
background-image: url('../img/paper_phren/pages.bg.fludd.png');
background-repeat: no-repeat;
background-position: 0 0;
background-size:contain;
background-attachment: fixed;
box-shadow:0px -5px 10px rgba(0,0,0,.3);
}
Hard to say without seeing your use case, but I've found that background-size doesn't work well for scaling an image to fit the width of any screen size without overflowing it's container. What most seem to do, and what I've now adopted, is just using an img element for the background. Yes, it's not as semantically accurate, but the control you gain is beyond worth it. Microsoft.com along with many others are using this for scalable background images.
Are you trying to fill the element and therefore don't mind if the background image scales outside of the element on either the height or width depending on the ratio? If yes, try: background-size:cover;
Foundation + off-canvas + chrome + background-attachment: fixed = problem. Or so I have heard....
http://foundation.zurb.com/forum/posts/1799-an-off-canvas-story
"1- Only in chrome for windows(or so internet say): background-attachment: fixed behave wierd with animations. Specially if you wrap a self animated offcanvas around all your fixed backs.
Notice: this has nothing to do with Zurb, but with chrome."
I need a little help with breaking down someone's shorthand to longhand.
Here's what I've been given:
background: url("img.png") repeat scroll 0 0%, -moz-linear-gradient(#4E4E4E, #1C1C1C) repeat scroll 0 0 transparent;
I've gotten this far:
background-image:url('jAGNPCMaDe9LJ5wqwVhLimg.png');
But the rest is definitely greek to me.
I'm curious about the -moz-linear-gradent(). Is this something all browsers recognize? And I'm guessing the colors in the parenthesis must apply a gradient effect (deducing from -moz-linear-gradient)
And what does "repeat scroll 0 0%" do?
As cimmanon has mentioned, you're actually looking at two backgrounds combined into a single background shorthand declaration. The comma separates the two layers. This combination of multiple backgrounds is new to CSS3. So, you have two distinct background layers in shorthand notation:
url("img.png") repeat scroll 0 0%
-moz-linear-gradient(#4E4E4E, #1C1C1C) repeat scroll 0 0 transparent
And each expands to its own set of values.
The correct longhand expansion of your code is this:
background-image: url("img.png"), -moz-linear-gradient(#4E4E4E, #1C1C1C);
background-repeat: repeat, repeat;
background-attachment: scroll, scroll;
background-position: 0 0%, 0 0;
background-color: transparent;
Notice that, again, commas are used to separate multiple background layers. There is only one background-color because you cannot have multiple background colors.
Also as mentioned, the -moz- prefix is Mozilla's vendor extension used for its experimental implementation of linear gradients. However, unless your background declaration is repeated for all other applicable vendor extensions, your code will only work in Mozilla browsers and no other browser because of the vendor extension.
Note also that if you use the longhand code above instead of the shorthand, unsupporting browsers will only ignore the background-image declaration and apply everything else, unlike the shorthand which unsupporting browsers will ignore completely.
You're actually looking at multiple backgrounds there. The comma is the separator.
url("img.png") repeat scroll 0 0% /* on top */
-moz-linear-gradient(#4E4E4E, #1C1C1C) repeat scroll 0 0 transparent /* on bottom */
The gradient is taking the spot of the background image. The rest should be easy to figure out by reading up on the background property.
https://developer.mozilla.org/en-US/docs/CSS/background
Take a look at the Mozilla reference here and the main section here. These should provide you with a good "way in" and an explanation of the -moz-XXX prefix.
here's your longhand:
#element{
background-image:url(img.png);
background-repeat:repeat;
background-attachment:scroll;
background-position:0 0;
background-color:transparent
background-image:-moz-linear-gradient(#4E4E4E, #1C1C1C);
}
The -moz-linear-gradient only works in Mozilla. That is why it is pre-fixed with -moz-. As you guessed right it makes a linear gradient as background, instead of the picture. But only in Mozilla, all other browsers use the background rules. The options of the gradient don't need to be repeated, because they are the same as for every other browser.
Hi I have a 1px png file,which I am trying to set as a background image for two divs which are adjacent to each other horizontally.The html and css are as under:-
<div id='one'>hi</div>
<div id='two'>hello</div>
The css is like this
div {
width: 50%;
height: 50%
}
#one, #two {
background-image: url(/images/image.png);
background-repeat: repeat;
}
Now the problem here is in between the two divs a black border automaticaly appears when the image is set. I dont want the two divs to be seen as separate blocks.Please help. Am totally new to css and need help:-)!
I'd be willing to bet that the image you are using has alpha transparency (that is, the image is partially transparent), and what you're seeing is a one-pixel overlap between the two divs. Either make sure that the container is an even number of pixels wide, or put the divs inside another container and use the background on that instead.
like robert, i'm also not getting the border, but i do get some repeats.
see if this works for you:
#one, #two{
background-image:url(99785.jpg);
background-repeat: no-repeat;
borders: 0
}
The problem is caused by a couple of interacting things.
First, make sure you are using the html strict doctype. This will help mitigate a lot of the formatting issues between browsers around divs. See alistapart for a description and list of real doctypes to use and quirksmode for a detailed comparison of them.
Second, you will more than likely have to set the margin of your divs to 0. Browsers have different default settings. A strict doctype will alleviate most of this, but there are usually other areas you have to overcome as well.
Also, you might want to grab firebug for firefox and leverage chromes dev tools. firebug will actually show you what all of the margins / padding / everything else is being set to. The Chrome tools don't give you a pretty picture with the details but you can see what the margins/padding/etc are in the Computed Style section.