Jak mogę wyświetlić tylko część obrazu w HTML / CSS?

140

Załóżmy, że chcę wyświetlić tylko środek 50 x 50 pikseli na środku obrazu o wymiarach 250 x 250 pikseli w formacie HTML. Jak mogę to zrobić. Czy istnieje sposób, aby to zrobić w przypadku odwołań do css: url ()?

Zdaję sobie sprawę z klipu w CSS, ale wydaje się, że działa tylko w przypadku pozycjonowania bezwzględnego.

Hafthor
źródło
List Apart powinien znajdować się na liście wszystkich stron do odwiedzenia z problemami HTML / CSS / JS: Oto jeden sposób na zrobienie sprite'ów , a tutaj inny przy użyciu JS .
graham.reeds
1
Użyj sprite'a - patrz tutaj w3schools.com/css/css_image_sprites.asp

Odpowiedzi:

116

Jednym ze sposobów jest ustawienie obrazu, który chcesz wyświetlić jako tło w kontenerze (td, div, span itp.), A następnie dostosowanie pozycji tła, aby uzyskać żądany duszka.

Espo
źródło
1
Aby to wyjaśnić, ustaw szerokość i wysokość kontenera td, div, span lub cokolwiek na 50 pikseli, aby to zadziałało.
Paul D. Waite
7
@Espo, Wydaje się, że jest to dość standardowe podejście, ale co zrobić, jeśli masz obraz sprite, który zawiera kilka pojedynczych obrazów o rozmiarze 32x32 i chcesz wyświetlić 1 z nich na div, span itp., Który jest większy niż 32x32 .. .setting the background-position już nie działa.
Matthew Layton
2
@ series0ne Prawdopodobnie mógłbyś połączyć się zbackground-size
Stijn de Witt
163

Jak wspomniano w pytaniu, jest clipwłasnością CSS, chociaż nie wymaga, że element jest obcięty jest position: absolute;(co jest wstyd):

.container {
  position: relative;
}
#clip {
  position: absolute;
  clip: rect(0, 100px, 200px, 0);
  /* clip: shape(top, right, bottom, left); NB 'rect' is the only available option */
}
<div class="container">
  <img src="http://lorempixel.com/200/200/nightlife/3" />
</div>
<div class="container">
  <img id="clip" src="http://lorempixel.com/200/200/nightlife/3" />
</div>

Demo JS Fiddle , do eksperymentów.

Aby uzupełnić oryginalną odpowiedź - nieco z opóźnieniem - edytuję, aby pokazać użycie clip-path, które zastąpiło obecnie przestarzałą clipwłaściwość.

clip-pathWłaściwość umożliwia szeroki zakres opcji (bardziej, niż w oryginale clip), o:

  • inset- kształty prostokątne / prostopadłościenne, zdefiniowane za pomocą czterech wartości jako „odległość od” (top right bottom left).
  • circle- circle(diameter at x-coordinate y-coordinate).
  • ellipse- ellipse(x-axis-length y-axis-length at x-coordinate y-coordinate).
  • polygon- zdefiniowany przez szereg współrzędnych x/ yw stosunku do początku elementu w lewym górnym rogu. Ścieżka zostanie zamknięte automatycznie realistyczne minimalna liczba punktów dla wielokąta wynosi trzy, każda mniejsza (dwóch) jest linią albo (jedna) jest punkt polygon(x-coordinate1 y-coordinate1, x-coordinate2 y-coordinate2, x-coordinate3 y-coordinate3, [etc...]).
  • url - może to być lokalny adres URL (przy użyciu selektora identyfikatora CSS) lub adres URL pliku zewnętrznego (przy użyciu ścieżki do pliku) w celu zidentyfikowania SVG, chociaż nie eksperymentowałem z żadnym (jeszcze), więc nie mogą dać wglądu w ich korzyść lub zastrzeżenie.

div.container {
  display: inline-block;
}
#rectangular {
  -webkit-clip-path: inset(30px 10px 30px 10px);
  clip-path: inset(30px 10px 30px 10px);
}
#circle {
  -webkit-clip-path: circle(75px at 50% 50%);
  clip-path: circle(75px at 50% 50%)
}
#ellipse {
  -webkit-clip-path: ellipse(75px 50px at 50% 50%);
  clip-path: ellipse(75px 50px at 50% 50%);
}
#polygon {
  -webkit-clip-path: polygon(50% 0, 100% 38%, 81% 100%, 19% 100%, 0 38%);
  clip-path: polygon(50% 0, 100% 38%, 81% 100%, 19% 100%, 0 38%);
}
<div class="container">
  <img id="control" src="http://lorempixel.com/150/150/people/1" />
</div>
<div class="container">
  <img id="rectangular" src="http://lorempixel.com/150/150/people/1" />
</div>
<div class="container">
  <img id="circle" src="http://lorempixel.com/150/150/people/1" />
</div>
<div class="container">
  <img id="ellipse" src="http://lorempixel.com/150/150/people/1" />
</div>
<div class="container">
  <img id="polygon" src="http://lorempixel.com/150/150/people/1" />
</div>

Demo JS Fiddle , do eksperymentów.

Bibliografia:

David mówi, że przywróć Monikę
źródło
14
niesamowite znalezisko, wielkie dzięki :) Po prostu FYI, to nie jest tak ograniczone, jak mogłoby się wydawać. Jeśli masz element div kontenera obrazu (id = "img_container") wokół tagu img, po prostu ustaw img_container położenie względne i ustaw img jako bezwzględne, możesz
przyciąć
„pozycja: absolutna; (szkoda)”
Sanket Sahu
Nie żebym był tego świadomy, nie.
David mówi, że przywróć Monikę
6
clipjest przestarzały . Nowsze clip-pathnie wymagają pozycjonowania
eagor
3
podczas gdy klip jest przestarzały, wiele nowoczesnych przeglądarek nie obsługuje jeszcze clip-path. developer.mozilla.org/en-US/docs/Web/CSS/clip-path
barrypicker
37

Inną alternatywą jest następująca, choć nie najczystsza, ponieważ zakłada, że ​​obraz jest jedynym elementem w kontenerze, tak jak w tym przypadku:

<header class="siteHeader">
  <img src="img" class="siteLogo" />
</header>

Możesz następnie użyć kontenera jako maski o żądanym rozmiarze i otoczyć obraz ujemnym marginesem, aby przesunąć go we właściwe miejsce:

.siteHeader{
    width: 50px;
    height: 50px;
    overflow: hidden;
}

.siteHeader .siteLogo{
    margin: -100px;
}

Demo można zobaczyć w tym JSFiddle .

Wydaje się, że działa tylko w IE> 9 i prawdopodobnie we wszystkich ważnych wersjach wszystkich innych przeglądarek.

Vincent
źródło
2
Chociaż jest to bitc hacky, ma tę stronę plus, że działa to we wszystkich przeglądarkach (klip jest przestarzały, a clip-path nie działa w IE) oraz że działa, gdy próbujesz wydrukować stronę internetową (obrazy tła są domyślnie pomijane )
Rauni Lillemets
To jedyna prawdziwa metoda dla różnych przeglądarek. Wszystkie inne sposoby mają problemy. „Klip” został zdeprecjonowany, a pozycja tła nie jest prawidłowo odczytywana we wszystkich przeglądarkach.
Kareem