71

Here is my JsFiddle

When I inspect the size of the anchor tags with Chrome developer tools it shows me 144px*18px for the 1st element and 310px*18px for the 2nd element.

I want to know why it does not take the height and width of the containing element and how it is being calculated.

.gallery {
    background-color: #abcdef;
}
.gallery img {
    display: inline-block;
    margin-left: 20px;
    margin-top: 20px;
}
.normal {
    height: 160px;
    width: 110px;
    border: 5px solid black;
}
.wide {
    height: 160px;
    width: 280px;
    border: 5px solid black;
}
<div class="gallery">
    <a href="#"> <img class="normal" src=""> </a>
    <a href="#"> <img class="wide" src=""> </a>
</div>
Matt
  • 1,518
  • 4
  • 16
  • 30
shubendrak
  • 2,038
  • 4
  • 27
  • 56
  • Possible duplicat [Inheriting height of a child node (IMG inside A)](http://stackoverflow.com/questions/8348381/inheriting-height-of-a-child-node-img-inside-a). – Vucko Sep 03 '13 at 06:30
  • 1
    anchor tags are inline elements. Inline elements do not fill the width of their container, they only fill the width of the content they contain. It's as simple as that. Think about it like this, if it was a block element, then you couldn't place a link on a single word in a sentence. – Erik Funkenbusch Sep 03 '13 at 07:08

7 Answers7

54

The CSS 2.1 spec says

The dimensions of the content area of a box — the content width and content height — depend on several factors: whether the element generating the box has the 'width' or 'height' property set, whether the box contains text or other boxes, whether the box is a table, etc. Box widths and heights are discussed in the chapter on visual formatting model details.

The <a> element defaults to a display value of inline. Its contents participate in the layout so it is a non-replaced element.

For height, the spec says:

10.6.1 Inline, non-replaced elements

The 'height' property does not apply. The height of the content area should be based on the font, but this specification does not specify how.

So 18px is arrived at from a single line of text, taken from the font metrics. Neither the larger image content, nor the containing block size plays any part.

For width, the spec says

10.3.1 Inline, non-replaced elements

The 'width' property does not apply. A computed value of 'auto' for 'margin-left' or 'margin-right' becomes a used value of '0'.

in other words, the width is determined by the <a> element's contents, paddings, borders and margins.

For the first <a> element that's 114px (contents - image plus one space) + 20px (left margin) + 2x5px (left and right border) = 144px

For the second <a> element that's 280px (contents - image) + 20px (left margin) + 2x5px (left and right border) = 310px

Just need to account for the spaces. The elements are being laid out in a line box in a inline context, so the spaces at the start of the first <a> element and at the end of the second <a> element are being dropped. The spaces at the end of the first <a> element and the start of the second <a> element are being collapsed into one space. When spaces are collapsed, it's always the first space which remains, which in this case is the one at the end of first <a> element, so that's why a space participates in the width of the first <a> element but not in the width of the second one.

Alohci
  • 78,296
  • 16
  • 112
  • 156
53

use display:inline-block in anchor

.gallery a{
    display:inline-block;
}

here is updated jsFiddle File

also remove margin from image and add it to anchor

.gallery a{
    display: inline-block;
    margin-left: 20px;
    margin-top: 20px;
}
Roy Sonasish
  • 4,571
  • 20
  • 31
  • I knew this would solve my problem but i want an explanation why that happen if we don't provide display: inline-block; – shubendrak Sep 03 '13 at 06:07
  • and i am also confused for getting space whether i should provide margin for anchor tag or img tag. can you tell me which one is good and why – shubendrak Sep 03 '13 at 06:08
  • anchor is inline element, we need to style it as display block or display inline-block to display proper width and height, adding margin in images will take blank space with anchor tag, so why we have add margin in anchor. – Roy Sonasish Sep 03 '13 at 06:13
  • 2
    Thank you for a concise answer that includes the solution. – Tod Birdsall Jul 08 '15 at 13:55
11

anchor is always display: inline by default. To make anchor took it's child space, you must give him a display:block, or in this case, display:inline-block so that they will be inlineand block.

a{
    display:inline-block;
}

JSFiddle

Read this question for more info.

Community
  • 1
  • 1
Vucko
  • 20,555
  • 10
  • 56
  • 107
4

The a tag's need to be styled as well

I added

.gallery a {
display: inline-block;
}
Tamil Selvan C
  • 19,913
  • 12
  • 49
  • 70
Anagio
  • 3,005
  • 9
  • 44
  • 81
  • 2
    This does show the link taking the height of it's child in the 'inspect element tool' but it does not however make it clickable ... – nclsvh Oct 18 '16 at 10:02
2

I had the same issue, for example, I have HTML generated by GitHub flavored markdown, so I can have paragraphs containing anchor with images inside.

Actually setting display: inline-block in anchors did not work for me; I did also set display: block in images. Using Sass nested something it looks like this:

.gallery {
  a {
      display: inline-block;

      img {
        display: block;
      }
  }
}
Gianluca Casati
  • 3,303
  • 1
  • 32
  • 20
0

Instead of applying {display: inline-block} on <a> , try applying {float: left} on the child of <a>. The height of the <a> would now match the height of the child.

Prashant Nair
  • 306
  • 3
  • 9
0

Another solution is to use a negative margin-bottom attribute with the img element (the size depends on the font, so, it's better to be sure of the used font by using an @font rule, 0.2em was fine for the font I use, moreover, using em units is a good idea as the size depends on the font, so, if you change the font-size later, you won't have to change this CSS code):

HTML:

Something, <a href="#"><img src="whatever.png" alt="Whatever" /></a>, something else.

CSS:

a:link {
 display: inline-block;
}
img {
 margin-bottom: -0.2em;
}

That way, all the texts are well aligned with the image, whatever it's in a link or not, I've done that to have all image + text blocks displayed the same way, but you might use a > img instead of just img in the above code.

By the way, I came up with this solution because I had something like:

a[something]:link::after {
 content=" something to add"
}

so, the img {display: block;} was not an option for me as the “ something to add” would have been under the image and the rest of the text after, this would have cut the reading flow.