Forum Bugs

Table of contents not working with flex

I've attached an image of the problem (without_display_flex.PNG): long text goes under the number prefix. To tackle this in HTML, I decided to use display: flex (or later table-cell).

However, if I use flex or table-cell, the table of contents is not rendered correctly. No dotting appears (with_display_flex.PNG). The "content: leader(".")" css stops working.

Also attached (with_display_flex_in_HTML.PNG) that shows what I am trying to accomplish.

Is there another way to do this? Or is it a bug?

<div class="toc-section">
  <a href="#toc__sec_9.6" style="display: flex;">
    <span class="toc-left">9.6</span>
    <span class="toc-right">Calculation of structure-borne sound level Lsn 
    and normalisation with respect to the acoustic properties of the wall</span>

a[href]::after { content: leader(".") target-counter(attr(href), page); }
.toc-left { width: 30pt; display: inline-flex; }
.toc-right { padding-left: 5pt; }

It would help my cause, if Prince allowed "list-style-type: 'string'" though ;)
  1. with_display_flex.PNG11.3 kB
  2. with_display_flex_in_HTML.PNG44.1 kB
  3. without_display_flex.PNG22.5 kB

Edited by rainhallikas

I think there are a few possible ways of doing this, for example with regular floats, but we will investigate the interaction between leaders and flexbox layout.

What exactly do you mean by "list-style-type: 'string'"? You can use the ::marker pseudo-element to specify the content of a list-item marker.
Okay. Float works. And list-style-type: '-' works in HTML and it's just more straight-forward than marker.
Thank you for the tips. I will try to use float and marker instead then.
I think the flex was having problems because the ::after should have been after .toc-right element. Not the whole link.

But the marker is not solving my problem too well because every list element has a custom value. ::marker is CSS element and can take custom values but I need to set a different custom marker for every li. I am not sure if content: string-set would solve the problem but overall it would be an overly complicated work-around.

I would look forward to "list-style-type: custom value" addition to Prince if you're at all considering it at some point.
Hi, I wrote a test case attempt although I'm not 100% certain the assertation is valid.
Flex-items (the SPAN elements and the ::after pseudo-elements) are likely expected to shrink to fit their contents. If you give the SPANs and the pseudos borders it helps clarifying what happens.

You could try making the ::after pseudo grow compared to the other flex items with

flex-grow: 2;

This gets me pretty close to the rendering you want. Only problem is the SPAN for the long text leaving space for only one dot - you may be able to live with that?

Announcement: repos for tests/utils

  1. 4348.htm1.3 kB
  2. Screenshot from 2020-02-15 12-14-29.png22.4 kB
    with flex-grow
(You may have tried the flex-grow solution already of course. If @mikeday thinks leader(".") content should be taken into account when shrinking those pseudo-element flex boxes the description of expected outcome in the test above is valid and the developers should investigate..)

Announcement: repos for tests/utils


I believe the correct behaviour when calculating the "flex base size" would be for the leader to fill up all available space as if the item was the only item in the container (although I admit the specs aren't entirely clear to me on this point). As such, the leader is likely to steal space from the other items even if they also fill up that space.

You can prevent this by setting "flex-basis: 0" on the pseudo-element, as well as setting flex-grow (note that the initial value of flex-grow is 0, so it is sufficient to set it to any positive value).

The leader function takes an optional argument for the minimum width, so you can force it to use multiple dots if needed.


P.S. The leader should indeed be taken into account when sizing. We've made some recent improvements in this area, but they don't apply to flexbox just yet. We're working on it :-)