web-dev-qa-db-ja.com

CSSスプライトで画像を拡大縮小するにはどうすればよいですか

この記事では、 http://css-tricks.com/css-sprites/ で、1つの大きな画像から小さな画像を切り取る方法について説明しています。可能かどうか、小さな画像を切り取り、レイアウトする前に切り取った領域を拡大縮小する方法を教えてください。

その記事の例を次に示します。

A
{
  background-image: url(http://www.jaredhirsch.com/coolrunnings/public_images/3deb155981/spriteme1.png);
  background-position: -10px -56px;
}

Spriteme1.pngから切り取った画像をどのように拡大縮小できるかを知りたい

例のURLは次のとおりです。 http://css-tricks.com/examples/CSS-Sprites/Example1After/

それで、Item1、2、3、4の横のアイコンを小さくできるかどうか知りたいですか?

151
michael

ほとんどのブラウザでサポートされているように、background-sizeを使用できます(ただし、すべてではありません http://caniuse.com/#search=background-size

background-size : 150% 150%;

または

zoomの組み合わせをwebkit/ieに使用し、transform:scaleをFirefox(-moz-)およびOpera(-o-)に使用して、クロスブラウザのデスクトップとモバイルに使用できます。

[class^="icon-"]{
    display: inline-block;
    background: url('../img/icons/icons.png') no-repeat;
    width: 64px;
    height: 51px;
    overflow: hidden;
    zoom:0.5;
    -moz-transform:scale(0.5);
    -moz-transform-Origin: 0 0;
}

.icon-huge{
    zoom:1;
    -moz-transform:scale(1);
    -moz-transform-Origin: 0 0;
}

.icon-big{
    zoom:0.60;
    -moz-transform:scale(0.60);
    -moz-transform-Origin: 0 0;
}

.icon-small{
    zoom:0.29;
    -moz-transform:scale(0.29);
    -moz-transform-Origin: 0 0;
}
125
aWebDeveloper

スプライトを使用する場合、スプライト内の画像のサイズに制限されます。 Stephenが言及したbackground-size CSSプロパティはまだ広くサポートされておらず、IE8以下のようなブラウザで問題を引き起こす可能性があります-そして、市場シェアを考えると、これは実行可能なオプションではありません。

この問題を解決する別の方法は、次のように、2つの要素を使用し、imgタグを使用してスプライトをスケーリングすることです。

<div class="Sprite-image"
     style="width:20px; height:20px; overflow:hidden; position:relative">
    <!-- set width/height proportionally, to scale the Sprite image -->
    <img src="Sprite.png" alt="icon"
         width="20" height="80"
         style="position:absolute; top: -20px; left: 0;" />
</div>

このようにして、外側の要素(div.Sprite-image)は、スケーリングされたbackground-imageのように動作するimgタグから20x20pxの画像をトリミングしています。

29
Alex Gyoshev

これを試してください: Stretchy Sprites-クロスブラウザ、CSS Spriteイメージのレスポンシブなサイズ変更/ストレッチ

このメソッドは、ブラウザウィンドウのサイズに応じて幅/高さが調整されるように、スプライトを「レスポンシブ」にスケーリングします。それは使用しませんbackground-size as support これは古いブラウザでは存在しないためです。

CSS

.stretchy {display:block; float:left; position:relative; overflow:hidden; max-width:160px;}
.stretchy .spacer {width: 100%; height: auto;}
.stretchy .Sprite {position:absolute; top:0; left:0; max-width:none; max-height:100%;}
.stretchy .Sprite.s2 {left:-100%;}
.stretchy .Sprite.s3 {left:-200%;}

HTML

<a class="stretchy" href="#">
  <img class="spacer" alt="" src="spacer.png">
  <img class="Sprite" alt="icon" src="Sprite_800x160.jpg">
</a>
<a class="stretchy s2" href="#">
  <img class="spacer" alt="" src="spacer.png">
  <img class="Sprite" alt="icon" src="Sprite_800x160.jpg">
</a>
<a class="stretchy s3" href="#">
  <img class="spacer" alt="" src="spacer.png">
  <img class="Sprite" alt="icon" src="Sprite_800x160.jpg">
</a>
19
tobyj

transform: scale();は、元の要素のサイズを保持します。

最適なオプションはvwを使用することです。それは魅力のように働いています:

https://jsfiddle.net/tomekmularczyk/6ebv9Lxw/1/

#div1,
#div2,
#div3 {
  background:url('//www.google.pl/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png') no-repeat;
  background-size: 50vw;   
  border: 1px solid black;
  margin-bottom: 40px;
}

#div1 {
  background-position: 0 0;
  width: 12.5vw;
  height: 13vw;
}
#div2 {
  background-position: -13vw -4vw;
  width: 17.5vw;
  height: 9vw;
  transform: scale(1.8);
}
#div3 {
  background-position: -30.5vw 0;
  width: 19.5vw;
  height: 17vw;
}
<div id="div1">
  </div>
  <div id="div2">
  </div>
  <div id="div3">
  </div>
