Obraz wewnątrz div ma dodatkową przestrzeń pod obrazem

502

Dlaczego w poniższym kodzie wysokość divjest większa niż wysokość img? Pod obrazem jest przerwa, ale nie wygląda ona na margines.

Jaka jest przerwa lub dodatkowa przestrzeń pod obrazem?

#wrapper {
  border: 1px solid red;
  width:200px;
}
img {
  width:200px;
}
<div id="wrapper">
  <img src="http://i.imgur.com/RECDV24.jpg" />
</div>

Obraz ze szczeliną lub białą spacją pod nim

Misza Moroszko
źródło
10
Oto krótka i pełna odpowiedź na to pytanie: stackoverflow.com/a/31445364/3597276
Michael Benjamin
1
Oto dobra lektura na ten temat: Dziwna luka <img> w HTML
Matheus Avellar

Odpowiedzi:

600

Domyślnie obraz jest renderowany liniowo, podobnie jak litera, więc znajduje się w tej samej linii, na której znajdują się litery a, b, cid.

Poniżej tego wiersza znajduje się spacja dla potomków, które można znaleźć na literach takich jak g, j, p i q.

Demonstracja zstępujących

Możesz:

  • dostosuj vertical-alignobraz, aby ustawić go w innym miejscu (np. middle) lub
  • zmień displaytak, aby nie był wbudowany.

div {
  border: solid black 1px;
  margin-bottom: 10px;
}

#align-middle img {
  vertical-align: middle;
}

#align-base img {
  vertical-align: bottom;
}

#display img {
  display: block;
}
<div id="default">
<h1>Default</h1>
  The quick brown fox jumps over the lazy dog <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/VangoghStarry-night2.jpg/300px-VangoghStarry-night2.jpg" alt="">
</div>

<div id="align-middle">
<h1>vertical-align: middle</h1>
  The quick brown fox jumps over the lazy dog <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/VangoghStarry-night2.jpg/300px-VangoghStarry-night2.jpg" alt=""> </div>
  
  <div id="align-base">
<h1>vertical-align: bottom</h1>
  The quick brown fox jumps over the lazy dog <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/VangoghStarry-night2.jpg/300px-VangoghStarry-night2.jpg" alt=""> </div>

<div id="display">
<h1>display: block</h1>
  The quick brown fox jumps over the lazy dog <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/VangoghStarry-night2.jpg/300px-VangoghStarry-night2.jpg" alt="">
</div>


Dołączony obraz jest własnością publiczną i pochodzi z Wikimedia Commons

Quentin
źródło
9
Mówiąc ściślej, zdarza się, że elementy wbudowane b / c zajmują przestrzeń ich prądu line-height. Ustawienie line-heightpożądanego wymiaru przezwyciężyłoby również niepożądane białe znaki.
Kevin Boucher
3
Czy „f” kwalifikuje się jako zstępny?
j08691
2
@ j08691 - Zależy od czcionki.
Quentin,
134

Inną sugerowaną tutaj opcją jest ustawienie stylu obrazu jakostyle="display: block;"

Thea
źródło
4
dzięki. To rozwiązało również podobny problem ze spacją pod filmem flash. (dodano display: blok do osadzania / znaczników obiektowych)
jessieloo,
5
lub inline-blockjeśli nadal chcesz, aby wyświetlał się w linii, tak jak zwykle to robią obrazy.
Ian
6
@Ian @Imperative inline-blocknie działa.
p.matsinopoulos
93

Szybka naprawa:

Aby usunąć odstęp pod obrazem , możesz:

  • Ustaw właściwość wyrównania w pionie obrazu na vertical-align: bottom; vertical-align: top;lubvertical-align: middle;
  • Ustaw właściwość wyświetlania obrazu na display:block;

Zobacz poniższy kod do prezentacji na żywo:


Wyjaśnienie: dlaczego pod obrazem jest przerwa?

Luka lub dodatkowe miejsce pod obrazem nie jest błędem ani problemem, jest to zachowanie domyślne. Główną przyczyną jest to, że obrazy są zastąpionymi elementami ( patrz Elementy zastąpione MDN ). To pozwala im „zachowywać się jak obraz” i mieć własne wewnętrzne wymiary, proporcje…
Przeglądarki obliczają swoje właściwości wyświetlania, inlineale dają im specjalne zachowanie, które zbliża ich doinline-block elementów (ponieważ można je wyrównać w pionie, dać im wysokość, górny / dolny margines i wypełnienie, przekształca ...).

Oznacza to również, że:

<img>nie ma linii bazowej, więc gdy obrazy są używane w kontekście formatowania wbudowanego z wyrównaniem pionowym: linia bazowa, dolna część obrazu zostanie umieszczona na linii bazowej tekstu.
( źródło: MDN , moje podkreślenie )

Ponieważ przeglądarki domyślnie obliczają właściwość wyrównania pionowego do linii bazowej, jest to zachowanie domyślne. Poniższy obraz pokazuje położenie linii bazowej na tekście:

Lokalizacja linii bazowej na tekście ( Źródło obrazu )

Wyrównane elementy linii bazowej muszą zachować przestrzeń dla zejść, które rozciągają się poniżej linii bazowej (jak j, p, g ...), jak widać na powyższym obrazku. W tej konfiguracji spód obrazu jest wyrównany do linii podstawowej, jak widać w tym przykładzie:

