Why anchor tag does not take height and width of its containing element
HtmlCssHtml Problem Overview
Here is my http://jsfiddle.net/ttftC/">JsFiddle</a>
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>
Html Solutions
Solution 1 - Html
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;
}
Solution 2 - Html
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.
Solution 3 - Html
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 inline
and block
.
a{
display:inline-block;
}
Solution 4 - Html
The a tag's need to be styled as well
I added
.gallery a {
display: inline-block;
}
Solution 5 - Html
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;
}
}
}
Solution 6 - Html
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.
Solution 7 - Html
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.