Why can’t I have a <table> inside an <h2>? - html

I would like to understand what is wrong with this:
<body>
<h2>
<table>
<tr>
<td> Text</td>
</tr>
</table>
</h2>
</body>
Validator complains:
document type does not allow element "table" here; missing one of "object", "ins", "del", "map", "button" start-tag
Further explanation says:
The mentioned element is not allowed to appear in the context in which you've placed it; the other mentioned elements are the only ones that are both allowed there and can contain the element mentioned. This might mean that you need a containing element, or possibly that you've forgotten to close a previous element.
One possible cause for this message is that you have attempted to put a block-level element (such as "<p>" or "<table>") inside an inline element (such as "<a>", "<span>",or "<font>").
Both h2 and table are block level so the last comment does not seem to apply. I want a table with h2 sized elements that is all... What is the right way to tell table to use the same size that h2 uses?
Thanks!

CSS. Tables are simply not allowed inside headings, since it makes no semantic sense. Have you ever seen a book chapter whose title was a table? Don't use HTML semantic tags for appearance; style them yourself.
It doesn't matter whether table is block or inline by CSS, only what the HTML DTD says they are. Look here: only "flow" elements are allowed into td. Follow the link to see the definition of "flow": you'll see it's "inline" or "block". You can continue to follow those links down, until you find that, e.g. sub is fine, as is span... but you won't find table.
Also - tables are not even display: block - they have their own layout value, display: table. Not that it matters.

CSS is the appropriate way to change the size of HTML elements. HTML isn’t designed to be used to create visual effects.
There’s no way in CSS to specifically tell a <table> to be whatever size <h2>s are.
However, you can tell tables and h2s to both be one specific size, e.g.:
h2,
table {
font-size: 2em;
}
You could also use Chrome’s Web Inspector (or similar tools in other browsers) to check what the default styles are, and apply the relevant ones to your table. These default styles might vary between browsers though.
As for why you can’t have a table inside an <h2> tag, I’m not sure off the top of my head if the HTML spec offers rationales for its nesting rules, but <h2>s are meant to mark up headings, i.e. relatively short pieces of text that describe a section of a document.
It’s difficult to imagine how a table would be an appropriate heading.

Related

Is there a mistake in the latest HTML specification?

