CSS 响应精灵/百分比

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21810262/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 01:52:55  来源:igfitidea点击:

responsive sprites / percentages

csssprite

提问by user3097405

I've read every single question about responsive sprites using css, I saw jsfiddle with working examples of responsive sprites, but I still cannot understand how to get the percentage of background-position and of background-size, how to use a wrapper (some people say it is necessary) around the div that uses background-image and why to use it...
For instance, if I have a div that has width:20% (say 40px) and is a circle. The image I need to use as background-image has 80px width (a circle, and I need to resize it to fit my div) and is one of the 40 images I have in my sprite sheet. It is at the position -173px -293px.
I really have no clue how to make it work.
I tried:

我已经阅读了有关使用 css 的响应式精灵的每个问题,我看到了 jsfiddle 与响应式精灵的工作示例,但我仍然无法理解如何获得背景位置和背景大小的百分比,如何使用包装器(一些人们说这是必要的)围绕使用背景图像的 div 以及为什么使用它......
例如,如果我有一个宽度为 20%(比如 40px)并且是一个圆圈的 div。我需要用作背景图像的图像有 80 像素的宽度(一个圆形,我需要调整它的大小以适合我的 div)并且是我的精灵表中的 40 个图像之一。它位于-173px -293px 的位置。
我真的不知道如何使它工作。
我试过:

div {
  width:20%;
  border-radius:50%;
  background: url('images/sprites.png') no-repeat 72.083% 67.981%;
  background-size: 50%;
  }

Of course, it did not work. I don't understand how to get the background-position-x, background-position-y (the numbers I have are from the "auto" size sprite sheet) when the background-size is not auto, or how the background-size relates to the percentage of the div size.
Is there any mathematical formula that I can use? Can anyone please explain me or give me a name of some website/book where I can learn it?
Thanks,

当然,它没有奏效。当背景大小不是自动时,我不明白如何获得背景位置x,背景位置y(我拥有的数字来自“自动”大小的精灵表),或者背景大小如何与 div 大小的百分比有关。
有什么数学公式可以使用吗?任何人都可以解释我或给我一个可以学习它的网站/书籍的名称吗?
谢谢,

采纳答案by vals

The div dimension doesn't play in the calculus, only the background sizes, and the part that you are going to use.

div 维度不参与微积分,只与背景大小以及您将要使用的部分有关。

Lets say that your background has a width of 1000px and a height of 500px.

假设您的背景宽度为 1000 像素,高度为 500 像素。

The image that you are going to use has 80px width and height.

您将要使用的图像具有 80 像素的宽度和高度。

background-size:

背景尺寸:

x part     1000px / 80px = 12.5   ->> 1250%
y part      500px / 80px = 6.25   ->>  625%

background-size: 1250% 625%;

background-position:

背景位置:

x-part     173px / 1000px = 0.173   ->> 17.3%
y part     293px / 500px = 0.586    ->> 58.6%

background-position: 17.3% 58.6%;

回答by ChillyPenguin

An update to @vals' answer. Some of his calcs didn't quite work for me.

@vals 答案的更新。他的一些计算对我来说不太适用。

The background-size calcs worked, except that he was multiplying by 1000 instead of 100 to get the final percentage figures. So 12500% should be 1250% and so on. (Update: 10/2015 - it looks like @vals has corrected this in his answer.)

背景大小的计算有效,除了他乘以 1000 而不是 100 以获得最终百分比数字。所以 12500% 应该是 1250% 等等。(更新:10/2015 - 看起来@vals 在他的回答中更正了这一点。)

The background-position X value calcs were very slightly out for me. They didn't match what was generated by spritecow.com (as per Adrian Florescu's suggestion). This is, I think, because absolute coordinates are calculated from the left of the background image, whereas with percentages, you have to calculate from the right of the background image. That being the case, you have to subtract the image width from the overall background width beforeyou divide the absolute x-pos number with it.

背景位置 X 值计算对我来说非常轻微。它们与 spritecow.com 生成的内容不匹配(根据 Adrian Florescu 的建议)。我认为这是因为绝对坐标是从背景图像的左侧计算的,而对于百分比,您必须从背景图像的右侧计算。在这种情况下,您必须先从整体背景宽度中减去图像宽度,然后再用绝对 x-pos 数除以它。

So instead of:

所以而不是:

x-part 173px / 1000px = 0.173 ->> 17.3%

do this:

做这个:

x-part 173px / (1000px - 80px) = 0.1880434783 ->> 18.80434783%

Where:

在哪里:

1000px is the width of the background image (sprite)