10

これを行うために私がしたことは次のとおりです。 IE8以下では動作しないことに注意してください。

#element {
  width:100%;
  height:50px;
  background:url(/path/to/image.png);
  background-position:140.112201963534% 973.333333333333%;
}

背景画像の幅は、#elementの親が縮小するにつれて縮小します。 heightをパーセンテージに変換すると、高さでも同じことができます。唯一のトリッキーなビットは、background-positionのパーセンテージを計算することです。

最初の割合は、通常の幅にあるときのSpriteのターゲット領域の幅をSpriteの合計幅で除算し、100倍したものです。

2番目のパーセンテージは、スケーリングされる前のSpriteのターゲット領域の高さをSpriteの合計の高さで割って、100倍されます。

これらの2つの方程式の表現は少しずさんなので、説明が必要な場合はお知らせください。

7
user621994

古い投稿ですが、ここにbackground-size:cover;(@Ceylan Pamirへのヒント)を使用してやったことがあります...

使用例
水平円フリッパー(前面の画像にカーソルを合わせると、異なる画像で背面に反転します)。

例のスプライト
480px x 240px

例の最終サイズ
単一画像@ 120px x 120px

一般コード
.front {width:120px; height:120px; background:url(http://www.example.com/images/image_240x240.png); background-size:cover; background-repeat:no-repeat; background-position:0px 0px;}

.back {width:120px; height:120px; background:url(http://www.example.com/images/image_240x240.png); background-size:cover; background-repeat:no-repeat; background-position:-120px 0px;}

略称ケースフィドル
http://jsfiddle.net/zuhloobie/133esq63/2/

5
chris

背景サイズを使用してみてください: http://webdesign.about.com/od/styleproperties/p/blspbgsize.htm

最初に必要なサイズで画像をレンダリングするのを妨げる何かがありますか?

4
stephenmurdoch

私が満足していたこの問題の解決策を作成するのに時間がかかりました:

問題:

  • アイコンのSVGスプライト-たとえば80px x 3200px

  • 使用するサイズに基づいて各スプライトの座標を再定義することなく、さまざまなサイズのさまざまな場所のコンテンツセレクター(:before /:after)でそれらを使用するたびにスケーリングします。

したがって、このソリューションでは、<button><menuitem>と同じスプライト座標を使用しながら、スケーリングを行うことができます。

[data-command]::before {
    content: '';
    position: absolute;
    background-image: url("images/Sprite.svgz");
    background-repeat: no-repeat;
    background-size: cover;
}

button[data-command]::before {
  width: 32px;
  height: 32px;
}

menuitem[data-command]::before {
  width: 24px;
  height: 24px;
}

[data-command="cancel"]::before {
  background-position: 0% 35%;
}

[data-command="logoff"]::before {
  background-position: 0% 37.5%;
}

ここで他の人が提案したように、背景サイズではなく背景位置でパーセンテージ(小数点以下2桁まで)を使用することで、同じアイコン宣言を再宣言することなく任意のサイズに拡大縮小できます。

位置yの割合は、元のスプライトの高さ/アイコンの高さを%で表したものです。ここでは、80px * 100/3200px ==各スプライトは2.5%のy位置で表されます。

ホバー/マウスオーバーの状態がある場合、スプライトの幅を2倍にして、position-x座標で指定できます。

このアプローチの欠点は、後日アイコンを追加するとスプライトの高さとy位置%が変わることですが、そうしないと、必要なスケーリングされた解像度ごとにスプライト座標を変更する必要があります。

4
Neil

画像をスケーリングするためのより簡単なソリューションを見つけたと思います:例-使用したい3つの同じサイズのスプライトを持つ画像があるとしましょう。CSSを使用して画像をスケーリングします

background-size : 300% 100%;

次に、html要素に適用する必要があるカスタムの高さと幅を指定します。例:

 width :45%;
 height:100px;

サンプルコードは次のようになります。

.customclass {
    background: url("/sample/whatever.png") 0 0 no-repeat ;
    background-size : 300% 100%;
    width :45%;
    height:100px;
}

imはcssにかなり新しく、スタイリングは私の最善の領域ではありません。これは間違ったやり方かもしれません。しかし、Firefox/Chrome/Explorer 10ではうまくいきました。

2
Dasith

2018ここパーセンテージでbackground-sizeを使用します。

シート:

これは、スプライトの単一行を想定しています。シートの幅は100で割り切れる数値+ 1つのスプライトの幅である必要があります。 108x108ピクセルのスプライトが30個ある場合、最後に余分な空白スペースを追加して、最終的な幅を5508px(50 * 108 + 108)にします。

CSS:

.icon{
    height: 30px;  /* Set this to anything. It will scale. */
    width: 30px; /* Match height. This assumes square sprites. */
    background:url(<mysheeturl>);
    background-size: 5100% 100%; /*  5100% because 51 sprites. */
}

/* Each image increases by 2% because we used 50+1 sprites. 
   If we had used 20+1 sprites then % increase would be 5%. */

.first_image{
    background-position: 0% 0;
}

.ninth_image{
    background-position: 16% 0; /* (9-1) x 2 = 16 */
}

HTML:

<div class ="icon first_image"></div>
<div class ="icon ninth_image"></div>
2
user984003

transform: scale(...);を使用し、一致するmargin: -...pxを追加して、空き領域をスケーリングから補正します。 (* {outline: 1px solid}を使用して要素の境界を表示できます)。

2
adyry

これは私にとってはうまくいくようです。

スプライトがグリッドにある場合、background-sizeを100%のスプライト数に設定し、100%のスプライト数を下に設定します。次にbackground-position -<x*100>% -<y*100>%を使用します。xとyはゼロベースのスプライトです

つまり、左から3番目のスプライトと2段目、1段下の2番目のスプライトが必要な場合

background-position: -200% -100%;

たとえば、これはスプライトシートの4x2スプライトです

enter image description here

そして、ここに例があります

div {
  margin: 3px;
  display: inline-block;
}
.Sprite {
  background-image: url('https://i.stack.imgur.com/AEYNC.png');
  background-size: 400% 200%;  /* 4x2 sprites so 400% 200% */
}
.s0x0 { background-position:    -0%   -0%; }
.s1x0 { background-position:  -100%   -0%; }
.s2x0 { background-position:  -200%   -0%; }
.s3x0 { background-position:  -300%   -0%; }
.s0x1 { background-position:    -0%  -100%; }
.s1x1 { background-position:  -100%  -100%; }
.s2x1 { background-position:  -200%  -100%; }
.s3x1 { background-position:  -300%  -100%; }
<div class="Sprite s3x1" style="width: 45px; height:20px"></div>
<div class="Sprite s3x1" style="width: 128px; height:30px"></div>
<div class="Sprite s3x1" style="width: 64px; height:56px"></div>
<div class="Sprite s2x1" style="width: 57px; height:60px"></div>
<div class="Sprite s3x0" style="width: 45px; height:45px"></div>
<div class="Sprite s0x1" style="width: 12px; height:100px"></div>

<br/>
<div class="Sprite s0x0" style="width: 45px; height:20px"></div>
<div class="Sprite s1x0" style="width: 128px; height:45px"></div>
<div class="Sprite s2x0" style="width: 64px; height:56px"></div>
<div class="Sprite s3x0" style="width: 57px; height:60px"></div>
<br/>
<div class="Sprite s0x1" style="width: 45px; height:45px"></div>
<div class="Sprite s1x1" style="width: 12px; height:50px"></div>
<div class="Sprite s2x1" style="width: 12px; height:50px"></div>
<div class="Sprite s3x1" style="width: 12px; height:50px"></div>

スプライトのサイズが異なる場合は、スプライトの幅が100%になるように、各スプライトのbackground-sizeをパーセントに設定する必要があります

つまり、画像の幅が640pxで、その画像内のスプライトの幅が45pxである場合、その45pxを640pxにするには

xScale = imageWidth / spriteWidth
xScale = 640 / 45
xScale = 14.2222222222
xPercent = xScale * 100
xPercent = 1422.22222222%

次に、オフセットを設定する必要があります。オフセットの複雑さは、0%が左に揃えられ、100%が右に揃えられることです。

enter image description here

グラフィックプログラマーとして、100%のオフセットが要素全体で背景を100%移動すること、つまり完全に右側から移動することを期待していますが、backgrouhnd-positionで使用した場合の100%の意味ではありません。 background-position: 100%;は右揃えを意味します。したがって、スケーリング後にそれを考慮するためのフォーラムは

xOffsetScale = 1 + 1 / (xScale - 1)              
xOffset = offsetX * offsetScale / imageWidth

オフセットが31pxであると仮定します

xOffsetScale = 1 + 1 / (14.222222222 - 1)
xOffsetScale = 1.0756302521021115
xOffset = offsetX * xOffsetScale / imageWidth
xOffset = 31 * 1.0756302521021115 / 640
xOffset = 0.05210084033619603
xOffsetPercent = 5.210084033619603

これは、2つのスプライトを含む640x480の画像です。

  1. 31x 27yサイズ45w 32h
  2. 500x 370yサイズ105w 65h

enter image description here

スプライト1について上記の数学に従ってください

xScale = imageWidth / spriteWidth
xScale = 640 / 45
xScale = 14.2222222222
xPercent = xScale * 100
xPercent = 1422.22222222%

xOffsetScale = 1 + 1 / (14.222222222 - 1)
xOffsetScale = 1.0756302521021115
xOffset = offsetX * xOffsetScale / imageWidth
xOffset = 31 * 1.0756302521021115 / 640
xOffset = 0.05210084033619603
xOffsetPercent = 5.210084033619603

yScale = imageHeight / spriteHEight
yScale = 480 / 32
yScale = 15
yPercent = yScale * 100
yPercent = 1500%

yOffsetScale = 1 + 1 / (15 - 1)
yOffsetScale = 1.0714285714285714
yOffset = offsetY * yOffsetScale / imageHeight
yOffset = 27 * 1.0714285714285714 / 480
yOffset = 0.06026785714285714
yOffsetPercent = 6.026785714285714
div {
  margin: 3px;
  display: inline-block;
}
.Sprite {
  background-image: url('https://i.stack.imgur.com/mv9lJ.png');
}
.s1 {
  background-size:      1422.2222% 1500%;
  background-position:  5.210084033619603% 6.026785714285714%;
}
.s2 {
  background-size:      609.5238095238095% 738.4615384615385%;
  background-position:  93.45794392523367% 89.1566265060241%;
}
<div class="Sprite s1" style="width: 45px; height:20px"></div>
<div class="Sprite s1" style="width: 128px; height:30px"></div>
<div class="Sprite s1" style="width: 64px; height:56px"></div>
<div class="Sprite s1" style="width: 57px; height:60px"></div>
<div class="Sprite s1" style="width: 45px; height:45px"></div>
<div class="Sprite s1" style="width: 12px; height:50px"></div>
<div class="Sprite s1" style="width: 50px; height:40px"></div>
<hr/>
<div class="Sprite s2" style="width: 45px; height:20px"></div>
<div class="Sprite s2" style="width: 128px; height:30px"></div>
<div class="Sprite s2" style="width: 64px; height:56px"></div>
<div class="Sprite s2" style="width: 57px; height:60px"></div>
<div class="Sprite s2" style="width: 45px; height:45px"></div>
<div class="Sprite s2" style="width: 12px; height:50px"></div>
<div class="Sprite s2" style="width: 50px; height:40px"></div>
1
gman

スプライト画像のラッパー要素に幅と高さを設定します。このCSSを使用します。

{
    background-size: cover;
}
0
Ceylan Pamir