Converting from width to background-width in Less for sprites within CSS class
Just after posting this I looked into where the sprite function came from and found my answer in the generated sprite.less file:
.sprite-width(@sprite) {
width: ~`"@{sprite}".split(', ')[4]`;
}
.sprite-height(@sprite) {
height: ~`"@{sprite}".split(', ')[5]`;
}
The sprite.less file is generated using a mustache template. In order to solve my problem in Spritesmith you can specify a mustache template. It was also incorrect that I was looking at background-width and the property I needed was background-size. My attempts at inlining also failed, and I should have been looking at using a div rather than sizing the sprite component.
What's the math behind CSS's background-size:cover
Here's a logic behind cover calculations.
You have four base values :
imgWidth // your original img width
imgHeight
containerWidth // your container width (here 698px)
containerHeight
Two ratios derived from these values :
imgRatio = (imgHeight / imgWidth) // original img ratio
containerRatio = (containerHeight / containerWidth) // container ratio
You want to find two new values :
finalWidth // the scaled img width
finalHeight
So :
if (containerRatio > imgRatio)
{
finalHeight = containerHeight
finalWidth = (containerHeight / imgRatio)
}
else
{
finalWidth = containerWidth
finalHeight = (containerWidth / imgRatio)
}
... and you have the equivalent of a background-size : cover.
CSS3 background-size and background-position issue
The key to your problems is that percentage that you specify gives the point where the container and the image match. This point is calculated both in the image and in the container.
So, if you want the image centered, that means that the center of the image is in the center of the container. So, this is the value that you find by trial and error.
The key here is 50% as background-position always gets the image centered, and you don't need any of your calculations
If you specify 10% for the property, that would mean that the point at 10% from the left in the image is positioned at the point at 10% from the left in the container.
formula for this
How to convert from percentage to px (as requested).
Lets say that you have a container o size n and the image is greater by a factor of f You specify a background position of x%. We take this as an unitary factor a being a=x*100
The position to match in the container is an. The position to match in the image is afn. The position of the image from the container is the difference, afn-an , that can be given as an(f-1).
That explains why:
The apparent result of the property is inverted when f > 1 . (the image is bigger than the container.
The result is nil when f = 1 (the image is the same size than the container)
Now to convert that to space percentage, you just divide by the size of the container (n) to give
a(f-1)
or divide by the size of the image (fn) to give
a(f-1)/f
Position a background image outside an element using percent
Background position with percentage values is not easy.
You can see an explanation of the math involved here
In your case, the short answer is:
The background size is greater or smaller than the div by a factor of f. Then your percentage is 100 / (1 - f).
That means that:
- The backgound size is the same than the div. You are out of luck, it's not posible.
- The background is bigger. Say div=100 background=400, then f = 4 and the formula gives -33%. (first example in demo)
- The background is narrower. Say div=400 background=100, f=0.25 and the formula gives 133% (second example in the demo)
demo
Notice that in the demo the percentages are a little bit offset to show that the background is really there
css:
div.foo {
width: 100px;
background-size: 400px 100px;
background: red url(http://placekitten.com/400/100) no-repeat 50% 0;
height: 100px;
background-position: -32% 0; /* Disappear to the left */
}
div.foo2 {
width: 400px;
background-size: 100px 100px;
background: red url(http://placekitten.com/100/100) no-repeat 50% 0;
height: 100px;
background-position: 132% 0; /* Disappear to the left */
}
HTML background image offset by x pixels from the center
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 math functions to get integer values
There is a simple workaround to the problem using temporary variable and 0px
hack.
.foo {
@height: 20px;
@iconHeight: 13px;
@result: `Math.ceil((parseInt('@{height}') - parseInt('@{iconHeight}')) / 2)`;
background-position: 0 (0px + @result);
}
Related Topics
CSS Selector for Shadow Root or All Top Level Elements in Shadow Root
How to Make a Div Adopt The Height of The Screen
How to Center an Image in Bootstrap
How to Style The Input Type "Time"
Putting Buttons and Links Over Particles.Js Script (Z-Index)
Fixed Positioned Div Is Extending Outside of HTML & Body
How to Stop Manual Input in a Type=Number But Still Allow Changes with The "Up/Down" Buttons
Chrome Incorrectly Rendering Pixels as Fractions
Image Align Attribute in HTML 5
How to Change a Div Padding Without Affecting The Width/Height
Simple Two Column HTML Layout Without Using Tables
Distributing Images Evenly & Horizontally in a Div via CSS
Div Scrollbar - Any Way to Style It
CSS - Internet Explorer and The <Main> Tag Background