CSSスプライトで画像を拡大縮小するには


157

この記事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/

では、アイテム1、2、3、4の横にあるアイコンを小さくできるかどうか知りたいのですが?


スティーブンが尋ねたように、最初に必要なサイズでイメージをレンダリングするのを妨げているものはありますか?
ポールD.ウェイト2013年

4
同じことの答えを探していたので、このページにたどり着きました。高解像度のRetinaディスプレイを備えた今日の世界では、画像を必要なサイズの2倍にしてから、<img>属性またはCSSスタイルで高さ/幅の値を使用して、表示時に高さ/幅を半分に減らします。これにより、スマートフォンやタブレットで鮮明な表示が保証されます。ただし、PNGスプライトは、キャッシュとレンダリングをすばやく行うのに最適です。2x画像のスプライトを使用するだけでなく、鮮明に見えるサイズに拡大するのが最善です。
Art Geigel 2016

元の質問が受け入れられた答えを得ることはなく、かなりきちんとした後方互換性のあるソリューションがあるので、元のウェブサイトはもうオンラインではなく、後方に必要な人がまだいるので、私は新しいCodepen Stretchyバージョンを作りました互換性のあるソリューション。私は、オリジナルの作品/著者の帰属でペンを作りました。
すべてのビットが2018年

回答:


131

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

background-size : 150% 150%;

または

webkit / ieにはズームの組み合わせを使用でき、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;
}

3
Chromeでは問題なく動作し、FF、IE9 / 10では問題なく動作します。ほとんどの部分で望ましい効果が得られます。
RCNeil 2014年

(例)背景サイズを使用:15%; 正しいアスペクト比を維持しながら、スプライトに最適です。これは、レスポンシブサイトのブレークポイントで使用する簡単なソリューションです。
C13L0

1
高さと幅が固定されているsvgスプライトでは、background-sizeプロパティが機能しませんでしたが、スケールでうまくいきました。
Andre

IE8にサポートを追加するには、IE8標準モードでのズームの同義語として-ms-zoom属性を使用します。-ms-zoom:0.7; 詳細については、次のリンクを参照してください:msdn.microsoft.com/en-us/library/ms531189(v
Amr

2
2017年の更新:background-sizeは、IE9 +を含むすべての主要なブラウザーでサポートされています。 caniuse.com/#search=background-size
Nathan Hinchey

29

スプライトを使用する場合、スプライト内の画像のサイズに制限されます。background-sizeスティーブン言及CSSプロパティは、広くはまだサポートされておらず、IE8のような、以下のブラウザで問題が発生するかもしれない-と彼らの市場シェアを考えると、これは現実的な選択肢ではありません。

この問題を解決するもう1つの方法は、次のように、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)は、imgタグから20x20pxの画像をトリミングしますbackground-image


2
cletusやQuentinがここで述べているように、これは最善のアプローチではないかもしれません。私にとってはそれは契約違反です-私はsrcCSSで割り当てる必要があります。
ジョーク2013年

-1:プレゼンテーション要素とコンテンツ/データを混在させることはできません。<img>コンテンツの一部である場合にのみ使用してください。デザインの目的では、背景画像は必須です。
Shahriyar Imanov 2016年

ベストアンサー(a)は普遍的に機能し、(b)人間が理解できる、(c)簡潔、...(z)プレゼンテーションをコンテンツから分離します。
Bob Stein

18

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

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

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>

3
リンクは、ここで理論を実際に説明していません。オーバーフローのあるdivを使用しています:スプライトイメージのスケーリングされたバージョンを使用する上に、トリミング領域/ウィンドウとして非表示になっています。これが、背景画像をまったく使用しない理由です。ちょうど1つのレイヤーを別のレイヤーの上に重ねてマスクします。
Simon

1
スペーサーは画像でなければなりませんか、それとも単純なdivを代わりに使用できますか?
isapir 2013年

4
これがCodePenの例です。水平または垂直スプライトでのみ機能するようです。グリッドではありません。
Wernight

元のウェブサイトがもうオンラインではなく、下位互換性のあるソリューションを必要とする人がまだいるので、私は新しいCodepen Stretchyバージョンを作成しました。私はオリジナルの作品/著者の帰属でペンを作成しました
All Bits Equal

