Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doctype affects size so much?

The following code draws nice oval button from image parts without doctype. Original image is 143x45 and correctly sliced.

<body bgcolor="#000000" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">


<div style="position:absolute; left:200px; top:200px">
    <table border="0" cellpadding="0" cellspacing="0">
        <tr>
            <td style="width:19px; height:3px; background-image:url('images/button_01.png')"></td>
            <td style="height:3px; background-image:url('images/button_02.png')"></td>
            <td style="width:20px; height:3px; background-image:url('images/button_03.png')"></td>
        </tr>
        <tr>
            <td style="width:19px; height:19px; background-image:url('images/button_04.png')"></td>
            <td style="background-color:rgb(183,174,130)" rowspan="3">

                Some text

            </td>
            <td style="width:20px; height:19px; background-image:url('images/button_06.png')"></td>
        </tr>
        <tr>
            <td style="width:19px; background-image:url('images/button_07.png')"><img src="images/button_07.png" width="19" height="1" alt=""></td>
            <td style="width:20px; background-image:url('images/button_08.png')"><img src="images/button_08.png" width="20" height="1" alt=""></td>
        </tr>
        <tr>
            <td style="width:19px; height:19px; background-image:url('images/button_09.png')"></td>
            <td style="width:20px; height:19px; background-image:url('images/button_10.png')"></td>
        </tr>
        <tr>
            <td style="width:19px; height:3px; background-image:url('images/button_11.png')"></td>
            <td style="height:3px; background-image:url('images/button_12.png')"></td>
            <td style="width:20px; height:3px; background-image:url('images/button_13.png')"></td>
        </tr>
    </table>
</div>

</body>

But if I add declaration

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

to the beginning of document, the button becomes much taller as if something is present in central part.

Why is it so? Is it possible to avoid such behavior? What is better: find a way to make this working on HTML 4.01 or change doctype to more modern one?

like image 507
Dims Avatar asked Dec 26 '11 09:12

Dims


People also ask

Why is the doctype important?

The HTML document type declaration, also known as DOCTYPE , is the first line of code required in every HTML or XHTML document. The DOCTYPE declaration is an instruction to the web browser about what version of HTML the page is written in. This ensures that the web page is parsed the same way by different web browsers.

Is doctype HTML really necessary?

Even though a doctype may look a bit strange, it is required by the HTML and XHTML specifications. If you don't include one you will get a validation error when you check the syntax of your document with the W3C Markup validator or other tools that check HTML documents for errors.

What happens if we remove doctype?

The absence of the DOCTYPE or its incorrect usage will force the browser to switch to quirks mode. It means that the browser will do its best to layout the page that is considered to be old or created against web standards.

What is strict doctype?

The HTML 4.01 strict doctype validates against the HTML 4.01 spec, although it doesn't allow any presentational markup or deprecated elements (such as elements) or framesets to be used. If you are using an XHTML doctype, you need to use XML well-formed syntax.


3 Answers

Why is it so?

Understanding why things happen the way they do in CSS is not something most web designers or web authors worry about. Often, the reason involves the interaction of various parts of the CSS spec. That's also why browser manufacturers took so long to get some of this right, and therefore why, when you don't use a DOCTYPE, and hence get quirks mode, you get layout behaviour that sometimes seems more intuitive than when you use a DOCTYPE to get standards mode, where the CSS rules are strictly followed.

It's usually sufficient for authors to know that something happens, and what to do when it happens. More of which at the bottom of this answer.

However, the reasons are to be found in the CSS 2.1 spec with some searching.

First, some definitions we need to understand:

9.2.1 Block-level elements and block boxes

Block-level elements are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the 'display' property make an element block-level: 'block', 'list-item', and 'table'.

...

9.2.2 Inline-level elements and inline boxes

Inline-level elements are those elements of the source document that do not form new blocks of content; the content is distributed in lines (e.g., emphasized pieces of text within a paragraph, inline images, etc.) ....

