Kawałek Kodu

Każdy lubi wyjazdy, ale chyba mało kto lubi się pakować. Szczególnie kiedy do dyspozycji mamy jedną walizkę, albo jedną reklamówkę... a multum rzeczy do zabrania ze sobą, oczywiście potrzebnych. Dziś też będziemy upychać, ale w jedną rzecz i w bardziej przyjemny sposób. (Nie, nie, nie! Mam na myśli CSS!).

Szeroki, wąski, niski, wysoki, każdy upchnąć się może.

O właściwości object-fit, bo o niej mowa, być może słyszałeś. Pewnie szczególnie przydatna była wartość cover, która załatwia nam to samo co analogiczna wartość dla background-size, czyli wciska nam obrazek zachowując jego proporcje, do kontenera o być może zupełnie innych proporcjach. Object-fit ma oprócz zbieżnych wartości, kilka innych, mniej lub bardziej przydatnych. A więc jakie ma?

  • fill - obrazek wciśnie się w zadane wymiary, nie będzie utrzymywał jednak proporcji, nie zostanie docięty, to jest domyślna wartość - bez jej nadawania obrazek też się tak zachowa,
  • none - obrazek utrzyma swój naturalny wymiar i proporcje, może być docięty,
  • cover - obrazek wciśnie się w zadane wymiary, ale utrzyma swoje proporcje, tak więc może zostać docięty z boków lub góry i dołu,
  • contain - obrazek wciśnie się w zadane wymiary, utrzyma swoje proporcje i nie zostanie docięty, mogą więc powstać puste przestrzenie z boków lub góry i dołu,
  • scale-down - obrazek utrzyma swój naturalny wymiar i proporcje jeśli jest mniejszy od przestrzeni, lub zostanie przeskalowany w dół jeśli jest większy niż dostępna przestrzeń, zachowa się wtedy analogicznie do contain. W tym przypadku obrazek nigdy nie jest skalowany w górę (powiększany).

Sam sobie kontenerem i obrazkiem.

Póki co nie napisałem dokładnie do jakiej przestrzeni dopasowuje się obrazek. I tu być może małe zaskoczenie. Obrazek dopasowuje się sam do siebie... Brzmi to trochę nielogicznie, bo skoro ma się tak dopasowywać, to przecież to jedyny sposób, a nie kilka, jak wymieniłem wyżej. Już wyjaśniam. Zadając określone wymiary obrazka czy to poprzez atrybuty, czy poprzez CSS, to one tworzą przestrzeń, w którą będziemy wciskać obrazek. Ciekawe, co?

Mając obrazek o wymiarach naturalnych 640x480, możemy zadać mu wymiary 200x200. Jeśli teraz nadamy mu właściwość object-fit o wartości np. contain, to obrazek wciśnie się na pełną szerokość 200px, a wysokość wyniesie 150px (zachowa proporcje). Pod i nad obrazkiem będą przestrzenie po 25px, bo obrazek dla wszystkich wartości jest domyślnie centrowany w pionie i poziomie.

<img src="mario-1557240_640.jpg" />
<img src="mario-1557240_640.jpg" class="none" />
<img src="mario-1557240_640.jpg" class="cover" />
<img src="mario-1557240_640.jpg" class="contain" />
<img src="mario-1557240_80.jpg" class="scale-down" />

+

img {
  width: 100px;
  height: 100px;
  border: 1px solid #000;
  object-fit: fill;
}

img.none {
  object-fit: none;
}

img.cover {
  object-fit: cover;
}

img.contain {
  object-fit: contain;
}

img.scale-down {
  object-fit: scale-down;
}

Zobaczmy jak to wygląda. Mamy tu przykłady w takiej kolejności jak wartości wymienione wyżej. W ostatnim przykładzie został użyty mniejszy obrazek, tak aby pokazać, że nie zostaje przeskalowany w górę, do kontenera. Czarna ramka, to ramka... obrazka.

Sam sobie sterem w kontenerze.

Jak widzisz tło obrazka ustawiane jest zawsze w centrum kontenera. Podobnie jak w przypadku background-position, tu też jest możliwe przesunięcie tła. Tła, a nie obrazka. Tło ustawiamy za pomocą właściwości object-position, natomiast sam obrazek pozycjonujemy standardowo (albo w ogóle, albo za pomocą position, marginesów, itd.). Czyli za pomocą position ustawiamy naszą walizkę w bagażniku, a za pomocą object-position ustawiamy nasz termos w walizce. O ile wartości bezwzględne (px, em, rem, itp.) są oczywiste, to wartości względne już nie całkiem. Zobacz poniżej. Domyślnie zawartość wszystkich obrazków ustawiona jest na 1px od lewej i 1px od góry. Natomiast po kliknięciu wszystkie ustawiają się w pozycji 80% 20%.

Jak zauważyłeś niektóre z nich nie zmieniają pozycji, niektóre przesuwają się w lewo, a niektóre w prawo. Dlaczego tak się dzieje? Znów musimy podeprzeć się obrazkiem. Tym razem szkic:

Mamy tu pokazane trzy sytuacje. Mogą one być analogią do ustawień: scale-down, contain i cover. We wszystkich trzech wariantach pokazanych na szkicu, zasada obliczania przesunięcia jest identyczna. Wolna przestrzeń to: C=A-B. Jeśli zawartość jest mniejsza od szerokości box'a i ma być wycentrowana, to wolna przestrzeń (różnica między wymiarami) dzielona jest na pół (w przypadku przesunięcia 50%) i dodawana z lewej, czyli zawartość przesuwa się w lewo. Jeśli wymiary są równe, to brak przestrzeni, a co za tym idzie, brak przesunięcia. Jeśli natomiast zawartość jest większa od szerokości box'a, to różnica jest ujemna, więc przesuniecie będzie ujemne - w lewo. Analogicznie jest w przypadku wysokości i przesunięcia pionowego.

Najczęściej będziesz pewnie używać domyślnego object-position, które wycentruje zawartość. Ciekawszym wykorzystaniem tej właściwości z innym ustawieniem może być slider z jednego obrazka. Ustawiasz box obrazka na zadany wymiary, a jego zawartość stanowi bitmapa sklejona z trzech slajdów. Ponieważ właściwość object-position jest animowalna, możesz cyklicznie przesuwać pozycję o jeden slajd (w przypadku bitmapy z 5 slajdów, byłoby to 20%). Inne wykorzytanie to popularna lupa, którą możemy zobaczyć powiększony fragment obrazka.

W kolejnym wpisie przyjrzymy się kolejnemu problemowi. Bez wciskania... kitu!