Why is there a gap between my image and its containing box? - html

When my browser renders the following test case, there's a gap below the image. From my understanding of CSS, the bottom of the blue box should touch the bottom of the red box. But that's not the case. Why?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>foo</title>
</head>
<body>
<div style="border: solid blue 2px; padding: 0px;">
<img alt='' style="border: solid red 2px; margin: 0px;" src="http://stackoverflow.com/Content/Img/stackoverflow-logo-250.png" />
</div>
</body>
</html>

Inline elements are vertically aligned to the baseline, not the very bottom of the containing box. This is because text needs a small amount of space underneath for descenders - the tails on letters like lowercase 'p'. So there is an imaginary line a short distance above the bottom, called the baseline, and inline elements are vertically aligned with it by default.
There's two ways of fixing this problem. You can either specify that the image should be vertically aligned to the bottom, or you can set it to be a block element, in which case it is no longer treated as a part of the text.
In addition to this, Internet Explorer has an HTML parsing bug that does not ignore trailing whitespace after a closing element, so removing this whitespace may be necessary if you are having problems with Internet Explorer compatibility.

Because the image is inline it sits on the baseline. Try
vertical-align: bottom;
Alternately, in IE sometimes if you have whitespace around an image you get that. So if you remove all the whitespace between the div and img tags, that may resolve it.

line-height: 0; on the parent DIV fixes this for me. Presumably, this means the default line-height is not 0.

display: block
in the image fixes it as well, but probably breaks it in other ways ;)

Remove the line break before the tag, so that it directly follows the tag with no blanks between it.
I don't know why, but for the Internet Explorer, this works.

font-size:0; on the parent DIV is another tricky way to fix it.

Related

How do you limit the area that the background color takes up in an area in html?

