Bagaimana saya bisa skala gambar dalam sprite CSS

157

Dalam artikel ini, http://css-tricks.com/css-sprites/ , ia berbicara tentang bagaimana saya bisa memotong gambar yang lebih kecil dari 1 gambar yang lebih besar. Bisakah Anda memberi tahu saya jika mungkin / bagaimana saya bisa memotong gambar yang lebih kecil dan kemudian skala wilayah yang dipotong sebelum saya meletakkannya?

Ini adalah contoh dari artikel itu:

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

Saya ingin tahu bagaimana saya bisa skala gambar itu setelah saya memotongnya dari spriteme1.png

Berikut ini URL contohnya: http://css-tricks.com/examples/CSS-Sprites/Example1After/

Jadi saya ingin tahu apakah saya dapat membuat ikon di sebelah Item1,2,3,4 lebih kecil?

michael
sumber
Seperti Stephen bertanya, apakah ada sesuatu yang menghentikan Anda dari rendering gambar pada ukuran yang Anda inginkan?
Paul D. Waite
4
Saya berakhir di halaman ini karena saya mencari jawaban untuk hal yang sama. Di dunia saat ini dengan tampilan retina definisi tinggi, biasanya untuk membuat gambar dua kali ukuran daripada yang seharusnya dan kemudian menggunakan nilai tinggi / lebar dalam atribut <img> atau gaya CSS untuk menguranginya menjadi setengah tinggi / lebar saat ditampilkan. Ini memastikan tampilan yang tajam pada smartphone dan tablet. Tapi sprite PNG bagus untuk caching dan rendering dengan cepat. Akan lebih baik tidak hanya menggunakan sprite dari gambar 2x, tetapi untuk kemudian skala ke ukuran yang membuatnya terlihat segar juga.
Seni Geigel
Karena pertanyaan aslinya tidak pernah mendapat jawaban yang diterima dan ada solusi yang cukup rapi dan kompatibel ke belakang, saya membuat versi Codepen Melar baru , karena situs web asli tidak online lagi dan mungkin masih ada beberapa orang di luar sana yang perlu mundur. solusi yang kompatibel. Saya telah membuat Pena dengan atribusi karya asli / penulis.
All Bits Equal

Jawaban:

131