1000px 是背景图片(精灵)的宽度

80px is the width of displayed image

80px 是显示图像的宽度

173px is the absolute x-coordinate of the displayed image.

173px 是显示图像的绝对 x 坐标。

This is what works for me, anyway!

无论如何,这对我有用!

回答by Greg

I've written a Responsive CSS Sprite Generatorto take care of all the work for you. You can just upload a bunch of images and it will give you a sprite image and the CSS for it.

我编写了一个响应式 CSS 精灵生成器来为您处理所有工作。你可以只上传一堆图片,它会给你一个精灵图片和它的 CSS。

It uses a novel method for making the sprites responsive - a data src with a transparent PNG to make the image maintain its aspect ratio, so unlike other methods the images don't need to be square, or all the same ratio.

它使用一种新颖的方法来使精灵具有响应性 - 带有透明 PNG 的数据 src 使图像保持其纵横比,因此与其他方法不同,图像不需要是方形的,或完全相同的比例。

回答by Andres Separ

This is the best responsiveexample I have found to solve the problem of sprite!

这是我找到的解决精灵问题的最佳响应示例!

Cross-browser, responsive resizing/stretching of CSS sprite images

跨浏览器、响应式调整大小/拉伸 CSS 精灵图像

This method does not rely on background-size, so it will work in older browsers.

此方法不依赖于 background-size,因此它可以在较旧的浏览器中使用。

Stretchy Sprites

有弹性的精灵

  • This example uses an image that is 800 wide x 160 high. This image contains 6 equal size sprites (160x160 each).

  • If your sprite size is different all you need to change is the max-width property of .sprite to match the individual sprite width.

  • To set the visible sprite: Set the left value of .sprite to: 0 = 1st sprite -100% = 2nd sprite -200% = 3rd sprite etc... Easy!

  • If you want images to stretch larger than their natural size: Add the class .no-limit to .stretchy. This removes max-width:160px from .stretchy and add min-height:100% to .sprite Alternatively you could set a larger max-width using a px value, e.g. 300px.

  • The spacer image can be any size, as long as it is propotional to the dimensions of the individual sprites.

  • 此示例使用 800 宽 x 160 高的图像。该图像包含 6 个大小相同的精灵(每个 160x160)。

  • 如果您的精灵大小不同,您需要更改的是 .sprite 的 max-width 属性以匹配单个精灵宽度。

  • 设置可见精灵: 将 .sprite 的左值设置为: 0 = 1st sprite -100% = 2nd sprite -200% = 3rd sprite 等等……简单!

  • 如果您希望图像拉伸得比其自然尺寸大:将类 .no-limit 添加到 .stretchy。这会从 .stretchy 中删除 max-width:160px 并将 min-height:100% 添加到 .sprite 或者您可以使用 px 值设置更大的 max-width,例如 300px。

  • 间隔图像可以是任何尺寸,只要它与单个精灵的尺寸成正比。

回答by Edouard Kombo

This is a simpler solution, check this

这是一个更简单的解决方案,检查这个

.my_picture{
    //target your sprite
    background: url(my_img.jpg) no-repeat;

    //Specify it full image
    backgound-size: 100%;

    //Position of the targeted picture
    background-position: left 0 bottom x%;

    //Zoom in or out on the position
    width: x%;

    //Scale height by playing with padding
    padding-bottom: x%;

    //Set height to 0 because of sprite size
    height: 0;
}

How does it work? To target any sprite pictures easily, we have to specify sprite size to original, “100%”. We will then target a picture position from corresponding bottom, with left 0.

它是如何工作的?为了轻松定位任何精灵图片,我们必须将精灵大小指定为原始“100%”。然后我们将从对应的底部定位一个图片位置,左侧为 0。

Because the sprite size is set to max 100%, we have to disable height, and the only option to set height now, is to play with padding-bottom, in percentage too.

因为精灵大小设置为最大 100%,我们必须禁用高度,现在设置高度的唯一选项是使用 padding-bottom,百分比也是。

Your image is now fully responsive, just play with width values (in percentage), to zoom in or out, and that's all, you have a fully responsive css sprite.

您的图像现在完全响应,只需使用宽度值(百分比),放大或缩小,就这样,您就有了一个完全响应的 css sprite。

Original article on my blog here: http://creativcoders.wordpress.com/2014/05/05/css-responsive-sprites/

我博客上的原始文章:http: //creativcoders.wordpress.com/2014/05/05/css-responsive-sprites/

回答by Ankur Aggarwal

You can use websites to find out the exact coordinates of your sprite. I personally use http://www.spritecow.com/

