with the background-position property, where is the 50% position decision? - css

in the following example an image created with background-image has an even width (4 pixels) .
It is placed in the middle (50%) of the div element containing it. This element has an odd size (9pixels).
result:
the image has 3 pixels to its left and 2 to its right.
it could have been 2 pixels to its left and 3 to its right.
My question is not why. My question is where are the documents that specify this type of CSS decision?
#a {
background-position: 50% 50%;
background-image: linear-gradient(red,red);
width: 9px;
height: 10px;
image-rendering: pixelated;
background-color: black;
background-repeat: no-repeat;
background-size: 4px 6px;
}
<div id="a"></div>

Related

Background image with a colored curved border at the bottom

I am trying to achieve this with css3, I tried using border-radius with percent values and it's not the same always, I always got a rounded corners and the border will start disappearing on the corners too.
I want it to be exactly the same as the example image:
EDIT:
this is my html code :
<div class='container-fluid'>
<section class='section-1'>
<div class='container'>
</div>
</section>
And this is my css:
.section-1 {
background-image: url('../images/bg.png');
background-size: cover;
background-repeat: no-repeat;
position: relative;
background-position: 50%;
}
If you want, you can accomplish this using only CSS by creating a <div> that would be used only as a mask. You can create the round effect with the border-radius property, but you need to do it bigger than the part that will be visible, then crop the result to show only the curvy part that you want. And you must compensate the imagem position.
Check my example below:
.oval-header {
width: 100%;
height: 150px;
overflow: hidden;
position: relative
}
.oval-header--mask {
width: 200%; /* Mask width 2x the size of the header */
height: 200%; /* Mask height 2x the size of the header */
transform: translate(-25%, -51%); /* This compensates the size of the image and places the curvy part that you want on the certer of the mask, it's a translate that negativates half it's width and half it's height */
border: 6px solid yellow;
border-radius: 0 0 50% 50%;
overflow: hidden;
border-top: 0;
background-image: url('http://www.placecage.com/3000/1500');
background-size: cover
}
<div class="oval-header">
<div class="oval-header--mask">
</div>
</div>

How is background-size percentage calculated?

