3
votes

I'm building a custom element to mark up examples (play with it at http://jsbin.com/kiboxuca/1/edit):

<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.2.0/platform.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.2.0/polymer.js"></script>
<polymer-element name="my-example" noscript>
  <template>
    <style>
      :host { display: inline }
    </style>
    [ <em>Example:</em>
    <content></content>
    — <em>end example</em> ]
  </template>
</polymer-element>
<div>
  Some text <my-example>Introduction
  <pre>Some code here</pre>
  More example</my-example>
</div>

This produces the appearance I want:

Some text [ Example: Introduction

Some code here

More example — end example ]

However, because it makes the <my-example> element display:inline I'm worried that the block-level <pre> element is going to cause problems.

Styling <my-example> as display:block forces it to start on a new line, which is inconsistent with the PDF I need to imitate.

What sorts of problems should I expect from violating the CSS box model like this, and how can I mitigate them?

1
One known problem is that <p> elements auto-close before a <pre>, but that's a problem with the HTML parser, rather than the CSS box model, and I can fix it by replacing the <pre> with a new custom element that wraps it.Jeffrey Yasskin
By default elements are display: inline, so you can ditch the <style>. The <p> closing is annoying. I had to change things over to <div> to get a few of the examples form the PDF to work: jsbin.com/xapevika/2/editebidel
Another thing to try is display: inline-block if you want something to render inline but be able to contain block-level elements.Scott Miles
@ScottMiles, unfortunately, inline-block makes the example render as a single box inside the line started by "Some text": jsbin.com/kiboxuca/4/editJeffrey Yasskin

1 Answers

1
votes

This is specified in section 9.2.1.1 of the CSS2.1 spec, which describes anonymous block boxes.

The description in the spec is pretty verbose, so I will not quote it here, but basically what happens is that the inline portions of your <div> element, including <my-element>, are relocated into anonymous block boxes surrounding the <pre> block box. The "Some text " bit that precedes the <my-example> element is contained in its own anonymous inline box, while the <my-example> element generates its own inline box as usual, except that it is split into the anonymous block boxes that are generated around the <pre> box.

While it might not make much sense for an inline box to contain a block-level box — after all, the spec does say to break it up into a bunch of anonymous boxes for the purposes of rendering — the behavior in such a case is very well-defined and therefore (or at least, it should be) reliable across browsers. You should not run into any problems aside from obscure browser bugs, of which there are none I am currently aware of, although Chrome has been known to act downright weird with a elements containing block boxes.

Here's an illustration:

<polymer-element name="my-example" noscript>
  <!-- ... -->
</polymer-element>
<div>

  <anonymous-block>
    <anonymous-inline>Some text </anonymous-inline>
    <my-example>
      [ <em>Example:</em>
      Introduction
    </my-example>
  </anonymous-block>

  <pre>Some code here</pre>

  <anonymous-block>
    <my-example>
      More example
      — <em>end example</em> ]
    </my-example>
  </anonymous-block>

</div>

Note of course that the <my-example> element isn't actually split like that — the start and end tags in this illustration delimit the boxes that are generated, rather than the elements themselves. In terms of the shadow DOM, the <pre> element is still considered a child of the <my-example> element, and the entire <my-example> element is still just one element.