Inline-level boxes that are not inline boxes (such as replaced inline-level elements, inline-block elements, and inline-table elements) are called atomic inline-level boxes because they participate in their inline formatting context as a single opaque box.

Then, we also need to understand the concept of a line box:

9.4.2 Inline formatting contexts

In an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. Horizontal margins, borders, and padding are respected between these boxes. ... The rectangular area that contains the boxes that form a line is called a line box.

... The height of a line box is determined by the rules given in the section on line height calculations.

...

Line boxes are created as needed to hold inline-level content within an inline formatting context. ...

So an <img> is a replaced inline element, which establishes an inline-level box, which establishes a line box, which is laid out in a block container object like a <div>, or a <td>. The line box height is then determined by those line height calculations:

10.8 Line height calculations: the 'line-height' and 'vertical-align' properties

As described in the section on inline formatting contexts, user agents flow inline-level boxes into a vertical stack of line boxes. The height of a line box is determined as follows:

  1. The height of each inline-level box in the line box is calculated. For replaced elements, inline-block elements, and inline-table elements, this is the height of their margin box; for inline boxes, this is their 'line-height'. (See "Calculating heights and margins" and the height of inline boxes in "Leading and half-leading".)
  2. The inline-level boxes are aligned vertically according to their 'vertical-align' property. In case they are aligned 'top' or 'bottom', they must be aligned so as to minimize the line box height. If such boxes are tall enough, there are multiple solutions and CSS 2.1 does not define the position of the line box's baseline (i.e., the position of the strut, see below).
  3. The line box height is the distance between the uppermost box top and the lowermost box bottom. (This includes the strut, as explained under 'line-height' below.)

Working through the steps, the <img height="1"> itself, only causes the line-height to be one pixel high, so that leaves the strut. This is described in the section on leading and half-leading:

10.8.1 Leading and half-leading

...

On a block container element whose content is composed of inline-level elements, 'line-height' specifies the minimal height of line boxes within the element. The minimum height consists of a minimum height above the baseline and a minimum depth below it, exactly as if each line box starts with a zero-width inline box with the element's font and line height properties. We call that imaginary box a "strut." ...

The height and depth of the font above and below the baseline are assumed to be metrics that are contained in the font. ...

So there we have it. The line box, created by the <img> element, has an imaginary inline box at the start, whose height is determined by the font size, which causes the line box to be high enough to contain a character of that font.

Is it possible to avoid such behavior?

From the explanation above, two options are available:

  1. The line box is created from the inline <img> element. So if the element is changed to be a block level element, there's no line box, and no problem.

    i.e. in CSS td img { display:block; }

  2. Since the height is caused by the strut which is dependent on the font size, changing the font size to 0 in that place also solves the problem.

    i.e. in CSS tr:nth-of-type(3) td { font-size:0px }

    (You may wish to put a class on the third <tr> and use that instead of :nth-of-type(3) for compatibility with non CSS 3 supporting browsers)

What is better: find a way to make this working on HTML 4.01 or change doctype to more modern one?

The most modern one is <!DOCTYPE html>. Your page will work exactly the same with that as it does with <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">, because both cause standards mode in browsers.

like image 59
Alohci Avatar answered Oct 17 '22 01:10

Alohci


Without DOCTYPE, each web browser acts in their unique way, we call "quirk mode". With DOCTYPE, the result will accord with the standard given in DOCTYPE tag, in your case, we call "Strict mode" because you provide ".../strict.dtd".

In my opinion, you should stick to the standards. Because each kind of browser has their own quirk mode and produce unpredictable result from this browser to another browser.

like image 30
hirikarate Avatar answered Oct 16 '22 23:10

hirikarate


Each browser got its standards, but if you use a doctype it takes that for the standards. I hope that this helps you.

like image 39
Robin Van den Broeck Avatar answered Oct 16 '22 23:10

Robin Van den Broeck