您可以使用网站来找出精灵的确切坐标。我个人使用http://www.spritecow.com/

回答by wolfitoXtreme

I spent a lot of time looking for an answer on this matter, I came out with this solution, it works for me at least for now, is based on fixed pixel box-sizing, and horizontal sprites, will be a mess with percentage anyway because you will have to do the math for the pixel values for that percentage, and for random located sprites because you will have to find the randomlocation of the sprite inside the image, too much math for a simple task I believe.

我花了很多时间寻找关于这个问题的答案,我提出了这个解决方案,至少现在对我有用,基于固定像素框大小和水平精灵,无论如何都会弄乱百分比因为您必须为该百分比的像素值和随机定位的精灵进行数学运算,因为您必须在图像内找到精灵的随机位置,我相信对于一个简单的任务来说,数学太多了。

You need:

你需要:

  • Know the image width (compass image-width($image))
  • The original pixel size and location of the sprite inside the image (Photoshop does the trick)
  • The size of the containing box proportional to the corresponding sprite you are intended to show
  • And of course the amount of stretch you want to apply to the specific sprite.
  • 知道图像宽度 ( compass image-width($image))
  • 图像中精灵的原始像素大小和位置(Photoshop 做到了这一点)
  • 包含框的大小与您打算显示的相应精灵成比例
  • 当然还有你想应用于特定精灵的拉伸量。

As a piece of advice, you will have to leave at least 1px of physical margin between each image because percentages produce not integer pixels, and you will end up with overlaping sprites!! ;)

作为一条建议,您必须在每个图像之间留出至少 1px 的物理边距,因为百分比产生的不是整数像素,并且最终会出现重叠的精灵!!;)

Check it out and give me some feedback please:

检查一下并给我一些反馈,请:

//functions

//stretch by percentage
@function stretchImage($width, $height, $percentage) {

    $s_width: round( ($width * $percentage) / 100 );
    $s_height: round( ($height * $percentage) / 100 );

    @return ($s_width, $s_height);
}

//strip units
//(Eric M Suzanne) http://stackoverflow.com/questions/12328259/how-do-you-strip-the-unit-from-any-number-in-sass
@function strip-units($number) {
  @return $number / ($number * 0 + 1);
}

//replace in string
//(css tricks) http://css-tricks.com/snippets/sass/str-replace-function/
@function str-replace($string, $search, $replace: '') {
    $index: str-index($string, $search);

    @if $index {
        @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
    }

    @return $string;
}

//get unitless percentage
@function getPercentageFrom($valueA, $valueB) {

    $percentage: percentage(strip-units($valueA)/strip-units($valueB));

    @return ($percentage);
}


//now the magic