I am fairly new to html therefore this may be something very basic for you. This is the css file for my code:
.sidepanel-list{
margin-left: 10px;
background-color:lightgray;
When i run the file, the background color I have mentioned takes up all the space on the lines as I have put in the image. How do I limit it so it only takes some of the space on the lines?
Image will make it way clearer to understand what i am saying: https://i.stack.imgur.com/04dYi.png
In CSS, an element has a certain size (obviously). Inside that element, you can add padding to keep text or whatever away from the edge. Outside it, you can add margin to keep other elements away from that element.
What this hopefully shows is that your code is doing exactly what you asked: making the background color of the element itself gray, and then adding a margin outside that area of 10px. (This is why the gray doesn't extend beyond the text, even though you've specified that 10px of left margin, which is pushing the text out from the edge of the window.)
If you want 10px of space between the text and the edge of the gray area, use padding instead of margin.
If what you want is to make the whole thing narrower, you need to apply a width to the stylesheet (e.g. width: 50% or width: 400px).
To get a feel for this stuff, it can help to use your browser's Inspector tool. Among other things, this will show you the size, padding and margin on each element, so you can see exactly what's happening with your layout.
<!DOCTYPE html>
<html>
<head>
<style>
p.set {
background-color:lightgray;
}
</style>
</head>
<body>
<p class="set"><b>Categories</p></b>
<p class="set">Cable & docks</p>
<p class="set">cases & films</p>
<p class="set">charging devices</p>
<p class="set">connected home</p>
<p class="set">headphones</p>
</body>
</html>

Irremovable bottom margin in div when using image

I am trying too code a simple thing: an image in a div with no space between their borders but somehow I always get a bottom margin (or padding depending on how you want to see it). I tried putting margin and padding to 0 but it doesn't change anything.
Here is the code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head>
<meta charset="utf-8"/>
<title>Sandbox</title>
<style>
*{margin:0;padding:0;}
div{
background:red;
}
</style>
</head>
<body>
<div>
<img src="image.jpg"/>
</div>
</body>
</html>
I tried on two browser already (Chrome, Maxthon) no luck. is it in the specification or all web browser are messing when it come to that?
Display your <img /> as a block-level element:
div > img {
display: block;
}
jsFiddle Demo
The problem and solution:
The reason is because inline-elements (such as images) align automatically to the baseline of the parent box unless modified by the vertical-align property. If you ever set a block-level element to display as an inline-block you'll often encounter this problem also. To fix this you align the image with the top or bottom of the div as follows:
img {
vertical-align: top;
}
Understanding baseline:
Baseline is easy to understand when thinking about text. Letters such as abcdefhiklmnorstuvwxz all sit on the baseline. There is, however, room under this line to handle letters that extend past the baseline. All other letters also sit on the baseline, but there is a portion of the letter that extends below the baseline. These include the letters: gjpqy. As inline elements (including images) sit on the baseline by default there will be extra space below them unless you modify the vertical-alignment.

Unable to set width/height to an img when DOCTYPE is set (Firefox)

Imagine three images with fixed size:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
div.photos img {
width: 320px;
height: 240px;
background-color: black;
}
</style>
</head>
<body>
<div class="photos">
<img src="abc" />
<img src="def" />
<img src="ghi" />
</div>
</body>
</html>
When you look at such page in IE or Chrome, you'll see what I expected - threee images with fixed sizes.
In Firefox however, it doesn't work.
But if I set the images to display: block; or remove the DOCTYPE (doesn't show on jsfiddle) it works.
What am I doing wrong?
Thanks
This seems to be an old feature in Firefox: I found a discussion about it from year 2007:
So I suppose it’s intentional and won’t go away. I guess they might be thinking this way: Everything is fine if you set dimensions on an image, we’ll scale it. But if the image is missing, we will render the alternative text instead, and this changes the img element from a replaced inline element to a text, a non-replaced inline element, and for it we won’t support height and width, by the spec. Instead, the text determines the dimensions. And presumably the authors of Firefox think this is the right thing to do, and only in Quirks Mdoe do they do as other browsers do.
If you add alt attributes (as you should, every img should have one), you’ll see how the box size varies by text length. Apparently Firefox treats a missing alt here as equivalent to alt="", implying zero width.
This would explain why setting display to inline-block (or block) changes the behavior: then width and height are applied.
I think firefox wont be applying height and width to <img> element which are empty and hence it must be rendering like that, so use CSS display: block;
Here's my fiddle
Or use an image and see...
Updated : fiddle

display:inline-block with border?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru">
<head>
<style type="text/css">
body { margin:0;padding:0;}
</style>
</head>
<body>
<div>
<div style="width:1000px;margin:0 auto;">
<div style="width:700px;display:inline-block;">1</div>
<div style="width:300px;display:inline-block;">2</div>
</div>
</div>
</body>
</html>
I want these blocks flush, but currently the second block is pushed down..
If I change the width of second block to 296px then it works..
I don't want to use float:left because it will require one more block with clear:both;.
This is what you have at the moment, but reduced in size:
I don't want to use float:left because
it requires one more block with
"clear:both;".
With float: left, you can clear/contain the floats without adding an element with clear: both. You can do this by adding overflow: hidden (or clearfix) on the parent element.
Without overflow: hidden
With overflow: hidden
If you want to stick with display: inline-block..
The first thing you need to do is remove the whitespace between the two divs.
With whitespace
Without whitespace
If you want to add a border, you can add wrapper elements and add the borders to that.
Or, you can use box-sizing: border-box as shown here.
If you want to use 2 elements in line (1000px total for 300+700px) - just set font-size:0 for container. This is very logical in this case and now you can use all benefits from inline-blocks, like align:justify!
You can only give display:inline-block to elements that are naturally inline (e.g. span, a)
Otherwise your element won't render correctly in older browsers (e.g. IE7-)
Include the width of the border in the width of the div.
If you want it to appear 300px wide on the screen, make it 298px (+1px for the left border, +1px for the right border = 300px). This is also true for padding.
Read up on the w3 box model versus the IE box model.

Why does absolute positionining within <button> works differently from <div>

I expect following code to put my span to the top-left corner of the button, but it doesn't. Why is that?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<style type='text/css'>
</style>
</head>
<body>
<button style='height:100px;width:100px;position:relative;'>
<span style='position:absolute;top:0;left:0;'>text</span>
</button>
</body>
</html>
<span> is placed relative to the vertical-middle line (with 3px padding I can't explain).
Replacing <button> with <div> does places <span> at the top-left corner.
Question: why does absolute positioning within button (with position:relative) behaves differently from layout using <div>? And how do I fix it?
Background: I use two absolutely positioned div's within button to create a floating-width button with rounded corners.
EDIT: IMPORTANT IE 8.0 works exactly as I expect it (span in the top-left corner), the problem I see is in Firefox (3.6.6).
I advice against using a <button> this way. It is really difficult to style and you'll end up having to write specific styles for different browsers.
I needed to achieve something very similar and after dealing with a large amount of exceptions and fiddly positioning to accommodate different browser rendering, I went for this structure instead:
<div class="button">
<span>
<button>Text</button>
</span>
</div>
With the button tag reset this way:
button {
background:none repeat scroll 0 0 transparent;
border:0 none;
font-family:inherit;
font-size:inherit;
font-weight:inherit;
margin:0;
overflow:visible;
padding:0;
position:relative;
}
You can even use js to wrap the <button> on page load. This system has turned out to be much more solid and reliable. Requiring less css and almost no browser specific styling.
Update:
As I commented below, the wrapping element should not be an <a> tag. Remember that we need the <button> to keeps its functionality, we just need it to be text only (form will still submit on enter).
You can still re-use any css that you may be using to turn standard links into expandable button widgets only in this case it;s a <div> instead of an <a>.
Your problem is only with Firefox?? (3.6.6) - Can't fix it with standard CSS. Try:
button::-moz-focus-inner {
border: 0;
padding: 0;
}
That will do it for Firefox hopefully. Good luck!