LaTeXML icon indicating copy to clipboard operation
LaTeXML copied to clipboard

Displaying listings in small viewports

Open xworld21 opened this issue 3 years ago • 6 comments

Migures containing multiple images and a caption create a nested flex wrappers. I believe it is intentional, but it breaks horizontal scrolling for listings:

\usepackage{listings}
\usepackage{graphicx}
\begin{figure}
\begin{lstlisting}
Very long text that overflows the container as long as I write enough
\end{lstlisting}
\includegraphics{}
\caption{A listing}
\end{figure}

When on mobile, the listing gets clipped on the left, and the entire figure scrolls horizontally but only to reveal the right side of the listing. Verified both in Chromium and Firefox.

I can't figure out how to unbreak this. CSS is hard!

Edit: I see this on the current master.

xworld21 avatar May 19 '22 20:05 xworld21

Since I've caused this, let me say 1) sorry! and 2) creating reasonable markup for floats is hard.

There should be a workable setup that allows us to keep the flex benefits without all the weird unintentional damage. #1797 also contains broken bits related to the new flex model, so it may be a good idea for us to consider the two issues together.

dginev avatar May 19 '22 21:05 dginev

I have taken some time to examine this issue.

Fundamentally, this is a problem about reflowing listings (in subfigures, but also in general) and I think it will be encountered whether the listing was contained within a flexbox figure, an HTML table or CSS grid.

The narrow mobile display renders correctly when using non-listing content. For example, a figure with two vertical image subfigures. But the rendering encounters the exact issues described by Vincenzo when we have a listing that horizontally overflows the viewport width. That is pretty easy to encounter on a vertical phone display (~360 pixels or so on the smallest presets in the browser inspector).

A very rough CSS fix here would be on the lines of allowing the browser to reflow all listing lines bravely on very narrow horizontal displays. For example adding the media rule:

@media only screen and (max-width: 32rem) {
  .ltx_listing .ltx_listingline {
      white-space: break-spaces !important;
      word-break: break-word !important;
  }
}

with 1rem usually being 16px (so displays 512px or less). Choosing the exact cutoff value is also hard, usually requires testing a variety of devices, on a variety of real-world listings...

Since I don't think there is a quick solution here - and there are available CSS workarounds for the short-term and mid-term, I will bump the milestone up here, and we can discuss some more.

dginev avatar Dec 12 '22 22:12 dginev

I don't know if I'm overinterpretting what I'm reading, but listings should not reflow; their linebreaks are inherant in their markup; at most they might provide for horizontal scrolling.

So, if that's a clue: whatever css magic is done to the figures/subfigures or other containers that allow the blocks of stuff to be rearranged should never reach the listing itself.

brucemiller avatar Dec 12 '22 23:12 brucemiller

So, if that's a clue: whatever css magic is done to the figures/subfigures or other containers that allow the blocks of stuff to be rearranged should never reach the listing itself.

That's the irony of it - it currently doesn't, exactly as you are hoping, which is incompatible with the flex setup. Vincenzo's example fits just about exactly a full PDF line of an {article} document (which has wide margins):

Very long text that overflows the container as long as I write enough.

In our default conversion to HTML, that leads to a rendered div element holding the (unbroken, single line) listing that is 442px in width, which would overflow the e.g. 360px vertical mobile display in the inspector.

But the flex figures are set up to be centered (align-items: center) with an expectation that the content in them can be auto-resized to "fit" in the available max-width. Which - for some currently unknown browser reason - leads to a horizontal scroll can only go to the right, but not back to the piece that remained clipped to the left.

I am a big fan of responsive reflow, so the first direction of improvement I explored was to see what it would take to enable reflow on small devices.

But, naturally, the other direction is to avoid the flexbox centering on small devices, which will start the listing in the visible page, and the rest can be access with a horizontal scroll to the right. That's a bit more conservative, but probably more predictable. I got a working CSS rule prototype for it as well, say:

@media only screen and (max-width: 32rem) {
  .ltx_table, .ltx_figure {
    align-items: baseline !important;
  }
}

dginev avatar Dec 12 '22 23:12 dginev

But, naturally, the other direction is to avoid the flexbox centering on small devices, which will start the listing in the visible page, and the rest can be access with a horizontal scroll to the right. That's a bit more conservative, but probably more predictable. I got a working CSS rule prototype for it as well, say:

Having tables and listings align to the left when the screen is too small is a very good idea. A breakpoint-free approach might be an extra div wrapper stretched to full size instead of aligned, with margin auto and overflow on the content. Then it would be centred when there is enough space, but stick to the left otherwise. Maybe.

xworld21 avatar Dec 14 '22 21:12 xworld21

Maybe the expectation "that the content in them can be auto-resized", rather than display size, is the root of the problem; and maybe this connects to #2154, #2036.

brucemiller avatar Aug 24 '23 10:08 brucemiller