//we know the witdh of the image containing the sprites 
$image: url(http://www.cssguy4hire.com/codePenAssets/sprite_test.png);
$image_width: 965px;

//the amount of strech we want to aply
$stretchTo: 175;

//we know the current sprite measures we  going to set 
$sprite_width: 150px;
$sprite_height: 150px;
//left is 0 cuz is first sprite                
$sprite_left: 0%;                

//stretch sprite                            
$stretch: stretchImage($sprite_width, $sprite_height, $stretchTo);
$width: nth($stretch, 1);                
$height: nth($stretch, 2);                

//set background size and position          
$bkg-size: getPercentageFrom($image_width * ($stretchTo / 100), $width);

//default position 0
$bkg_left: $sprite_left;              


//compose the css
#image {
    margin: auto;
    width: $width;
    height: $height;
    position: relative;
    display: block;
    background: #00f00f $image $bkg_left 0 no-repeat;
    background-size: $bkg-size;
    border: 5px solid #cccccc;

    //we chage the sprite
    &.sprite_1 {

        //the amount of strech we want to aply
        $stretchTo: 250;

        //we know the current sprite measures we  going to set 
        //0 is te first sprite starting left to right
        $sprite_width: 250px;
        $sprite_height: 75px;
        $sprite_left: 150px;              

        //stretch sprite                            
        $stretch: stretchImage($sprite_width, $sprite_height, $stretchTo);
        $width: nth($stretch, 1);                
        $height: nth($stretch, 2);                

        //set background size        
        $bkg-size: getPercentageFrom($image_width * ($stretchTo / 100), $width);
        $bkg_left: percentage($sprite_left / ($image_width - $sprite_width) );

        //compose the css
        width: $width;
        height: $height;
        background-size: $bkg-size;
        background-position: $bkg_left 0;

    }

    &.sprite_2 {

        //the amount of strech we want to aply
        $stretchTo: 80;

        //we know the current sprite measures we going to set 
        $sprite_width: 140px;
        $sprite_height: 120px;
        $sprite_left: 400px;              

        //stretch sprite                            
        $stretch: stretchImage($sprite_width, $sprite_height, $stretchTo);
        $width: nth($stretch, 1);                
        $height: nth($stretch, 2);                

        //set background size        
        $bkg-size: getPercentageFrom($image_width * ($stretchTo / 100), $width);
        $bkg_left: percentage($sprite_left / ($image_width - $sprite_width) );

        //compose the css
        width: $width;
        height: $height;
        background-size: $bkg-size;
        background-position: $bkg_left 0;

    }

    &.sprite_3 {

        //the amount of strech we want to aply
        $stretchTo: 125;

        //we know the current sprite measures we going to set 
        $sprite_width: 290px;
        $sprite_height: 134px;
        $sprite_left: 540px;              

        //stretch sprite                            
        $stretch: stretchImage($sprite_width, $sprite_height, $stretchTo);
        $width: nth($stretch, 1);                
        $height: nth($stretch, 2);                

        //set background size        
        $bkg-size: getPercentageFrom($image_width * ($stretchTo / 100), $width);
        $bkg_left: percentage($sprite_left / ($image_width - $sprite_width) );

        //compose the css
        width: $width;
        height: $height;
        background-size: $bkg-size;
        background-position: $bkg_left 0;

    }

    &.sprite_4 {

        //the amount of strech we want to aply
        $stretchTo: 153;

        //we know the current sprite measures we going to set 
        $sprite_width: 135px;
        $sprite_height: 56px;
        $sprite_left: 830px;              

        //stretch sprite                            
        $stretch: stretchImage($sprite_width, $sprite_height, $stretchTo);
        $width: nth($stretch, 1);                
        $height: nth($stretch, 2);                

        //set background size        
        $bkg-size: getPercentageFrom($image_width * ($stretchTo / 100), $width);
        $bkg_left: percentage($sprite_left / ($image_width - $sprite_width) );

        //compose the css
        width: $width;
        height: $height;
        background-size: $bkg-size;
        background-position: $bkg_left 0;

    }

}

http://codepen.io/wolfitoXtreme/pen/BymKyP

http://codepen.io/wolfitoXtreme/pen/BymKyP

回答by eivers88

My approach is similar to Greg's in that I wrote a tool to generate responsive css sprites. I however have taken it one step further and added a sorting algorithm so you can pack more images efficiently onto a png.

我的方法类似于 Greg 的方法,因为我编写了一个工具来生成响应式 css sprite。然而,我更进一步并添加了一种排序算法,以便您可以有效地将更多图像打包到 png 上。

Here is the Responsive CSS Sprite Generator Tool: https://responsive-css.us/

这是响应式 CSS 精灵生成器工具:https: //responsive-css.us/

回答by Bambino Negro

From a large FE experience, I've developed responsive sprites framework that does not rely on background-image, but instead it uses "physical" image in a container that is scaled like original image/part of sprites. The problem with css bgd-img is calculating size and position and its often for css to "miss" pics possition for few pixels. Most of the browsers renders these values at 0.1px, but rounds it as well. So the precision is (about 1/2 of the px). This missmatch multiplies when you try to scale it (to make it responsive).- so dont be fooled by "responsive sprites" that rely on css background-image. They're just a bad and displaced display of sprites image you need. - The JavaScript (framework) is far more precisious - (1/100px), and its solid ground for responsive images - as you have 1/50 size to scale pics and not loose any pixel. I'm not advertising this, If anyone is interested - take a look at: responsive-sprites.com

根据大型 FE 经验,我开发了不依赖于背景图像的响应式精灵框架,而是在容器中使用“物理”图像,该容器的缩放比例类似于原始图像/精灵的一部分。 css bgd-img 的问题是计算大小和位置,css 通常会“错过”几个像素的图片位置。大多数浏览器将这些值呈现为 0.1 像素,但也会对其进行四舍五入。所以精度是(大约像素的1/2)。 当您尝试对其进行缩放(以使其具有响应性)时,这种不匹配会成倍增加。- 所以不要被依赖 css 背景图像的“响应精灵”所迷惑。它们只是您需要的精灵图像的不良和移位显示。- JavaScript(框架)要精确得多 - (1/100px),它是响应式图像的坚实基础 - 因为你有 1/50 的尺寸来缩放图片并且不会丢失任何像素。我不是在做广告,如果有人感兴趣 - 看看:responsive-sprites.com