views:

1441

answers:

8

I've heard that putting a block element inside a inline element is a HTML sin:

<a href="http://www.mydomain.com"&gt;&lt;div&gt;
What we have here is a problem. 
You see, an anchor element is an inline element,
and the div element is a block level element.
</div></a>

But what about if you style the outer anchor as "display:block" in the stylesheet? Is it still wrong? The HTML 4.01 spec on block-level and inline elements seems to think so:

Style sheets provide the means to specify the rendering of arbitrary elements, including whether an element is rendered as block or inline. In some cases, such as an inline style for list elements, this may be appropriate, but generally speaking, authors are discouraged from overriding the conventional interpretation of HTML elements in this way.

Does anyone have any further tips about this issue?

+1  A: 

If you're going to go to the effort of making <a> block, why not put <a> inside the div, being a block element it'll give you the same effect.

Dave
Because I might want the anchor to enclose multiple divs.
Tom
I didn't think before I posted that response D:
Dave
+2  A: 

The W3C doc doesn't use concepts like wrong and sin, but it does use those like provide the means, may be appropriate and discouraged.

Actually, in the second paragraph of section 4, the 4.01 spec itemizes its words as follows

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119]. However, for readability, these words do not appear in all uppercase letters in this specification.

With that in mind, I believe the definitive statement is in 7.5.3 Block-level and inline elements, where it says

Generally, inline elements may contain only data and other inline elements.

The condition "generally" appears to introduce enough ambiguity to say that HTML 4.01 does allow inline elements to contain block elements.

Certainly, CSS2 has a display property value, inline-block, that appears to be suited to the purpose you describe. I'm not sure if it was ever widely supported, but it seems that someone anticipated the need for that kind of behavior.

The DTD appear to be less forgiving here, but the text of the DTD defers to the spec:

The HTML 4.01 specification includes additional syntactic constraints that cannot be expressed within the DTDs.

In another comment, you suggest that you want to make a block active by wrapping it in an anchor. I don't believe HTML prohibits that, and CSS clearly allows it. So to answer the title question about whether it is ever correct, I say yes. By the standards, it is sometimes correct.

Ewan Todd
You had me until you mentioned doctype.
Robert Harvey
Not doctype, doctype.com
Ewan Todd
Yes, I know what you meant.
Robert Harvey
Better? .......
Ewan Todd
You're probably right - I should have used doctype.com. Opps - I'll try to remember for next time around. PHP -> SO, HTML -> doctype.com
Tom
I'm don't have a strong preference of forum for this question. I'm interested in Robert Harvey's take on doctype, though.
Ewan Todd
My take is there's not a "vote to close as belongs on doctype.com" option (nor should there be).
Robert Harvey
I agree with Rob - Stack Overflow is for programming. HTML/CSS is certainly programming in my view.
DisgruntledGoat
+5  A: 

No it won't validate, but yes it generally will work in modern browsers. That being said, use a span inside your anchor, and set display: block on it as well, that will definitely work everywhere, and it will validate!

Eloff
+1  A: 

If you change it to a block-style element, then no, it's no longer 'wrong', but it probably won't validate. But it doesn't make much sense to do what you're doing. You should either just keep the anchor tag as a block level element with no inner div, or put the div on the outside.

Chris
+1  A: 

You can't put <div> inside <a> - it's not valid (X)HTML.

Even though you style a span with display: block you still can't put block-level elements inside it: the (X)HTML still has to obey the (X)HTML DTD (whichever one you use), no matter how the CSS alters things.

The browser will probably display it as you want, but that doesn't make it right.

Greg
+15  A: 

HTML 4.01 specifies that <a> elements may only contain inline elements. A <div> is a block element, so it may not appear inside an <a>.

Of course you are at liberty to style an inline element such that it appears to be a block, or indeed style a block so that it is rendered inline. The use of the terms inline and block in HTML refers to the relationship of the elements to the semantic structure of the document, whereas the same terms in CSS are related more to the visual styling of the elements. If you make inline elements display in a blocky manner, that's fine.

However you should ensure that the structure of the document still makes sense when CSS is not present, for example when accessed via an assistive technology such as a screen reader - or indeed when examined by the mighty Googlebot.

If you want to be cutting-edge, HTML5 allows <a> elements to contain blocks.

NickFitz
Can you explain where the HTML 4.01 spec "specifies that <a> elements may only contain inline elements"? I can't find it.
Ewan Todd
There is a DTD for 4.01 at http://www.w3.org/TR/REC-html40/sgml/dtd.html . A can contain %inline%; %inline% is a bunch of different stuff (you can follow the links) but DIV is not among them. Thus, an A with a DIV inside is not XML-validatable. I think that DTD expresses the intentions of the committee pretty well, so I'd say: No.
Carl Smotricz
@Ewan: the first link in my answer is to the relevant section of HTML 4.01.
NickFitz
+2  A: 

It's wrong. Use a span.

Jon Hadley
+1  A: 

There's a DTD for HTML 4 at http://www.w3.org/TR/REC-html40/sgml/dtd.html . This DTD is the machine-processable form of the spec, with the limitation that a DTD governs XML and HTML 4, especially the "transient" flavor, permits a lot of things that are not "legal" XML. Still, I consider it comes close to codifying the intent of the specifiers.

<!ELEMENT A - - (%inline;)* -(A)       -- anchor -->

<!ENTITY % inline "#PCDATA | %fontstyle; | %phrase; | %special; | %formctrl;">

<!ENTITY % fontstyle "TT | I | B | BIG | SMALL">

<!ENTITY % phrase "EM | STRONG | DFN | CODE | SAMP | KBD | VAR | CITE | ABBR | ACRONYM" >

<!ENTITY % special "A | IMG | OBJECT | BR | SCRIPT | MAP | Q | SUB | SUP | SPAN | BDO">

<!ENTITY % formctrl "INPUT | SELECT | TEXTAREA | LABEL | BUTTON">

I would interpret the tags listed in this hierarchy to be the total of tags allowed.

While the spec may say "inline elements," I'm pretty sure it's not intended that you can get around the intent by declaring the display type of a block element to be inline. Inline tags have different semantics no matter how you may abuse them.

On the other hand, I find it intriguing that the inclusion of special seems to allow nesting A elements. There's probably some strong wording in the spec that disallows this even if it's XML-syntactically correct but I won't pursue this further as it's not the topic of the question.

Carl Smotricz
Do you know what `- -` means. I tried to find an explanation but I couldn't find one.
Ewan Todd