I wanted to know if tables are allowed inside anchors like this:
<a>
<table>
<tr>
<td>Hello!</td>
</tr>
</table>
</a>
Because some people on the internet say it is allowed while others say it is not.
I looked under §4.5.1 The a element and it says the content model is "transparent". Then I looked into 3.2.5.3 Transparent content models to see what that means. And it says:
[...] the elements required in the part of the content model that is "transparent" are the same elements as required in the part of the content model of the parent [...]
They use the word required but I think it must be the word allowed.
Inside the 'a' element no elements are required at all. Instead the question is which elements are allowed. Or am I wrong?
Note that this question is not about whether tables are allowed inside anchors but instead if there is a mistake in section 3.2.5.3 of the HTML specification.
They use the word required but I think it must be the word allowed.
well, you just answered yourself with the next sentence:
Inside the 'a' element no elements are required at all.
and no
Instead the question is which elements are allowed.
that's not the question of the content model of the spec.
the spec says that an a-tag can't contain other interactive elements, which would then make those elements not-allowed.
also to the tables inside links question: as long as the table does not contain any interactive elements (buttons, inputs, other links etc.) you can put a table inside your a-tag (if that's a good idea is another question), the spec itself even gives that exact example:
The a element can be wrapped around entire paragraphs, lists, tables, and so forth, even entire sections, so long as there is no interactive content within (e.g., buttons or other links).
so no, in my opinion there is no "mistake" there.

Is it valid for inline level to include block level in HTML5? [duplicate]

I know it's wrong to put a block element inside an inline element, but what about the following?
Imagine this valid markup:
<div><p>This is a paragraph</p></div>
Now add this CSS:
div {
display:inline;
}
This creates a situation where an inline element contains a block element (The div becomes inline and the p is block by default)
Are the page elements still valid?
How and when do we judge if the HTML is valid - before or after the CSS rules are applied?
UPDATE: I've since learned that in HTML5 it is perfectly valid to put block level elements inside link tags eg:
<a href="#">
<h1>Heading</h1>
<p>Paragraph.</p>
</a>
This is actually really useful if you want a large block of HTML to be a link.
From the CSS 2.1 Spec:
When an inline box contains an in-flow block-level box, the inline box (and its inline ancestors within the same line box) are broken around the block-level box (and any block-level siblings that are consecutive or separated only by collapsible whitespace and/or out-of-flow elements), splitting the inline box into two boxes (even if either side is empty), one on each side of the block-level box(es). The line boxes before the break and after the break are enclosed in anonymous block boxes, and the block-level box becomes a sibling of those anonymous boxes. When such an inline box is affected by relative positioning, any resulting translation also affects the block-level box contained in the inline box.
This model would apply in the following example if the following rules:
p { display: inline }
span { display: block }
were used with this HTML document:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HEAD>
<TITLE>Anonymous text interrupted by a block</TITLE>
</HEAD>
<BODY>
<P>
This is anonymous text before the SPAN.
<SPAN>This is the content of SPAN.</SPAN>
This is anonymous text after the SPAN.
</P>
</BODY>
The P element contains a chunk (C1) of anonymous text followed by a block-level element followed by another chunk (C2) of anonymous text. The resulting boxes would be a block box representing the BODY, containing an anonymous block box around C1, the SPAN block box, and another anonymous block box around C2.
The properties of anonymous boxes are inherited from the enclosing non-anonymous box (e.g., in the example just below the subsection heading "Anonymous block boxes", the one for DIV). Non-inherited properties have their initial value. For example, the font of the anonymous box is inherited from the DIV, but the margins will be 0.
Properties set on elements that cause anonymous block boxes to be generated still apply to the boxes and content of that element. For example, if a border had been set on the P element in the above example, the border would be drawn around C1 (open at the end of the line) and C2 (open at the start of the line).
Some user agents have implemented borders on inlines containing blocks in other ways, e.g., by wrapping such nested blocks inside "anonymous line boxes" and thus drawing inline borders around such boxes. As CSS1 and CSS2 did not define this behavior, CSS1-only and CSS2-only user agents may implement this alternative model and still claim conformance to this part of CSS 2.1. This does not apply to UAs developed after this specification was released.
Make of that what you will. Clearly the behaviour is specified in CSS, although whether it covers all cases, or is implemented consistently across today's browsers is unclear.
Regardless if it's valid or not, the element structure is wrong. The reason that you don't put block elements inside inline elements is so that the browser can render the elements in an easily predictable way.
Even if it doesn't break any rules for either HTML or CSS, still it creates elements that can't be rendered as intended. The browser has to handle the elements just as if the HTML code was invalid.
The HTML and the CSS will both still be valid. Ideally, you wouldn't have to do something like this, but that particular bit of CSS is actually a handy (and syntactically valid but not semantically valid) way for getting Internet Explorer's double margin bug without resorting to conditional stylesheets or hacks that will invalidate your CSS. The (X)HTML has more semantic value than the CSS, so it's less important that the CSS is semantically valid. In my mind, it's acceptable because it solves an annoying browser issue without invalidating your code.
The HTML is validated independently of the CSS, so the page would still be valid. I'm fairly sure that the CSS spec says nothing about it either, but don't quote me on that one. However, I'd be very careful using a technique like this, as while it might render as intended in some browsers, you'd need to test 'em all—I don't see many guarantees being made.
Are the page elements still valid?
“Valid” in an HTML sense, yes; HTML knows nothing about CSS.
The rendering you get in the browser, however, is ‘undefined’ by the CSS specification, so it could look like anything at all. Whilst you could include such a rule in CSS hacks aimed at one particular browser (where you know how that browser renders this case), it shouldn't be served to browsers in general.
I don't know off the top of my head if this validates any rules but I would recommend using the W3C HTML Validator and the W3C CSS Validator to determine that. Hope this is helpful!
If there is a logic you follow and you end up implementing it like this, it's NOT WRONG. Working things are not "wrong" just because they're weird. Yes, it's quite unusual but it HELPS and it's not a mistake. It's intentional. HTML and CSS should serve you, not the other way around so don't ever listen to comments telling you not to do it just because it's ugly.
It's typical to call a solution "invalid" and suggest a long way around the block. Sometimes you can rethink what you did. But there can be many reasons for what you did and they don't consider them.
I do use blocks inside inlines regularly. It's valid and it's working - it's just not necessary in most cases. So what. Remember when XHTML told us to always put quotes around properties (and everyone yelled at you if you didn't!), now HTML5 allows to omit them if there's no space inside. What happened to that last slash after singular tags? "<br />" ? Come on. Standards change. But browsers keep supporting non-standard things as well. CENTER is deprecated; we're in 2013 and it still works. TABLE for vertical centering? Sometimes it's the only way. DIV inside A to make it hover as you planned? Just go ahead.
Focus on important things.
I think, (x)html is valid, css is valid. Is the result valid? Yes, if it is looking in the browser as You want.
No, It is not a wrong choice. We can use as per requirements.