Anda dapat menggunakan ukuran latar belakang , karena didukung oleh sebagian besar browser (tetapi tidak semua http://caniuse.com/#search=background-size )

background-size : 150% 150%;

Atau

Anda dapat menggunakan kombinasi zoom untuk webkit / ie dan mentransformasikan: skala untuk Firefox (-moz-) dan Opera (-o-) untuk desktop & seluler lintas-peramban

[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;
}
aWebDeveloper
sumber
3
Berfungsi bagus di Chrome, berfungsi OK di FF, IE9 / 10. Menghasilkan efek yang diinginkan untuk sebagian besar.
RCNeil
Menggunakan (contoh) ukuran latar: 15%; berfungsi sempurna untuk sprite sambil mempertahankan rasio aspek yang benar. Ini adalah solusi sederhana untuk digunakan dengan breakpoint di situs responsif.
C13L0
1
properti ukuran latar tidak bekerja untuk sprite svg saya dengan tinggi dan lebar tetap, namun skala melakukan trik.
Andre
Untuk menambahkan dukungan ke IE8, gunakan atribut -ms-zoom sebagai sinonim untuk zoom dalam mode Standar IE8. -ms-zoom: 0,7; Lihat tautan di bawah ini untuk perincian lebih lanjut: msdn.microsoft.com/en-us/library/ms531189(v=vs.85).aspx
Amr
2
Pembaruan 2017: ukuran latar belakang didukung oleh semua browser utama, termasuk IE9 +. caniuse.com/#search=background-size
Nathan Hinchey
29

Saat Anda menggunakan sprite, Anda terbatas pada dimensi gambar di sprite. The background-sizeproperti CSS, disebutkan oleh Stephen, tidak didukung secara luas belum dan mungkin menyebabkan masalah dengan browser seperti IE8 dan di bawah - dan diberikan pangsa pasar mereka, ini bukan pilihan yang layak.

Cara lain untuk memecahkan masalah adalah dengan menggunakan dua elemen dan skala sprite dengan menggunakannya dengan imgtag, seperti ini:

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

Dengan cara ini, elemen luar ( div.sprite-image) memotong gambar 20x20px dari imgtag, yang bertindak seperti skala background-image.

Alex Gyoshev
sumber
2
Seperti cletus dan Quentin statet di sini , ini mungkin bukan pendekatan terbaik. Bagi saya itu adalah dealbreaker - saya harus srcmenggunakan css.
Jook
-1: Anda tidak dapat mencampur elemen presentasi dengan konten / data. <img>seharusnya hanya digunakan jika itu adalah bagian dari konten. untuk tujuan desain, gambar latar belakang adalah suatu keharusan.
Shahriyar Imanov
Jawaban terbaik (a) bekerja secara universal, (b) dapat dipahami oleh manusia, (c) singkat, ... (z) memisahkan presentasi dari konten.
Bob Stein
18

Coba ini: Stretchy Sprite - Lintas-browser, pengubahan ukuran / peregangan gambar sprite CSS responsif

Metode ini skala sprite 'responsif' sehingga lebar / tinggi menyesuaikan sesuai dengan ukuran jendela browser Anda. Tidak digunakan background-size karena dukungan untuk ini di browser lama tidak ada.

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>
tobyj
sumber
3
Tautannya tidak benar-benar menjelaskan teorinya di sini. Anda menggunakan div dengan overflow: disembunyikan sebagai area pemangkasan / jendela di atas menggunakan versi skala dari gambar sprite. Itulah sebabnya mengapa tidak menggunakan gambar latar belakang sama sekali. Hanya satu lapisan di atas yang lain sebagai topeng.
Simon
1
apakah spacer harus berupa gambar atau dapatkah div sederhana digunakan?
isapir
4
Berikut adalah contoh CodePen tentang ini. Tampaknya hanya berfungsi untuk sprite horizontal atau vertikal. Bukan grid.
Wernight
Saya membuat versi Melar Codepen baru , karena situs web asli tidak online lagi dan mungkin masih ada beberapa orang di luar sana yang membutuhkan solusi kompatibel yang terbelakang. Saya telah membuat Pena dengan atribusi dari karya / penulis asli
All Bits Equal
10

transform: scale(); akan membuat elemen asli mempertahankan ukurannya.

Saya menemukan opsi terbaik adalah menggunakan vw. Ini bekerja seperti pesona:

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>

Tomasz Mularczyk
sumber
Halo, ini tidak menjawab pertanyaan. Anda harus menunjukkan tiga div dengan skala berbeda dari gambar yang sama. Dalam beberapa kata, ini akan menunjukkan ukuran "font" yang berbeda. Bisakah kamu memperbaikinya?
Robert
hai @Robert. Bagaimana kalau sekarang?
Tomasz Mularczyk
PS sudahkah Anda memperhatikan perilaku menggunakan satuan ukuran VW?
Robert
Saya tidak yakin, perilaku apa yang Anda maksud?
Tomasz Mularczyk
VW VH scaling secara proporsional dengan ukuran viewport. Saya belum pernah menggunakannya sampai sekarang. Itu hanya rasa ingin tahu tentang pengalaman Anda menggunakannya. Apakah mereka begitu "ajaib" atau ada masalah yang perlu dipertimbangkan (perilaku tak terduga) dalam beberapa situasi yang mungkin Anda perhatikan? terima kasih
Robert
7

Inilah yang saya lakukan untuk melakukan ini. Perlu diingat itu tidak akan berfungsi pada IE8 dan di bawah ini.

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

Lebar gambar latar belakang akan turun sebagai induk #elementskala turun. Anda dapat melakukan hal yang sama dengan tingginya, juga, jika Anda mengonversi heightke persentase. Satu-satunya hal yang sulit adalah mencari tahu persentase background-position.

Persentase pertama adalah lebar area yang ditargetkan dari sprite ketika pada lebar normal dibagi dengan total lebar sprite, dan dikalikan dengan 100.

Persentase kedua adalah ketinggian area yang ditargetkan dari sprite sebelum diskalakan dibagi dengan tinggi total sprite, dan dikalikan dengan 100.

Kata-kata pada kedua persamaan itu sedikit ceroboh, jadi beri tahu saya jika Anda membutuhkan saya untuk menjelaskannya dengan lebih baik.


sumber
6

Ini sepertinya bekerja untuk saya.

Jika sprite berada dalam kisi, atur background-sizejumlah sprite 100% dan 100% jumlah sprite. Kemudian gunakan di background-position -<x*100>% -<y*100>%mana x dan y adalah sprite berbasis nol

Dengan kata lain, jika Anda menginginkan sprite ke-3 dari kiri dan ke-2, maka 2 over dan 1 down

background-position: -200% -100%;

Sebagai contoh di sini adalah sprite sheet 4x2 sprite

masukkan deskripsi gambar di sini

Dan ini sebuah contoh

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>

Jika ukuran sprite berbeda, Anda perlu mengatur background-sizeuntuk setiap sprite ke persen sehingga lebar sprite menjadi 100%

Dengan kata lain jika gambar memiliki lebar 640px dan sprite di dalam gambar itu adalah lebar 45px maka untuk mendapatkan 45px menjadi 640px

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

Maka Anda perlu mengatur offset. Komplikasi dari offset adalah bahwa 0% lurus kiri dan 100% lurus kanan.

masukkan deskripsi gambar di sini

Sebagai seorang programmer grafis, saya berharap offset 100% untuk memindahkan latar belakang 100% melintasi elemen, dengan kata lain sepenuhnya dari sisi kanan tetapi bukan itu yang berarti 100% ketika digunakan dengan backgrouhnd-position. background-position: 100%;berarti selaras kanan. Jadi, forumla untuk memperhitungkannya setelah penskalaan adalah

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

Asumsikan offsetnya adalah 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

Berikut adalah gambar 640x480 dengan 2 sprite.

  1. pada 31x 27y ukuran 45w 32j
  2. pada ukuran 500x 370y 105w 65j

masukkan deskripsi gambar di sini

Mengikuti matematika di atas untuk sprite 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>

gman
sumber
Bagaimana Anda menghitung nilai untuk offsetX dan offsetY?
TryHarder
5

Posting lama, tapi inilah yang saya lakukan menggunakan background-size:cover;(hat tip ke @Ceylan Pamir) ...

CONTOH PENGGUNAAN
sirip lingkaran horizontal (arahkan kursor pada gambar sisi depan, membalik ke belakang dengan gambar berbeda).

CONTOH SPRITE
480px x 240px

CONTOH FINAL SIZE
Gambar tunggal @ 120px x 120px

KODE GENERIK
.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/

chris
sumber
4

coba gunakan ukuran latar belakang: http://webdesign.about.com/od/styleproperties/p/blspbgsize.htm

Adakah sesuatu yang menghentikan Anda dari rendering gambar pada ukuran yang Anda inginkan di tempat pertama?

stephenmurdoch
sumber
Dapatkah saya menggunakan JavaScript dan CSS dalam kombinasi untuk menyelesaikan ini? Saya mencoba ukuran latar belakang; Properti. Saya tidak bisa membuatnya bekerja. Itu tidak skala gambar karena alasan tertentu.
michael
1
background-sizeadalah CSS 3 dan belum didukung secara luas.
janmoesen
4
Ini didukung oleh sebagian besar versi browser sekarang. Memeriksa ini caniuse.com/#search=background-size
kiranvj
4

Butuh beberapa saat untuk membuat solusi untuk masalah ini yang saya senangi:

Masalah:

  • Sprite ikon SVG - katakan 80px x 3200px

  • Kami ingin mengatur skala setiap penggunaannya dalam pemilih konten (: sebelum /: setelah) di berbagai tempat di berbagai ukuran tanpa mendefinisikan ulang co-ords dari setiap sprite berdasarkan pada ukuran yang digunakan.

Jadi solusi ini memungkinkan Anda untuk menggunakan co-ords sprite yang sama dalam <button>waktu <menuitem>sementara masih meningkatkannya.

[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%;
}

Dengan menggunakan persentase (ke 2 tempat desimal) di posisi latar belakang daripada ukuran latar belakang seperti yang disarankan oleh orang lain di sini, Anda dapat mengatur deklarasi ikon yang sama untuk ukuran apa pun, tanpa harus mendeklarasikan ulang.

Persentase posisi-y adalah tinggi sprite asli / tinggi ikon sebagai% - dalam kasus kami di sini 80px * 100 / 3200px == setiap sprite diwakili oleh posisi-y 2.5%.

Jika Anda memiliki status hover / mouseover, Anda dapat menggandakan lebar sprite dan menentukan dalam koordinat posisi-x.

Kerugian dari pendekatan ini adalah bahwa menambahkan lebih banyak ikon di kemudian hari akan mengubah tinggi sprite dan% y-posisi, tetapi jika Anda tidak melakukan itu maka koordinat sprite Anda akan memerlukan perubahan untuk setiap resolusi skala yang Anda butuhkan.

Neil
sumber
2

Yah saya pikir menemukan solusi yang lebih sederhana untuk penskalaan gambar: contoh - katakanlah ada gambar dengan 3 sprite berukuran sama yang ingin Anda gunakan, gunakan CSS untuk skala gambar

background-size : 300% 100%;

dan kemudian tentukan tinggi dan lebar khusus yang perlu diterapkan ke elemen html Anda misalnya:

 width :45%;
 height:100px;

Kode sampel akan terlihat seperti ini:

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

im cukup baru untuk css, dan styling bukan area terbaik saya ini bisa menjadi cara yang salah untuk melakukannya .. tapi itu bekerja untuk saya di Firefox / Chrome / Explorer 10, harap itu bekerja di versi yang lebih lama juga ..

Dasith
sumber
2

Gunakan transform: scale(...);dan tambahkan pencocokan margin: -...pxuntuk mengkompensasi ruang kosong dari penskalaan. (Anda dapat menggunakan * {outline: 1px solid}untuk melihat batas elemen).

Adyry
sumber
2

2018 di sini. Gunakan ukuran latar belakang dengan persentase.

LEMBAR:

Ini mengasumsikan satu baris sprite. Lebar lembar Anda harus berupa angka yang dapat habis dibagi 100+ lebar satu sprite . Jika Anda memiliki 30 sprite yang berukuran 108x108 px, maka tambahkan ruang kosong tambahan di ujungnya untuk membuat lebar akhir 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>
pengguna984003
sumber
1

Gunakan transform: scale(0.8);dengan nilai yang Anda butuhkan, bukan 0,8

Miguel Ballén
sumber
0

Atur lebar dan tinggi ke elemen pembungkus gambar sprite. Gunakan css ini.

{
    background-size: cover;
}
Ceylan Pamir
sumber
1
Saya tidak mengerti mengapa ini tidak dipilih. Bekerja untukku. Akan memposting metode saya sebagai jawaban.
chris
Saya setuju dengan chris di sini. Ini memecahkan masalah dalam kasus saya juga. Tidak yakin mengapa itu dibatalkan!
ShellZero
3
Itu tidak bekerja dengan sprite (lihat judul pertanyaan), itu sebabnya solusi ini diturunkan.
Dimko Desu
-8

Mudah ... Menggunakan dua salinan gambar yang sama dengan skala berbeda pada lembar sprite. Atur Coords dan ukuran pada logika aplikasi.

makubex
sumber