响应精灵/百分比

时间:2014-02-16 11:02:59

标签: css css3 sprite

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

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

当然,它没有用。我不明白当background-size不是auto时,如何得到background-position-x,background-position-y(我的数字来自“auto”大小精灵表),或者背景大小如何与div大小的百分比有关。
我可以使用任何数学公式吗?任何人都可以解释我或给我一些网站/书籍的名称,我可以在那里学习它?
谢谢,

9 个答案:

答案 0 :(得分:27)

更新@ vals'回答。他的一些计算对我来说并不适合。

背景大小的计算工作,除了他乘以1000而不是100来得到最终的百分比数字。所以12500%应该是1250%,依此类推。 (更新:2015年10月 - @vals在他的回答中更正了这一点。)

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

所以而不是:

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

这样做:

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

其中:

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

80px是显示图像的宽度

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

无论如何,这对我有用!

答案 1 :(得分:17)

div维度不会在微积分中播放,只会在背景大小和您将要使用的部分中播放。

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

您要使用的图像宽度和高度均为80像素。

背景大小:

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

background-size: 1250% 625%;

<强>背景位置:

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

background-position: 17.3% 58.6%;

答案 2 :(得分:14)

我写了Responsive CSS Sprite Generator来照顾你的所有工作。你可以上传一堆图像,它会给你一个精灵图像和它的CSS。

它使用一种新颖的方法使精灵响应 - 一个带有透明PNG的数据src,使图像保持其纵横比,所以与其他方法不同,图像不需要是方形的,或者都是相同的比。

答案 3 :(得分:4)

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

跨浏览器,自适应调整CSS精灵图像的大小/拉伸

此方法不依赖于背景大小,因此它可以在较旧的浏览器中使用。

  

<强> Stretchy Sprites

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

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

  • 设置可见的精灵:将.sprite的左侧值设置为: 0 =第一个精灵 -100%=第二个精灵 -200%=第3次精灵 等等... 简单!

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

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

答案 4 :(得分:3)

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

.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;
}

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

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

您的图片现在已完全响应,只需播放宽度值(以百分比表示),放大或缩小,这就是全部,您拥有完全响应的css精灵。

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

答案 5 :(得分:2)

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

答案 6 :(得分:0)

我花了很多时间寻找这个问题的答案,我出来了这个解决方案,至少现在它对我有用,是基于固定的像素盒大小,水平精灵,将是一个烂摊子无论如何都要使用百分比,因为你必须对该百分比的像素值进行数学计算,对于随机定位的精灵,因为你必须在图像中找到精灵的随机位置,太多的数学我相信一个简单的任务。

你需要:

  • 了解图片宽度(compass image-width($image)
  • 原始像素大小和图像内部精灵的位置(Photoshop可以解决)
  • 包含框的大小与您要显示的相应精灵成比例
  • 当然还有你想要应用于特定精灵的伸展量。

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

请查看并给我一些反馈意见:

//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

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

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