2

body {font-size: 40px;}
p {font-size: 12px;}
div, span {font-size: 20px;}
<h6>Why font size of before is inherited from p, while that of after is inherited from div</h6>
<p>before<div>content</div>after</p>
<hr>
<h6>This result is acceptable</h6>
<p>before<span>content</span>after</p>
See spec on Anonymous block boxes follow this link: http://www.w3.org/TR/CSS2/visuren.html#anonymous-block-level.
jasonxia23
  • 147
  • 1
  • 12
  • Seems like the first example with `

    before

    content
    after` assumes that `before` still belongs to `p` and therefore renders it with a `font-size: 12px`, whereas according to specification, if there's a block element in the an inline element, the content around (in this case it should be both before and after, but seems like it's only applying to after) is an anonymous element and therefore styling from `div` is applied. The second example is just an inline element within an inline-element so no anonymous blocks are applied. Does that make sense?
    – emil.c Apr 03 '16 at 07:29
  • @emil.c I have set the `display` of `span` to `block`, the result didn't change. The answer of Denys Seguret seems to be right. – jasonxia23 Apr 03 '16 at 07:36
  • According to the specification, if you set `display: block` to `span`, there should be 2 anonymous blocks created: 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. – emil.c Apr 03 '16 at 07:39
  • So technicallly yes, Denys answer is completely correct, however there are more things to consider than just saying that the second part should work as expected every time (according to the specification. – emil.c Apr 03 '16 at 07:40
  • @emil.c - note that for "a block box representing the BODY, containing an anonymous block box around C1, the SPAN block box, and another anonymous block box around C2" to be right, the p element must also be set to display:inline - as per the spec example - otherwise there would be a block box representing the p element as well. – Alohci Apr 03 '16 at 08:22
  • @emil.c: How is that reference relevant? There's neither a block element within an inline element, nor an inline element within another inline element, in either of the examples. Of course the string "before" would belong to

    - what did you think

    before meant in HTML? An empty p followed by an orphaned "before" text node? (The "after

    " is [another story](http://stackoverflow.com/questions/11570902/why-does-a-stray-p-end-tag-generate-an-empty-paragraph).)
    – BoltClock Apr 03 '16 at 09:55
  • @Alohci I was confused because I thought that according to specs, C1 is an anonymous block that basically replaces the p element, so we have an anonymous block inheriting stuff from the parent element, but now I see I was mistaken. – emil.c Apr 03 '16 at 10:10

1 Answers1

1

The only valid content in a P element is phrasing content and a DIV isn't phrasing content. Your HTML is invalid and makes no sense for the browser, there's no reason the resulting content matches your expectations.

A span is a phrasing content, that's why the second part works according to your expectations.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • You are absolutely correct that the HTML is invalid when you place `div` inside `p`, however according to the specification it creates two anonymous blocks around that div if you do that. Which means both anonymous blocks should not inherit style from surrounding `p`. – emil.c Apr 03 '16 at 07:35
  • Anonymous blocks are only valid in a valid HTML part. Like having a P *inside* a div. Here, you can't expect anything (and there's no reason to keep a buggy html so it shouldn't matter). – Denys Séguret Apr 03 '16 at 07:41
  • 1
    That's right, but if you set `display: block` to `span` element in the second example, you should not expect the `span` to inherit style from `p`, isn't that right? (that's what they say in the specification) – emil.c Apr 03 '16 at 07:42
  • @emil.c - no that's not what the spec says. It says that inherited properties are inheriited. Non-inherited properties have their initial value. font-size is an inherited property. But of course, the span with display:block itself does not form a anonymous block box, and may therefore have styling applied to it directly, which would stop any inheritance of the set properties from applying. – Alohci Apr 03 '16 at 08:15
  • @emil.c: The spec has never said that display: block prevents inheritance altogether. In fact, CSS did not provide the ability to prevent an element from inheriting any properties from its parent element until recently with the all property. – BoltClock Apr 03 '16 at 09:57
  • Placing a div inside a p does not result in invalid HTML. It simply means something different altogether. In

    before

    content
    after, everything up to and including the "after" is valid HTML - the only thing that's invalid is the now-orphaned end tag.
    – BoltClock Apr 03 '16 at 10:02
  • @BoltClock The only *"Permitted content"* of a P element **is** phrasing content, as per [the norm](https://www.w3.org/TR/html5/grouping-content.html#the-p-element) – Denys Séguret Apr 03 '16 at 10:04
  • @Denys Séguret: Yes, so

    before

    content
    after (minus the end tag) produces a DOM that consists of a p with the text "before", a sibling div with the text "content", and a sibling text node "after". Notice the div is a sibling, not a child, of the p. This is in line with what you quote, albeit simply, as I mentioned, not in line with what the author expects. The presence of the
    start tag ends the

    implicitly since the end tag can be left out. It is equivalent to "

    before

    content
    after", and valid HTML. The is the only portion that's invalid.
    – BoltClock Apr 03 '16 at 10:06
  • @BoltClock - If you are measuring validity by the DOM, the `` won't be invalid either. Because the parser will form a full, empty p element from it. While a p element *should* have palpable content, it's not invalid for it to be empty. – Alohci Apr 04 '16 at 07:25
  • @Alohci: My point was that, contrary to what is stated in the answer,

    before

    content
    after *is* valid markup and *does* make sense for the browser, and that just because the result doesn't match the author's intentions doesn't make the markup invalid, i.e., it's not "placing a div inside a p", it's placing a div *after* the p. The only thing that makes the markup invalid is the stray end tag.
    – BoltClock Apr 04 '16 at 08:32
  • @BoltClock - What makes sense for the browser is a separate matter from what is valid. But I take your point. – Alohci Apr 04 '16 at 08:44