CSS Sprite

Krótka teoria

Sprawa bardziej Front Endowa. Zamiast wielu malych obrazeczków na przyciski (lub inne elementy), komponujemy jeden wielki obraz, który ściągnie się raz i oszczędzimy czas i resource’y potrzebne do generowania wielu requestów HTTP.

Wiele obrazków:

#nav li a.item1 {background-image:url('../img/image1.gif')}
#nav li a:hover.item1 {background-image:url('../img/image1_over.gif')}

Używając CSS Sprite:

#nav li a {background-image:url('../img/image_nav.gif')}
#nav li a.item1 {background-position:0 0}
#nav li a:hover.item1 {background-position:0 -72px}

Generowanie obrazka sprite’owego

Stronek do generowania sprite’ów jest wiele, zazwyczas jednak skupiają się na zbieraniu wszystkich malutkich rozrzuconych obrazków na stronie. Mój przypadek to 110 obrazków w folderze, które to mają być wkomponowane w jedek długaśny obrazek. Instant Sprite ostatecznie zrobił to czego potrzebowałem.

Mój case

Po najechaniu myszką pokazuje sie kilkanaście obrazków. Przeglądarka ma ograniczenie na ilość requestów które wysyła do jednego serwera (Roundup on Parallel Connections). Każdy obrazek potrzebował też momentu żeby się ściągnąć. Przez te dwie rzeczy zauważalny był efekt dociągania się obrazków, którego chciałem uniknąć:

Twilight struggle slow cards download

Zdecydowałem się na CSS Sprite. Trzeba podmienić markup pozbywając się tagów <img>. Ze strony Nine Techniques for CSS Image Replacement skorzystałem z techniki numer jeden. W przykładzie zastąpiono je <h1>, a ja wybrałem sobie <h2>, którego to wyboru nie potrafię jednak głębiej uzasadnić ;). Oto markup (+ KnockoutJS):

Przed sprite:

   
<img data-bind="attr: {src: picturePath, alt: name, title:name}" />

Używając sprite:

  • Style.css:

    h2.card-image-replacement
    {
        width: 80px;
        height: 112px;
        background-image: url(/images/cards_80px.PNG);
        margin: 0;
    }
    
    h2.card-image-replacement span
    {
        display: none;
    }
    
  • map.html

                        <h2 class="card-image-replacement" data-bind="style: {'background-position': backgroundPosition }, attr: {title: name }">
                            <span>sprite</span>
                        </h2>
    
    

    Z bindowaniem do background-position trochę się namęczyłem, ale finalnie działa tak jak w pozyższym kodzie.

  • map.js

            this.backgroundPosition = function () {
                return "0 " + (this.id - 1) * -113;
            };
    

Commit do podejrzenia na GitHub.

TS cards list

Wątpliwości

Nie wiem też, czy mój przepadek się dobrze nadaje do tego co właśnie popełniłem. Gdyby użyć obrazków w większej rozdzielczości to wygenerowany plik dochodzi do kilkunastu MB (niestety niesprawdzone ponieważ ta strona nie dała rady z 110 obrazkami w pełnej rozdzielczości). Obecny plik zajmuje 1,5MB i jestem to w stanie zaakceptować ponieważ jest też plik mapy który ma 2MB i który musi zostać najpierw pobrany.

Reklamy
Ten wpis został opublikowany w kategorii Programowanie i oznaczony tagami , , , , , . Dodaj zakładkę do bezpośredniego odnośnika.

2 odpowiedzi na „CSS Sprite

  1. nilphilus pisze:

    Osobiście to na klasach zrobiłem, jedna z rozmiarem a druga z nazwą obrazka. „iconHolder + buttonSave”. Knockout o ile jest fajny, to tutaj jest to raczej ‚overenginered\ ‚

    • Nie do końca rozumiem. Korzystałeś ze Sprite czy właśnie uznałeś że wykorzystanie tego tutaj to już overengineering?
      Knockout i tak jest w projekcie, więc tutaj tylko przy okazji się przydał.

Możliwość komentowania jest wyłączona.