In HTML, which element cannot include some other specific elements?

For example, in HTML 4.01,
1) inline elements in general cannot include other block elements (example: a <span> or <a> should not include any <div>.) But this rule is more forgiving, as most browsers won't alter the HTML structure like in rule 2 below. (And many browsers nowadays will handle the desired result of a <div> being inside of an <a> tag.)
2) <p> elements cannot include any <p> element. If any <p> appears before the closing of a previous <p> element, then the previous one will be immediately closed. This rule seems more strict as it alters the structure of the HTML document.
Are the rules above accurate, and are there other rules stating an element cannot include other elements? (as offsprings).
Are you talking about HTML5? Since that spec is supposed to supersede any other at this time, we'll stick with that.
I'm not going to go through each individual element, but if you need to look something up, here is the reference:
http://www.w3.org/TR/html5-author/
The section that talks about "Content Models,"
a description of the element's expected contents
is here: http://www.w3.org/TR/html5-author/content-models.html
You can see some examples in the specs for specific elements:
http://www.w3.org/TR/html5-author/the-html-element.html#the-html-element (the html element):
A head element followed by a body element.
Specific Examples
http://www.w3.org/TR/html5-author/the-a-element.html#the-a-element
http://www.w3.org/TR/html5-author/the-span-element.html#the-span-element
http://www.w3.org/TR/html5-author/the-br-element.html#the-br-element
a
We learn from the first link (on the a element) that its content model is Transparent, but only if there is no Interactive Content descendant.
By looking at the definitions of "Transparent," a we see that a inherits its Content Model from its parent. That means that your initial definition is incorrect and a can indeed contain a div, but only if its parent can. The docs above even include an example of nested "Transparent" content model elements.
Since a cannot contain any "Interactive Content" model elements, it cannot contain a button element at all. This makes sense because there would be a conflict as to which element actively responded to a click.
span
When we take a look at the second link, span, we see that its Content Model is "Phrasing Content," which is basically text and markup for paragraph-level text. The definition is not entirely specific, but it does include a guideline:
Most elements that are categorized as phrasing content can only contain elements that are themselves categorized as phrasing content, not any flow content.
Since div does not have a "Phrasing Content" model (it's "Flow Content,") span cannot contain it. This means that the span should follow the above rule and only contain any other "Phrasing Content" elements and/or embedded content or Text. If the above rule is broken, it will be listed specifically on the "Content Model" description of the element (remember the special rules for the a element about "Interactive Content.") span has none.
br
The third link, br, says that the Content Model is "Empty." Unfortunately, the W3C does not include a specific definition for that, but I think it's fairly obvious: it can contain no descendants at all. Not even text nodes. Any "Empty" Content Model element does not have a closing tag (you would write it as <br> not as <br></br>).
Your Questions
Are the rules above accurate?
First rule (inline vs. block)
What you've said is misleading. HTML has no concept of inline vs. block elements. These are CSS styles. Most browsers have a default setting for an element's display style as inline or block depending upon whether it is a "Phrasing" or "Flow" Content Model respectively (as a general rule; there is nothing hard and fast about that) or just traditionally.
If you want to say that "Phrasing Content" elements cannot contain "Flow Content" elements then you would be correct because that is in the spec specifically. This also works practically because span cannot contain div (as you indicate).
However, saying that a should not include any div is wrong. a can include div as long as its parents can. If a is contained in a span, it cannot contain div. However, if a is contained in body or another div, it can.
As for Browsers "being forgiving," this is all very convenient for many developers who cannot take the time to create valid HTML, but it can be a pain for those of us who do want to take the time. Browsers usually don't alter the "HTML structure" as you say -- what they alter is the DOM. Also node that the web vendor spec is a little different from the "Web author" spec I posted above, but we are the authors.
Second Rule (p containing p)
This is true because of an important point I left out: Context.
From the p element spec:
Contexts in which this element can be used:
Where flow content is expected.
Since p is "Phrasing Content," that means that another p cannot be put inside of a p because "Phrasing Content" is expected, not "Flow Content."
Any Other Rules?
The HTML5 spec has a huge number of elements, so I simply cannot go into all of those details here. I went into details about span and a contents vs. div as well as p because you brought those up specifically. Look at how long this answer is!
What you are going to need to do is take a look at whatever elements you have questions about in the spec itself. Take a look at the Context and Content Model sections to see whether or not your use of the element is valid.
In Summary
Refer to the spec when you have a question about how the element should work. To answer questions about how you should use the element (with respect to its container and contents), look at:
Contexts in which this element can be used:
Content model:
This tells you what can contain the element, what it can contain, and when.
If you have questions about whether your HTML is valid, you can always use the very nice W3C markup validation service:
http://validator.w3.org/
If you are using Chrome, you can take a look at the Chrome Inspector (F12) and compare the output DOM to the source HTML itself. You will notice for example that Chrome will automatically close nested p tags when it generates the DOM.
Regarding your second rule (in HTML 4.01) it's a little stronger: a P element cannot contain block-level elements (including P itself).
Based on your edited post --
<a> is now treated as a block-level element, as of html5 --
regardless of what standard you mark the page with, the browser will likely treat the element as if it's html5, so work from there, rather than backwards.
<a> can't contain <a> or any element which is meant to be interacted with (inputs/buttons).
<hX> cannot contain an <h_> tag of X or higher (in terms of hierarchy).
ie, <h3> cannot hold an <h1> or an <h2> or an <h3>
If you write it that way, the outline will close off the outline until it reaches the proper hierarchy-level.
<h1></h1>
<h2></h2>
<h3></h3>
<h2></h2> // starts a new branch of H2s, in terms of outline
<h1></h1>
<h2></h2>
<h3></h3>
<h1></h1> // closes the entire previous branch and all leaves, and starts a new outline
<ul> and <ol> can ONLY contain <li>s as immediate descendants.
<li>s can hold anything you want them to (except <li>s or other list-nodes), including other ordered/unordered/definition lists...
...but the <ul> and <ol> elements can only have <li> as their first-generation children.
Same deal with <dl>s with <dt> and <dd> nodes.
Most of the rest of it is either common-sense (don't put elements in <script> tags, <img> tags, <br> tags, <meta> tags, <legend> tags, et cetera)...
...or they're still having the kinks worked out (like what figure/figcaption can hold and the proper format for <picture>, et cetera).

Which is more correct: <h1><a>...</a></h1> OR <a><h1>...</h1></a>

Are both <h1><a ...> ... </a></h1> and <a ...><h1> ... </h1></a> valid HTML, or is only one correct? If they are both correct, do they differ in meaning?
Both versions are correct. The biggest difference between them is that in the case of <h1><a>..</a></h1> only the text in the title will be clickable.
If you put the <a> around the <h1> and the css display property is block (which it is by default) the entire block (the height of the <h1> and 100% of the width of the container the <h1> resides in) will be clickable.
Historically you could not put a block element inside of an inline element, but this is no longer the case with HTML5. I would think that the <h1><a>..</a></h1> approach is more conventional though.
In the case where you want to put an anchor on the header, a better approach than <a id="my-anchor"><h1>..</h1></a> would be to use either the id or the name attribute like this: <h1 id="my-anchor">..</h1> or <h1 name="my-anchor">..</h1>
In pre HTML 5 this one
<a><h1>..</h1></a>
will not validate. You can use it in HTML 5.
However, i would use this:
<h1><a>..</a></h1>
unless you need to add more than < h1 > inside the < a >
<a><h1></h1></a> is not W3C valid... Basically, you can't put block elements inside inline elements
<h1><a>..</a></h1> and <a><h1>..</h1></a> have always behaved almost the same, when style sheets do not affect the rendering. Almost, but not quite. If you navigate using the tab key or otherwise focus on a link, a “focus rectangle” appears around the link in most browsers. For <h1><a>..</a></h1>, this rectangle is around the link text only. For <a><h1>..</h1></a>, the rectangle extends across the available horizontal space, since the markup makes the a element a block element in rendering, occupying 100% width by default.
The following shows how a focused <a href=foo><h1>link</h1></a> is rendered by Chrome:
This implies that if you style elements e.g. by setting a background color for links, the effects differ in a similar manner.
Historically, <a><h1>..</h1></a> was declared invalid in HTML 2.0, and subsequent HTML specifications followed suit, but HTML5 changes this and declares it as valid. The formal definition has not affected browsers, only validators. However, it is remotely possible that some user agents (probably not normal browsers, but e.g. specialized HTML renderers, data extractors, converters, etc.) fail to handle <a><h1>..</h1></a> properly, since it has not been allowed in the specifications.
There is seldom a good reason to make a heading or text in a heading a link. (It’s mostly illogical and bad for usability.) But a similar question has often arised when making a heading (or text in a heading) a potential destination for a link, using e.g. <h2><a name=foo>...</a></h2> versus <a name=foo><h2>...</h2></a>. Similar considerations apply to this (both work, there may be a difference since the latter makes the a element a block, and before HTML5, only the former is formally allowed). But in addition, both ways are outdated, and using the id attribute directly on the heading element is now recommended: <h2 id=foo>...</h2>.
H1 elements are block level elements, and anchors are inline elements. You are allowed to have an inline element within a block level element but not the other way around. When you consider the box model and the HTML spec this makes sense.
So in conclusion the best way is:
<h1>Link</h1>
do you want to use a hyperlink <a href="…">/a:link, or do you want to add an anchor to your heading? if you want to add an anchor, you can simply assign an id <h1 id="heading">. you can then link it as page.htm#heading.
if you want to make the heading clickable (a link), use <h1><a></a></h1>/h1 > a – blocklevel elements first, and inline elements inside
Also, there is style hierarchy differences. If you have it as <h1>Heading here</h1>, The styles of the anchor will overrule the styles of the h1 element. Example:
a {color:red;font-size:30px;line-height:30px;}
WILL OVERRULE
h1 {color:blue;font-size:40px;line-height:40px;}
I think the <h1>text</h1> is the least problematic with weak or old browsers, but modern browsers and powerful search engines are supporting both it and <h1>text</h1>; So it's a good freedom and useful to use both to improve our web page.
«Hope that could be useful»
Both are correct. They depend on the sizing of the anchor tag which you want and how you want your website laid out.
You can do <h1>Home Page</h1>, in which case it would return: Home Page But with an Anchor.
Or you can do <h1>Home Page</h1> and it would return a H1 hyperlink instead of just heading an anchor to the H1, like so:
Home Page
However, mostly you cannot add links within H1 because it will just render it as an anchor onto the h1 rather than adding a hyperlink. However, I think I'm right in saying that you could see a difference in behaviour for this on different browsers.
But correct me if I am wrong. :)

Is it wrong to change a block element to inline with CSS if it contains another block element?

I know it's wrong to put a block element inside an inline element, but what about the following?
Imagine this valid markup:
<div><p>This is a paragraph</p></div>
Now add this CSS:
div {
display:inline;
}
This creates a situation where an inline element contains a block element (The div becomes inline and the p is block by default)
Are the page elements still valid?
How and when do we judge if the HTML is valid - before or after the CSS rules are applied?
UPDATE: I've since learned that in HTML5 it is perfectly valid to put block level elements inside link tags eg:
<a href="#">
<h1>Heading</h1>
<p>Paragraph.</p>
</a>
This is actually really useful if you want a large block of HTML to be a link.
From the CSS 2.1 Spec:
When an inline box contains an in-flow block-level box, the inline box (and its inline ancestors within the same line box) are broken around the block-level box (and any block-level siblings that are consecutive or separated only by collapsible whitespace and/or out-of-flow elements), splitting the inline box into two boxes (even if either side is empty), one on each side of the block-level box(es). The line boxes before the break and after the break are enclosed in anonymous block boxes, and the block-level box becomes a sibling of those anonymous boxes. When such an inline box is affected by relative positioning, any resulting translation also affects the block-level box contained in the inline box.
This model would apply in the following example if the following rules:
p { display: inline }
span { display: block }
were used with this HTML document:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HEAD>
<TITLE>Anonymous text interrupted by a block</TITLE>
</HEAD>
<BODY>
<P>
This is anonymous text before the SPAN.
<SPAN>This is the content of SPAN.</SPAN>
This is anonymous text after the SPAN.
</P>
</BODY>
The P element contains a chunk (C1) of anonymous text followed by a block-level element followed by another chunk (C2) of anonymous text. The resulting boxes would be a block box representing the BODY, containing an anonymous block box around C1, the SPAN block box, and another anonymous block box around C2.
The properties of anonymous boxes are inherited from the enclosing non-anonymous box (e.g., in the example just below the subsection heading "Anonymous block boxes", the one for DIV). Non-inherited properties have their initial value. For example, the font of the anonymous box is inherited from the DIV, but the margins will be 0.
Properties set on elements that cause anonymous block boxes to be generated still apply to the boxes and content of that element. For example, if a border had been set on the P element in the above example, the border would be drawn around C1 (open at the end of the line) and C2 (open at the start of the line).
Some user agents have implemented borders on inlines containing blocks in other ways, e.g., by wrapping such nested blocks inside "anonymous line boxes" and thus drawing inline borders around such boxes. As CSS1 and CSS2 did not define this behavior, CSS1-only and CSS2-only user agents may implement this alternative model and still claim conformance to this part of CSS 2.1. This does not apply to UAs developed after this specification was released.
Make of that what you will. Clearly the behaviour is specified in CSS, although whether it covers all cases, or is implemented consistently across today's browsers is unclear.
Regardless if it's valid or not, the element structure is wrong. The reason that you don't put block elements inside inline elements is so that the browser can render the elements in an easily predictable way.
Even if it doesn't break any rules for either HTML or CSS, still it creates elements that can't be rendered as intended. The browser has to handle the elements just as if the HTML code was invalid.
The HTML and the CSS will both still be valid. Ideally, you wouldn't have to do something like this, but that particular bit of CSS is actually a handy (and syntactically valid but not semantically valid) way for getting Internet Explorer's double margin bug without resorting to conditional stylesheets or hacks that will invalidate your CSS. The (X)HTML has more semantic value than the CSS, so it's less important that the CSS is semantically valid. In my mind, it's acceptable because it solves an annoying browser issue without invalidating your code.
The HTML is validated independently of the CSS, so the page would still be valid. I'm fairly sure that the CSS spec says nothing about it either, but don't quote me on that one. However, I'd be very careful using a technique like this, as while it might render as intended in some browsers, you'd need to test 'em all—I don't see many guarantees being made.
Are the page elements still valid?
“Valid” in an HTML sense, yes; HTML knows nothing about CSS.
The rendering you get in the browser, however, is ‘undefined’ by the CSS specification, so it could look like anything at all. Whilst you could include such a rule in CSS hacks aimed at one particular browser (where you know how that browser renders this case), it shouldn't be served to browsers in general.
I don't know off the top of my head if this validates any rules but I would recommend using the W3C HTML Validator and the W3C CSS Validator to determine that. Hope this is helpful!
If there is a logic you follow and you end up implementing it like this, it's NOT WRONG. Working things are not "wrong" just because they're weird. Yes, it's quite unusual but it HELPS and it's not a mistake. It's intentional. HTML and CSS should serve you, not the other way around so don't ever listen to comments telling you not to do it just because it's ugly.
It's typical to call a solution "invalid" and suggest a long way around the block. Sometimes you can rethink what you did. But there can be many reasons for what you did and they don't consider them.
I do use blocks inside inlines regularly. It's valid and it's working - it's just not necessary in most cases. So what. Remember when XHTML told us to always put quotes around properties (and everyone yelled at you if you didn't!), now HTML5 allows to omit them if there's no space inside. What happened to that last slash after singular tags? "<br />" ? Come on. Standards change. But browsers keep supporting non-standard things as well. CENTER is deprecated; we're in 2013 and it still works. TABLE for vertical centering? Sometimes it's the only way. DIV inside A to make it hover as you planned? Just go ahead.
Focus on important things.
I think, (x)html is valid, css is valid. Is the result valid? Yes, if it is looking in the browser as You want.
No, It is not a wrong choice. We can use as per requirements.