Kawałek Kodu

W dzisiejszym wpisie będziesz mógł posmakować zawodu YouTubera. Nie będziemy tworzyć co prawda niegrzecznych streamów ani zbierać miliona subskrypcji, ale przygotujemy efekt podobny do amatorskich filmów z telefonu gdzie w części kadru, której nie zajmuje obraz widzimy ten sam obraz, ale rozmyty. Przyznam, że to chyba pierwszy wpis, dla którego trudno mi było wybrać odpowiedni tytuł. "Rozmycie tła dla obrazu, który ma inne proporcje niż kadr"? A może jak film ze wstępu: "Jak naprawić pionowe wideo"? Treść chyba jednak wszystko wyjaśni i od razu rozpoznasz ten efekt. No to łapka w górę i zabieraj się do czytania!

Obrazek na ostro.

Jeśli jeszcze nie wiesz jaki efekt mam na myśli, to możesz sie mu przyjrzeć we wstępnym filmie. W tym wpisie zajmiemy się jednak tylko efektem na obrazkach, a w kontynuacji na wideo. Efekt możemy osiągnąć na kilka sposobów, które zaraz podam. Ale aby Ci było łatwiej zrozumieć ich zasadę działania, warto abyś zerknął na wpisy podane w "Przydatnych linkach", na końcu tego wpisu.

Być może nie wiesz, ale nic nie stoi na przeszkodzie, aby obrazek miał ustawioną właściwość background-image. Kilka dziwacznych przykładów zaraz Ci pokażę. Na koniec będzie przykład efektu z wykorzystaniem standardowych technik. Rzadko wykorzystujemy background-image dla obrazka, bo przecież sam w sobie jest tłem. Ale jeśli obrazek nie będzie zajmował całej przestrzeni samego siebie (poprzez odpowiednią wartość object-fit), to jednak zostanie nam pusta przestrzeń. Możemy ją zagospodarować właśnie poprzez ustawienie background-image. Tym sposobem mamy dwie pieczenie na jednym ogniu, bo w obrazku mogą być... dwa obrazki (różne, albo ten sam jeśli będa mieć to samo źródło). Zaczniemy od sposobu z użyciem object-fit i... braku rozmycia.

<img src="mario-1557240_640.jpg" width="320" height="480" />

+

img {
  object-fit: contain;
  background: url(mario-1557240_640.jpg);
  background-size: cover;
  background-position: center;
}

W atrybutach obrazka ustalamy przestrzeń dla niego jako 320x480 (układ portrait). Jednak ze względu na właściwość object-fit: contain sedno obrazka wciśnie się w dostępną szerokość, a nad i pod obrazkiem powstaną puste obszary (obrazek ma proporcje landscape). W sumie nie puste, ale wypełnione background-image, które zajmie całą przestrzeń i zostanie docięte w miare potrzeby (background-size: cover).

Wygląda to tak:

W tym przypadku nie ma możliwości rozmycia tła poprzez CSS, no chyba, że ustawimy obrazek dla tła już rozmyty. Ale chyba nie o to chodzi.

Wyglądasz niewyraźnie.

Teraz na 100% wiesz do czego dążymy, ale żeby się zbliżyć bardziej do oczekiwanego efektu, wykorzystamy właściwość obrazka obsługiwaną na niektórych przeglądarkach (przeczytasz o tym w podanym na końcu linku). 

<img src width="320" height="480" alt="" />

+

img {
  background: url(mario-1557240_640.jpg) center no-repeat;
  background-size: contain;
  position: relative;
  display: inline-block;
  overflow: hidden;
}

img:before {
  content: "";
  background: inherit;
  background-size: cover;
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  filter: blur(5px);
  transform: scale(1.2);
}

Tym razem tło obrazka przejmuje rolę samego obrazka. W poprzednim przykładzie wciskaliśmy zawartość obrazka w przestrzeń, teraz wciskamy tło. Obrazek nie ma źródła, więc możemy gdzieniegdzie wykorzystać pseudoelement dla IMG. Ma on to samo źródło co sam tło, ale tu zaletą jest możliwość użycia filtra blur. Dzięki z-index przesuwamy pseudoelement pod obrazek. Dlaczego pseudoelement jest trochę przeskalowany? Filtr blur powoduje, że rozmyte krawędzie zaczynają się w obszarze obrazka, wyglądałoby to tak:

Możemy ustawić overflow na obrazku (tak, tak), ale i tak zobaczymy część rozmycia:

Natomiast łącząc overflow z powiększeniem otrzymujemy to co chcieliśmy:

Nic nie stoi na przeszkodzie, aby nasz obrazek był pseudowideo:

Po staremu.

Powyższe przykłady nawiązywały do wykorzystania background-image dla obrazka, ale zawsze możemy skorzystać z najprostszej metody (wiemy też, że zadziała na każdej przeglądarce):

<div>
  <img src="mario-1557240_640.jpg" width="640" height="312" alt="" />
</div>

+

div {
  width: 320px;
  height: 480px;
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

div:before {
  content: "";
  background: url(mario-1557240_640.jpg) center no-repeat;
  background-size: cover;
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  filter: blur(5px);
  transform: scale(1.2);
}

img {
  width: 100%;
  height: auto;
}

Tym razem rolę kontenera przejął DIV. Rolę pseudoelementu dla IMG pseudoelement dla DIV. Natomiast obrazek najzwyczajniej wciskamy w DIV, w którym zawartość środkujemy w obydwu osiach. Musimy tu użyć dwa elementy (do diaska!).

Komu się podobał wpis daje łapkę w górę, komu się podobał zostawia komentarz, a jeśli pod tym wpisem będzie 50 tysięcy... a co tam 100 tysięcy! łapek w górę, to pomyślę o kolejnym wpisie...

 

Przydatne linki:
Upychanie walizki, czyli o właściwości object-fit i object-position.
Yeti - jedni widzieli, inni nie, czyli pseudoelement dla IMG.