I have a sprite that I am using and I wanted to reuse one of the images in the sprite but at half the size so I thought if I just used background-size:50%;, it would resize the background by 50%, but it seemed to quarter the size for some reason:
.test {
background: url(https://i.stack.imgur.com/KaIav.png) left top no-repeat;
width: 112px;
height: 112px;
border: 1px solid red;
}
.test.half-size {
width: 56px;
height: 56px;
background-size: 50%;
}
<div class="test"></div>
<div class="test half-size"></div>
Now I can fix this by having the background size as 113%:
.test {
background: url(https://i.stack.imgur.com/KaIav.png) left top no-repeat;
width: 112px;
height: 112px;
border: 1px solid red;
}
.test.half-size {
width: 56px;
height: 56px;
background-size: 113%;
}
<div class="test"></div>
<div class="test half-size"></div>
But why is the background-size greater than 100% when the image is smaller than the original?
Is there a set calculation I can apply when figuring out how to resize the sprite?
As per the W3C Specs:
A percentage is relative to the background positioning area.
and background positioning area is one of either border-box or padding-box or content-box based on the background-origin property. Here you haven't specified any value explicitly for this and so its default value of padding-box is used. This element has no padding and so it's equal to content-box.
Your image is 126 x 112 px but width and height of the element is 56 x 56px, so a background-size: 100% (which is inferred as100% auto) would mean the image is scaled down till it has a width of 56px. Now to get to 56px, the width is scaled down by 44.44% of the image's original size. So, to preserve aspect ratio (as one value is auto), the height of the image is also scaled down to 44.44%, which is, 49.78px (or 50px approximately). As you can see the calculated background image's dimensions are 56px x 50px (and not 56px x 56px) and so it doesn't cover the box entirely. You can see this clearly in the below snippet.
.test {
background: url(https://i.stack.imgur.com/KaIav.png) left top no-repeat;
width: 56px;
height: 56px;
border: 1px solid red;
background-size: 56px 50px; /* see how this is same as 100% or 100% auto */
}
.test.t2 {
width: 56px;
height: 56px;
background-size: 100%;
}
.test.t3 {
width: 56px;
height: 56px;
background-size: 100% auto;
}
<div class="test"></div>
<div class="test t2"></div>
<div class="test t3"></div>
Note: The 56px width includes the white-spaces on the right side of the circle and so even though it covers the entire width of the element, you will still see a gap. This is due to the image itself having a space.
Now when you set background-size: 50% ( = 50% auto), it would mean the max width of the image can be 28px and so it is scaled down by 22.22%. This means the height is also scaled down 22.22%, which is, roughly 25px. This is why you see it as being almost quarter size (but not exactly quarter). This can again be seen visually in the below snippet:
.test {
background: url(https://i.stack.imgur.com/KaIav.png) left top no-repeat;
width: 56px;
height: 56px;
border: 1px solid red;
background-size: 28px 25px; /* again see how they are same */
}
.test.t2 {
width: 56px;
height: 56px;
background-size: 50%;
}
.test.t3 {
width: 56px;
height: 56px;
background-size: 50% auto;
}
<div class="test"></div>
<div class="test t2"></div>
<div class="test t3"></div>
When we set background-size: 113%, it means the the width can be max 113% of the container's width, which would be, 63.28px and this is roughly 50% of the original image's width. Since width is scaled down by 50% from the original image, its height is also scaled down by same amount and so the resulting value is 56px (which is nothing but the height of the element and so it covers the box vertically). Now, since you've also given the background-position as left-top, the image is placed with respect to the left edge of the container and so the white-space which is present on the right side of the image (the other 7.28px) is invisible as the box will not show anything more than its width.
You've already answered the second part of your question and so I'm not going over it again.
For Future Readers: For OP's case, it might not be possible to get rid of the white-spaces because it is part of a sprite but if your case is different and you can get rid of the spaces then that is the best.
If the white-spaces on the right side are removed and the image is cropped to its actual size (which is, 112 x 112px) then just setting background-size: 100% 100% (or even 100% auto) would be enough. The container element's dimensions when set as half or quarter (or whatever) size of the original will automatically do the scaling for us.
.test {
background: url(https://i.stack.imgur.com/UaCct.png) left top no-repeat;
width: 112px;
height: 112px;
background-size: 100% 100%;
border: 1px solid red;
}
.test.half-size {
width: 56px;
height: 56px;
}
.test.quarter-size {
width: 28px;
height: 28px;
}
<div class="test"></div>
<div class="test half-size"></div>
<div class="test quarter-size"></div>
After a lot of playing around with the sprite I have come to the conclusion that it is width of full sprite divided by width of sprite part and times it by 100 will give you the x-axis background size percentage and then do the same with height for the y-axis background size.
So in my case to get the x percentage, it was
( 126px / 112px ) * 100 = 112.5%
Full width of sprite width of sprite part
and to get the y percentage it was
( 112px / 112px ) * 100 = 100%
Full height of sprite height of sprite part
This means that a background-size: 112.5% 100% will work for any square div with that sprite:
.test {
background: url(https://i.stack.imgur.com/KaIav.png) left top no-repeat;
width: 112px;
height: 112px;
background-size: 112.5% 100%;
border: 1px solid red;
}
.test.half-size {
width: 56px;
height: 56px;
}
.test.random-size {
width: 90px;
height: 90px;
}
<div class="test"></div>
<div class="test half-size"></div>
<div class="test random-size"></div>

<DIV> with three background images

I need to place three different background images inside a div. At the top I want blue.png, then in the middle yellow.png (with repeat-y), and finally, red.png at the bottom.
So far, I have this Fiddle: http://jsfiddle.net/nwUPU/1437/. My problem is that yellow.png covers both blue.png and red.png. What am I doing wrong, please?
This example is used in responsive design. I do not know the width and height of the images.
.colors {
width:600px;
height:600px;
position: relative;
z-index: 2;
background: url("http://s9.postimg.org/47v6naitr/blue.png") center top no-repeat, url("http://s1.postimg.org/fgv3q86i7/red.png") center bottom no-repeat;
background-size: 100%;
}
.colors:before {
content: '';
position: absolute;
z-index: -1;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: url("http://s24.postimg.org/hyhdhfg51/yellow.png") center top repeat-y;
background-size: 100%;
}
It is possible to add multiple backgrounds to the same element by providing them as coma separated values to the background property. Each background image that is provided will be added as a layer and will be stacked one on top of another (also depending on the background-position).
The key things to note here are:
When multiple backgrounds are applied to the same element, the first one is the top-most layer and the one provided last is the lower-most layer. Since we need the yellow to be sort of below the red and blue, it should be provided as the last value.
To position the blue and red images at their respective positions, background-position should be set appropriately. Since blue should be the first from top, it should be positioned at 0% 0% and since the red needs to be last from top, it should be positioned at 100% 100%.
.colors {
width: 600px;
height: 600px;
position: relative;
background: url("http://s9.postimg.org/47v6naitr/blue.png") center top no-repeat,
url("http://s1.postimg.org/fgv3q86i7/red.png") center bottom no-repeat,
url("http://s24.postimg.org/hyhdhfg51/yellow.png") center top repeat-y;
background-size: 100%;
background-position: 0% 0%, 100% 100%, 0% 0%;
}
<div class="colors"></div>
Possibly add three divs inside your first. each with their own .png?
<div>
<div id="blue" style="z-index: 1;"><img src="blue.png"></div>
<div id="yellow"style="z-index: 2;"><img src="yellow.png"></div>
<div id="red" style="z-index: 1;"><img src="red.png"></div>
</div>

put background image in center and repeat last pixel to left and right

i want to put my background image in the center and repeat only the last left pixelcolumn to the left and the same for the right and the last pixelrow down.
so that if you zoom out you see this
-------------- repeat last pixel of the right of the picture to the right
| |
| |
--------------
^
|
here repeat to the left the first pixels to the left
and below the picture the lowest row of pixels repeat down.
i hope you understand what i mean...
minke
This pen illustrates how this is possible now with border-image, which had very poor support at the time this question was asked, but is supported on the latest version of all the major browsers: (IE11+, Firefox 15+, Chrome 16+, Safari 6+)
Basically, you use background-image to render the 'full' image, positioning it centered using background-position.
#container {
height: 100vh;
width: 100%;
margin: 0 auto;
padding: 0 20%;
box-sizing: border-box;
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/44521/light_minimalistic_soft_shading_gradient_background_1024x768_58884.jpg);
background-size: 61% 100%;
background-position: center 0;
background-repeat: no-repeat;
}
Then, you can use border-image for the repeated edges. Note the use of border-image-slice to grab only 1px of the edges on the sides.
#container {
border-width: 0 20% 0 20%;
border-image-source: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/44521/light_minimalistic_soft_shading_gradient_background_1024x768_58884.jpg);
border-image-slice: 2;
border-image-width: 2 20%;
border-image-repeat: stretch;
border-image-outset: 2px;
}
Live example on CodePen
Have a look at the link below.
Position a CSS background image x pixels from the right?
This is not the exact solution you are looking for, but it could have the same effect on SOME images you are looking for:
.bg {
background:url(../images/image.jpg),url(../images/image.jpg);
background-repeat: no-repeat, repeat;
background-position: 0px 0px;
background-position-x: center;
background-size: 1914px 100% , 1px 100%; // 1914px is the width of the image
}
Take a 1px-wide slice of the image and save it. This is the code I used for a sticky footer with a 196px-wide left portion, and a repeating 1px-wide right section:
footer {
background-image: url('../../images/footer-left.png'), url('../../images/footer-right.png');
background-repeat: no-repeat, repeat-x;
background-size: 196px 175px;
bottom: 0;
color: white;
height: 175px;
left: 0;
margin-bottom: 0;
padding-top: 75px;
position: fixed;
text-align: center;
width: 100%;
}

CSS limited background repeat (multiple background images)

I am trying to make a cool background effect (with alpha transparency and rounded corners) for a drop-down menu with a single CSS entry.
I have a top cap (180 x 4 px), a bottom cap (180 x 20px) and a repeating middle (180 x 2px).
Here is my existing relevant CSS:
background-image: url('images/drop_top.png'), url('images/drop_bottom.png'), url('images/drop_middle.png');
background-position:left top, left bottom, 0px 10px;
background-repeat:no-repeat, no-repeat, repeat-y;
The problem is that the middle section which needs to be expandable/tilable is repeating all the way under the top and bottom caps--such that my rounded corners are now square because they have the repeating middle under them.
Is there some way to prevent the multiple backgrounds from overlapping??
Thanks in advance!
Background-origin and/or background-clip should do the trick. Just set top & bottom borders equal to the height of your cap graphics, then set drop_middle to background-clip:padding-box
EDIT: Here is a complete solution, but for a horizontal orientation:
http://jsfiddle.net/nGSba/
#box
{
display: inline-block;
margin: 1em;
padding: 9px;
border-left:9px solid transparent;
border-right:9px solid transparent;
background-image: url(http://s11.postimage.org/ufpdknvjz/left.png),
url(http://s11.postimage.org/6ng294tj3/right.png),
url(http://www.css3.info/wp-content/themes/new_css3/img/main.png);
background-repeat: no-repeat, no-repeat, repeat-x;
background-position: left top, right top, left top;
background-origin: border-box,border-box,padding-box;
background-clip: border-box,border-box,padding-box;
}
What got me stuck was the transparent on the border-color. The background will always go under the border, so if your border is solid the background will still be invisible.
Whatever your element is that you are applying the images to, try doing the following (I'll assume div for sake of illustration):
div {
background-image: url('images/drop_top.png'), url('images/drop_bottom.png');
background-position:left top, left bottom;
background-repeat:no-repeat, no-repeat;
position: relative;
}
div:after {
position: absolute;
top: 10px ; /* whatever your top image height is */
bottom: 10px; /* whatever your bottom image height is */
left: 0;
right: 0;
z-index: -1;
background-image: url('images/drop_middle.png');
background-position: left top;
background-repeat: repeat-y;
}

Resources