10

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>


こんにちはこれは質問に答えません。同じ画像の異なる縮尺の3つのdivを表示する必要があります。つまり、「フォント」のさまざまなサイズが表示されます。直せますか?
ロバート

@Robertさん、こんにちは。今はどう?
Tomasz Mularczyk 2017

PS VWメジャーユニットを使用した動作に気づきましたか?
ロバート

よくわかりません、どういう意味ですか
Tomasz Mularczyk 2017

VW VHは、ビューポートサイズに比例してスケーリングされます。今まで使ったことがない。それらを使用した経験についての好奇心に過ぎません。それらは「魔法」であるか、または気づいたかもしれない状況で考慮すべき問題(予期しない動作)がありますか?ありがとう
ロバート

7

これは私がこれを行うためにしたことです。IE8以下では機能しないことに注意してください。

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

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

最初のパーセンテージは、通常の幅でスプライトの合計幅で割ったときの、スプライトのターゲット領域の幅に100を掛けたものです。

2番目のパーセンテージは、スケーリングされる前のスプライトのターゲット領域の高さをスプライトの全体の高さで割り、100を掛けたものです。

これらの2つの方程式の表現は少しずさんです。そのため、もっとよく説明する必要がある場合はお知らせください。


6

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

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

つまり、左から3番目のスプライトと2番目の行が必要な場合は、2オーバーで1ダウンです。

background-position: -200% -100%;

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

ここに画像の説明を入力してください

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

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>

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

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

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

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

ここに画像の説明を入力してください

グラフィックプログラマーとして、要素全体で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

ここに画像の説明を入力してください

上記のスプライトの計算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>


offsetXとoffsetYの値をどのように計算しましたか?
TryHarder

5

古い投稿ですが、これは私が使ったものです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;}

ABBREVIATED CASE FIDDLE
http://jsfiddle.net/zuhloobie/133esq63/2/


4

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

そもそも希望するサイズで画像をレンダリングするのを妨げる何かがありますか?


これを解決するためにJavaScriptとCSSを組み合わせて使用​​できますか?背景サイズを試してみました。プロパティ。うまくいきません。何らかの理由で画像を拡大縮小しません。
マイケル

1
background-sizeCSS 3であり、まだ広くサポートされていません。
janmoesen 2010年

4
現在、ほとんどのブラウザバージョンでサポートされています。このcaniuse.com/#search=background-sizeを
kiranvj

4

この問題の解決策を作成するのに少し時間がかかりました。

問題:

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

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

このソリューションは、あなたが同じスプライト共同ordsを使用することができますので、<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%;
}

ここで他の人が示唆しているようにbackground-sizeではなくbackground-positionにパーセンテージ(小数点以下2桁まで)を使用することで、同じアイコン宣言を任意のサイズに拡大縮小できます。再宣言する必要はありません。

position-yパーセンテージは、元のスプライトの高さ/アイコンの高さを%で表したものです。この例では、80px * 100 / 3200px ==各スプライトは、2.5%のy位置で表されます。

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

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


2

まあ私は画像をスケーリングするためのより簡単な解決策を見つけたと思います:例-使用したい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

transform: scale(...);マッチングmargin: -...pxを使用して追加し、スケーリングによる空きスペースを補正します。(* {outline: 1px solid}要素の境界を確認するために使用できます)。


2

2018年はこちら。パーセンテージ付きのbackground-sizeを使用します。

シート:

これは、スプライトの単一の行を想定しています。シートの幅は、100 + 1つのスプライトの幅で均等に割り切れる数値にする必要があります。108x108ピクセルのスプライトが30個ある場合は、最後に余白を追加して、最終的な幅を5508ピクセル(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>


0

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

{
    background-size: cover;
}

1
これが反対投票された理由がわかりません。私のために働いた。私の方法を回答として投稿します。
クリス

私はここでクリスに同意します。これは私の場合にも問題を解決します。なぜ反対票が投じられたのかわからない!
ShellZero

3
スプライトでは機能しません(質問のタイトルを見てください)。そのため、このソリューションは反対投票されています。
Dimko Desu 2017

-8

簡単...スプライトのシートで、同じ画像の2つのコピーを異なるスケールで使用します。アプリのロジックで座標とサイズを設定します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.