div{border:1px solid red;font-size:30px;}
img{width:100px;height:auto;}
<div>
  <img src="http://i.imgur.com/RECDV24.jpg" />jpq are letters with descender
</div>


Właśnie dlatego domyślne zachowanie <img>znacznika tworzy lukę na dnie kontenera i dlatego zmiana właściwości wyrównania w pionie lub właściwości wyświetlania usuwa ją jak w poniższej wersji demonstracyjnej:

div {width: 100px;border: 1px solid red;}
img {width: 100px;height: auto;}

.block img{
  display:block;
}
.bottom img{
  vertical-align:bottom;
}
<p>Default:</p>
<div>
  <img src="http://i.imgur.com/RECDV24.jpg" />
</div>
<p>With display:block;</p>
<div class="block">
  <img src="http://i.imgur.com/RECDV24.jpg" />
</div>
<p>With vertical-align:bottom;</p>
<div class="bottom">
  <img src="http://i.imgur.com/RECDV24.jpg" />
</div>

web-tiki
źródło
Dlatego ustawienie rozmiaru czcionki na 0 nie działa. czy to robi?
Persijn
2
@Persijn robi. Jak ustawienie, line-height:0;ale nie uważam tego za dobre obejście w porównaniu do zmiany właściwości wyrównania w pionie lub właściwości wyświetlania
web-tiki
2
Należy jednak pamiętać, że niektóre przeglądarki nie przestrzegają font-size:0: ustawiają rozmiar czcionki na minimalny rozmiar w ustawieniach użytkownika.
Pan Lister,
Tak, wydaje się, że jest to biała przestrzeń.
mrbengi
cóż, myślę, że middle text-top sub superpozycja na zdjęciu jest niewłaściwa.
xianshenglu
40

Można również zerować wysokość linii rodzica:

#wrapper {
  line-height: 0;
}

Wszystkie poprawki: http://jsfiddle.net/FaPFv/

Pavlo
źródło
5
OSTRZEŻENIE! spowoduje to również zabicie wszystkich węzłów tekstowych w #wrapper. jak zostanie odziedziczony. Ale punkty bonusowe za tego niesamowitego skrzypka! tutaj jest aktualizowany o węzły tekstowe. jsfiddle.net/FaPFv/30
gcb
Alternatywnie, rozmiar czcionki: 0
Kiran
13

Wszystko, co musisz zrobić, to przypisać tę właściwość:

img {
    display: block;
}

Obrazy domyślnie mają tę właściwość:

img {
    display: inline;
}
Daniel Díaz
źródło
7

Możesz użyć kilku metod dla tego problemu, takich jak

  1. Za pomocą line-height

    #wrapper {  line-height: 0px;  }
  2. Za pomocą display: flex

    #wrapper {  display: flex;         }
    #wrapper {  display: inline-flex;  }
  3. Korzystanie z display: block, table, flexiinherit

    #wrapper img {  display: block;    }
    #wrapper img {  display: table;    }
    #wrapper img {  display: flex;     }
    #wrapper img {  display: inherit;  }
Santosh Khalse
źródło
Proszę nie polecać bardzo niechlujnego line-heightwłamania, a przynajmniej wyjaśnić, dlaczego jest to najgorsze „rozwiązanie” ze wszystkich: w momencie, gdy ktoś umieszcza tekst obok obrazu (zwłaszcza wstępnie sformatowany wieloliniowy z tagami BR), znajdzie się w gorszej sytuacji niż na początku.
Sz.
5

Użyłem line-height:0i działa dobrze dla mnie.

Abdulla Khan
źródło
Przepraszam, -1: to psuje pozycjonowanie tekstu, więc jeśli ktoś również umieści jakiś tekst (szczególnie powiedzmy, z <BR>tekstem) obok obrazu, będzie miał źle ustawiony, nakładający się / nadwieszony bałagan.
Sz.
3

Zauważyłem, że działa świetnie przy użyciu display: block; na obrazie i wyrównaj w pionie: do góry; na tekście.

.imagebox {
    width:200px;
    float:left;
    height:88px;
    position:relative;
    background-color: #999;
}
.container {
    width:600px;
    height:176px;
    background-color: #666;
    position:relative;
    overflow:hidden;
}
.text {
    color: #000;
    font-size: 11px;
    font-family: robotomeduim, sans-serif;
    vertical-align:top;
    
}

.imagebox img{ display:block;}
<div class="container">
    <div class="imagebox">
        <img src="http://machdiamonds.com/n69xvs.jpg" /> <span class="text">Image title</span>
    </div>
    <div class="imagebox">
        <img src="http://machdiamonds.com/n69xvs.jpg" /> <span class="text">Image title</span>
    </div>
    <div class="imagebox">
        <img src="http://machdiamonds.com/n69xvs.jpg" /> <span class="text">Image title</span>
    </div>
    <div class="imagebox">
        <img src="http://machdiamonds.com/n69xvs.jpg" /> <span class="text">Image title</span>
    </div>
    <div class="imagebox">
        <img src="http://machdiamonds.com/n69xvs.jpg" /> <span class="text">Image title</span>
    </div>
    <div class="imagebox">
        <img src="http://machdiamonds.com/n69xvs.jpg" /> <span class="text">Image title</span>
    </div>
</div>

lub możesz edytować kod JS FIDDLE

Tymotka
źródło
-1

Właśnie dodałem float:leftdo div i zadziałało

TomoMiha
źródło
9
To dlatego, że ustawienie float:leftpowodujedisplay:block
Kevin Boucher