Vyplnění elementu obrázkem

JavaScript, CSS

Ukážeme si jednoduchý trik, jak div nebo jiný blokový element vyplnit obrázkem, který následně i vycentrujeme. Samozřejmě počítáme i s použitím u responzivního designu.

Vyplnění elementu obrázkem

V mnoha designech, které dostávám od grafika, je nějaký blok vyplněný obrázkem. Protože responzivní design je už dnes téměř nutností, zmenšit obrázek podle velikosti v designu je nesmyslné. Navíc po změně proporcí by obrázek byl deformovaný nebo okolo něj bylo prázdné místo, které určitě nevypadá dobře.

Obrázek v pozadí

Pokud je obrázek v pozadí daného elementu, stačí využít CSS3 vlastností pro pozadí.

.fillByImage{
  background-image: url(...);
  background-size: cover;
}

Vyplnění obrázkem

Pokud nějaký kontejner vyplníme obrázkem, který má jiné proporce, je pravděpodobné, že obrázek přeteče. Je potřeba kontejneru nastavit overflow: hidden; obrázku pak nastavíme podle proporcí výšku nebo šířku na 100% a druhý rozměr ponecháme na automatickém dopočtu.

Zde bude potřeba zaměstnat JavaScript, protože potřebujeme spočítat proporce, abychom obrázek mohli správně zmenšovat/zvětšovat. Z důvodu responzivního designu budeme muset vše přepočítat také při změně velikosti okna prohlížeče.

Ukázka kódu

<a href="#..." class="imgFillContainer">
  <img src="...">
</a>
.imgFillContainer{
  height: 160px;
  overflow: hidden;
  width: 25%;
}
.imgFillContainer .fillHeight {

  /* Nastavíme trochu vyšší z důvodu chybného zobrazení při některých rozlišeních */
  height: 101%; 
  width: auto;
}
.imgFillContainer .fillWidth {
  height: auto;
/* Nastavíme trochu vyšší z důvodu chybného zobrazení při některých rozlišeních */
  width: 101%; 
}
$(function(){
  var filledImages = $(".imgFillContainer img").each(function () {
      this.onload = fillByImage; //po načtení obrázku zavoláme vyplnění
      if (this.complete || (this.naturalWidth !== "undefined" && this.naturalWidth !== 0)) {
          fillByImage.call(this); //pokud již je obrázek načten, voláme ihned
      }
  });
  
  $(window).resize(function () {
      //po změně velikosti okna opět nad všemi obrázky zavoláme vyplňovací funkci
      filledImages.each(function () {
          fillByImage.call(this);
      });
  });
});

function fillByImage() {
    //získáme obrázek a rodiče
    var t = $(this), p = t.parents(".imgFillContainer:first");
    //spočítáme poměry stran, podle kterých přiřadíme CSS třídu
    var pRatio = p.width() / p.height(), tRatio = t[0].naturalWidth / t[0].naturalHeight;
    if(pRatio < tRatio){
      t.addClass("fillHeight").removeClass("fillWidth");
    }else{
      t.addClass("fillWidth").removeClass("fillHeight");
    }
}

Vycentrování obrázku

Důležitá část obrázku se většinou nachází v jejím středu, je proto nutné obrázek ještě vycentrovat. Toho docílíme jednoduše pouze pomocí CSS3 a transition. Z toho důvodu je centrování funkční pouze v modernějších prohlížečích. I přes podporu až od IE9 včetně si myslím, že není potřeba tuto nedokonalost příliš řešit.

Ukázka kódu

.imgFillContainer{
  position: relative;
}
.imgFillContainer img {
  position: absolute;
  left: 50%;
  top: 50%;
  -ms-transform: translateY(-50%) translateX(-50%);
  -webkit-transform: translateY(-50%) translateX(-50%);
  transform: translateY(-50%) translateX(-50%);
}

Zatímco top a left se počítá podle velikostí rodiče, translate se počítá podle aktuální velikosti elementu, proto se náš obrázek dostane krásně doprostřed. Stejného řešení jsem využil na portfoliu Dominika, kde takto centruji nadpisy nad polygony.

Demo

Chování si můžete vyzkoušet na JSFiddle.

K tomuto článku již není možné přidávat další komentáře