Page MenuHomePhabricator

Vector: Handle <pre> overflow with a scrollbar or wrapping
Closed, ResolvedPublic

Description

Author: ui2t5v002

Description:
The fact that a pre section overflows its little blue dotted box is a bug. It
happens in Firefox, but not in IE.

Wanting it to have auto overflow is a feature request but also the only solution
I know of. Adding

pre { overflow: auto; }

to the css file fixes it under firefox, but not IE. adding width information to
the pre section in conjuction with the above does mostly fix it in IE, though it
adds a vertical scrollbar too, for some reason.

This page:

http://www.magpiebrain.com/archives/2004/04/19/ie_and_overflow_auto

explains how to make it even better in IE.


See Also:

Details

Reference
bz260

Event Timeline

bzimport raised the priority of this task from to Low.Nov 21 2014, 6:46 PM
bzimport set Reference to bz260.

ui2t5v002 wrote:

crude examples of firefox and IE

Attached:

overflow.png (762×849 px, 25 KB)

alpeterson wrote:

I think this is a pretty common problem for people.

I am looking for:

width="80";
to be added to the stylesheet defaults for pre...

it can be over ridden by those who know what they are doing, but it will keep
problems from happening, say as in this example page:

http://meta.wikimedia.org/wiki/User:AaronPeterson/pre_play

and in this page where it was causing problems

http://meta.wikimedia.org/wiki/Apache_config

The scrollbars are buggy as well, because they often cover the last row of the
pre. Additional, for long pre areas you'll have to scroll down the page to get
to the pre scrollbar, scroll up again to see the text, scroll down to scroll
horizontally again... A global page scrollbar that's always at the bottom is
much better in that case.

The text flowing out of the box might look a bit weird, but imo it's still the
best you can get. A fixed width on the pre is certainly no option, imagine that
on a wide screen or on a mobile..

  • Bug 414 has been marked as a duplicate of this bug. ***

ui2t5v002 wrote:

(In reply to comment #2)

I am looking for:

width="80";
to be added to the stylesheet defaults for pre...

I think this would be a problem if 80 is a definite number of characters width.
something like width="80%" would be better, though if that is 80% of the total
browser width, and the sidebar is a fixed width, no percentage would work for
all screen sizes, unless it could be set as the percentage of the text "frame".
In other words, the sidebar to the left is fixed width A, and the content area
to the right is changeable width b based on browser size, then you could say the
pre area is 90% of the width b of the content area, and doesn't care about the
existence of area A. I'm not sure how the code for this would work.

alpeterson wrote:

There is no "80%" option...

the width of the pre section is in characters... only :(

ui2t5v002 wrote:

(In reply to comment #6)

There is no "80%" option...

the width of the pre section is in characters... only :(

is there a way to have the browser supply the required number based on screen
size? :-\ i guess it would need to know font size as well...

still, i don't know why this can't just be added and make it nicer for firefox
users and do nothing in IE. it's not like it would break IE...

gangleri wrote:

referencing original url with 'oldid='

  • Bug 22060 has been marked as a duplicate of this bug. ***
  • Bug 414 has been marked as a duplicate of this bug. ***

Wow, I ran into this today and can't believe it has been open since 2004.

Running through some stuff:

(Cite bug 414 comment #21)

One difficulty with forcing line wrapping in the display when dealing with code
or configuration examples is that frequently line breaks are semantically
important.

[..]

A wrap to 80 columns would display as:

$wgScriptPath = '/w'; # Path to the actual files. This should already
be there
$wgArticlePath = '/wiki/$1'; # Virtual path. This directory MUST be different
from the one used in $wgScriptPath
$wgUsePathInfo = true;

which, if typed as it looks into an Apache config file would result in a big
fat syntax error.

Indeed, which is why wrapping it for real (no matter after how many characters) is an issue, and we shouldn't implement something like that. However any of these are not problematic:

  • Handeling overflow automatically with a scrollbar (only show a scrollbar if there is overflow). This can be done by setting overflow: auto;, which browsers evaluate on the fly and stays up to date when the page changes as well as when the window is resized.
  • Applying word-wrap. Afaik these do not affect the content being put in the clipboard. e.g. setting word-wrap: word-break. and copying a very long line that is wrapped, keeps it in tact (just tried in Chrome and Firefox).

(Cite bug 414 comment #12)

Mozilla Firefox doesn't have scroll bars for the <pre> tags... if you can

Afaik no browser has scrollbars on any element (except for <html>/<body>). <pre> tags (or any element for that matter) do not and should not have scrollbars unless a site's stylesheet explicitly sets it.

I've changed the summary to be no longer Firefox oriented, this bug happens in all browsers (which is the correct default behavior).

(Cite bug 414 comment #16)

Firefox supports scroll bars for pre text, as mentioned in bug 260. I thought
internet explorer was the problem. I added pre { overflow: auto; } to my user
stylesheet and it works delightfully in Firefox, automatically putting a
horizontal scrollbar for pre sections when they overflow the screen, and not
putting one when they don't. I suggested adding this to the site css but then
it was pointed out that it doesn't work in IE.

overflow: auto; is indeed the best solution.

Note (from bug 22060 comment 4 and on):

  • IE6 doesn't support it (falls back so default behavior ("overflow: visible") which is fine)
  • IE7 and IE8 show the scrollbar inside the element (potentially overlapping the last 1 or 2 lines)

That can be fixed by increasing the padding a bit in IE (as pointed out later in that discussion). However it is slightly more complicated then that. The bug is quite odd in IE7. The scrollbar overlaps the content, but it is still "smart" enough to then provide a vertical scrollbar to get to that. So adding bottom-padding will make the last line visible, but it will still force the vertical scrollbar, even if its just to allow the user scroll to the reserved padding we created. So we'll have to set overflow-y: hidden. Which is fine as long as there is no fixed height on the <pre>.

Tested on a Mac and on BrowserStack in Windows:

  • Chrome 19 (Mac): OK
  • Chrome 18: OK
  • Opera 11.1: OK
  • Firefox 3.0: OK
  • Firefox 3.6: OK
  • Firefox 12: OK
  • Safari 4: OK
  • Safari 5.1: OK
  • IE6: (defaults to old behavior, property "overflow" ignored (so no scrollbar). does have padding since *hack applies to IE<7.[1])
  • IE7: OK (scrollbar issue, fixed with *overflow-y: hidden; and *padding-bottom: 21px)
  • IE8: OK
  • IE9: OK
  • IE10.0: OK
  • OK: No scroll bar for small pres, show does scroll bar for big pres.
  • Source code: http://jsbin.com/apezup

    .pre-fixed { overflow: auto; /* IE<7: */ *padding-bottom: 21px; *overflow-y: hidden; }

[1] I confirmed *hack applying to IE6+IE7 myself. More ie hacks are documented here: http://www.webdevout.net/css-hacks

Created attachment 10781
Screenshot of a <pre> overflow running over other floated items due to lack of overflow control

The text exceeding the overflow is actually causing many things:

  • Causes long text to go off-page, causing a scrollbar on the entire window for the entire duration of the page view. (e.g. if somewhere half way a page there is a <pre> with overflow, when reading the intro you get this scrollbar for no apparent reason)
  • When scrolling to that off-page content, you no longer see the actual article, navigation, and most importantly: context (e.g. instructions, pointers). Causing usability issues (i.e. having to scroll back and forth to understand something is very unfriendly.
  • The lack of overflow control is also causing text to run *over* over floated elements. Such as image thumbnails, infoboxes, tables, citations and what not. That made the text completely unreadable, and looks like a broken page (see attached screenshot for a simple example, there are worse examples). This is especially hard to avoid because the layout is fluid, so the position where the text will overlap the image is completely variable and dependent on the font-size and window size / orientation.
  • When having reached the position in the page where the overflow-<pre> is, it is not always obvious to the user how to get to the extra content because there is no scrollbar to see. (there is one on the entire page, but that's afaik very rarely used on the web, and when it is, it is usually a bug).

All of that is fixed by simply controlling the overflow.

Tim Starling brought up an interesting result of this. If you're in an environment (device, os and or browser related) where you can't scroll without manually dragging the scrollbar (e.g. no laptop touchpad, desktop mouse scrollwheel or mobile touch gesture) then one has to go to the scrollbar in order to scroll. For most short <pre> sections this isn't an issue, but if the code is taller than the view port then one has to navigate down to find the vertical scroll bar which is quite inconvenient.

I don't think that problem weighs against the aforementioned usability, accessibility and layout issues. But it is something we can improve. I'd recommend we open another bug for that and (hopefully) fix it in less than 8 years (which is how long this bug survived - having 4 (in) direct duplicates and many on-wiki complaints).

Attached:

Screen_Shot_-_MediaWiki.png (317×974 px, 138 KB)

(In reply to comment #11)

Tested on a Mac and on BrowserStack in Windows:
[..]

.pre-fixed {
  overflow: auto;
  /* IE<7: */
  *padding-bottom: 21px;
  *overflow-y: hidden;
}

Landed in I2e0494603af9e3a8351a8c61e9b814f0093e422b.

Note: Fixed padding-bottom size is only to usual user schemes, but people can have bigger scrollbars using different user scheme.

steefy389 wrote:

Reopening.

This change was discussed on dewiki two years ago and got already implemented in Common.css for a short time. But it got reverted because of two reasons:

  1. padding issue in IE
  2. source codes

The first problem can be fixed with IE-rules, but the second one is something that shouldn't get ignored silently.
Long pre's get a scrollbar at the end of the content. This is especially a problem with long codes like in mediawiki-namespace or userscripts. Of course there are possibilities to scroll, for example via mousewheel. But additional to the above mentioned problems with mobile devices and touchpads I think that only a few users know about the possibility of clicking with the mouse wheel and the rest starts scrolling to the end of each longer pre which is much better in terms of usability than the current behaviour.

Contrary to Krinkle, I think this problems should be fixed before implementing this change.

A much better alternative would be white-space: pre-wrap;. It's still bad for sourcecodes, but at least it is a decent alternative for the usual user and for mobile devices.

(In reply to comment #15)

Long pre's get a scrollbar at the end of the content. This is especially a
problem with long codes like in mediawiki-namespace or userscripts. Of course
there are possibilities to scroll, for example via mousewheel. But additional
to the above mentioned problems with mobile devices and touchpads I think that
only a few users know about the possibility of clicking with the mouse wheel
and the rest starts scrolling to the end of each longer pre which is much
better in terms of usability than the current behaviour.

I had opened bug 37864 for this issue. Please look at the screenshot there and especially test usability on [[commons:MediaWiki:Gadget-HotCat.js]] before re-enabling anything with overflow: auto;

Although Gerrit change #12720| Change-Id: Ica40812ae221cdc7926dcbe7f82e1cb1591ea1e2 fixes a lot of issues, it introduces one (in my opinion, minor) potential UI regression. I'll try to summarize the exact case here:

When:

  • The user is someone who doesn't (know how to) use scroll wheels (but rely getting to the inline-scrollbar and drag that)
  • On a page that has a <pre> that is not just for pre-formatting a few lines but is actually very tall (taller than the view port / browser window)

Then (combining these two factors):

  • They'd have to scroll down the page to get to the inline scrollbar whereas they previously could re-use the main window scrollbar (because the <pre> used to just burst out of the page layout and widen the page itself).

However, one can argue whether the previous state was better, I think it was not obvious that the main window scrollbar can be used for this, so the fact that it can be no longer used for that is only a regression if that was actually obvious to the user. Either way, it could be something to take into consideration right now if we want to block on it.

One possible solution could be to implement a maximum height on the <pre> and as such force a vertical scrollbar as well for taller <pre>-areas. That way the entire <pre> will be both vertically and horizontally without "leakage" outside the view port. But requiring the use to scroll twice is also annoying.

Another solution that might work is to combine the patch set (Gerrit change #12720), with the above max-height idea + a :hover state that undoes. So you'd hover over the <pre> and then it expands in both directions (if there is something to expand, that is). That would be nice for most users (scrolling would be done through the main-window-scrollbar), but for the category described above it may still be an issue since moving the mouse away to the window-scrollbar means the cursor no longer hovers the <pre> and as such collapses the element again..

I think using word-wrap is superior solution because it makes the view more similar to the editing mode. If a long page of code with very long lines is written in an editor with word-wrap, it seems that not using word-wrap to view it would be an unwelcome disconnect.

See details about using break-word together with pre-wrap to target all browsers.
https://developer.mozilla.org/en/CSS/word-wrap

(In reply to comment #18)

I think using word-wrap is superior [than using scrollbar overflow]

I agree, and that would fix both this bug 260 as well as the usability concern from the solution I proposed in gerrit.

Note that on Wikimedia Commons they are already using word-break: break-word;
https://commons.wikimedia.org/wiki/MediaWiki:Common.js

When talking about this with Trevor we both had the same idea, but came up with different implementations that seemed the same at first.

Trevor suggested "white-space: pre-wrap;" and I suggested "word-wrap: break-word;". Both appear to do the same thing when used in a <pre> (when not used on a <pre>, but on a <p> the difference is much more obvious).

When used on a <pre> there is a sudle difference.

  • "white-space: pre-wrap;"

This causes the browser to naturally wrap by displaying words on the next line if they don't fit on the same line within the box (does not cut off words). At first sight this appears to be a nice solution, however long urls or JSON strings will often still break out of the box and cause the page layout to look broken.

  • "word-wrap: break-word:"

This forces the browser to wrap anywhere (even within when the spot is not a word boundry) when the line becomes too long.

The latter doesn't have the problem with long urls and JSON strings, but... it always breaks the word, even a short word such as "the" will be wrapped on 2 lines if it happens to be at the cut-off point of the <pre> box dimensions.

The best solution appears to combine the two. That way the browser will first naturally wrap the lines in a natural way (if a word doesn't fit it puts the entire word on the next line), and then break-word will only step in if necessary. Browser support for both of these are very good. I'll do some testing and come up with a patch on monday.

krinkle, what is the status here?

Test report:

  • Chrome 20: OK
  • Firefox 3.0: OK
  • Firefox 3.6: OK
  • Firefox 13: OK
  • Firefox 14b: OK
  • Safari 5.1: OK
  • IE6: OK
  • IE7: OK
  • IE8: OK
  • IE9: OK
  • IE10: OK
  • Opera 11.6: OK
  • Opera 12: OK

Test case:
http://commons.wikimedia.org/w/index.php?title=Commons:Sandbox&oldid=74719563

Change: I7eec3ffeaa | https://gerrit.wikimedia.org/r/16677

*** Bug 32045 has been marked as a duplicate of this bug. ***

I'm afraid you have broken the rendering of <source> tags now :( See e.g. https://en.wikibooks.org/wiki/C_Programming/Variables - huge margins are added to the top and bottom of codes.

The trouble is caused by "white-space: pre-wrap;" applied to .mw-code in https://bits.wikimedia.org/en.wikibooks.org/load.php?debug=true&lang=pl&modules=skins.vector&only=styles&skin=vector&* This enforces the rendering of a couple of newlines appearing in HTML source.

The minimal fix is to add ".mw-code { white-space: inherit }". But I don't get this code at all, why apply the rules to both pre and .mw-code when the second always has the first inside?

I've seen that, but that is a separate bug entirely. Please create a new bug for that.

Setting ".mw-code { white-space: inherit }" would be pointless as there is already a white-space rule - which has been set for a reason: to preserve whitespace. If the white-space property should be changed (which I don't think it should) then it should be unset, to set twice.

I've filed bug 38800 for the bug that causes that. Again, bug 260 is fixed and looks fine. Wikis that have Tidy enabled (by default Tidy is not enabled, Wikipedia, however, has it enabled) suffer from this bug, but that has been the case for a while. The fix for bug 260 made that more visible in some areas, but it has been happening for a long while on some pages.

My point is that .mw-code should *not* have this rule (or, in fact, these rules). .mw-code elements always have another div, then a pre inside – and only this pre should have the white-space and no-wrap rules set. Then we don't have to care about newlines being inserted or removed or whatnot.

(In reply to comment #26)

My point is that .mw-code should *not* have this rule (or, in fact, these
rules). .mw-code elements always have another div, then a pre inside – and only
this pre should have the white-space and no-wrap rules set. Then we don't have
to care about newlines being inserted or removed or whatnot.

I understand your point, but that doesn't solve the problem. Let me elaborate. ".mw-code" does need these rules. The elements have no space between them, so that works perfectly fine (if Tidy is disabled - or if bug 38800 is fixed).

The mw-code class is not DIV-specific, it is for any element that can contain code. It can be applied to a DIV, PRE or any other (block-)level element for that matter.

In the specific case of the Geshi syntaxhighlighter extension the reason it wraps in a DIV (instead of applying the class to the <pre> directly, which would also solve your problem) - is because the <pre> element is outputted as part of the third-party geshi lib itself. It is not controllable (the extension doesn't output <div class="mw-code"><pre> + code + </pre></div> but <div class="mw-code">+ (geshi output) + </div>.

The third-party output in the case of the geshi extension is a <pre> element, however other extensions may output code in other ways. Aside from that, even within geshi, the wrapper element itself is variable (it can be a <div> too, so in that case there wouldn't even be a <pre> *anywhere*).

And to go even further, the geshi-lib contains hardcoded css rules that basically overrules any and all css on elements that it "owns". So setting css rules on ".mw-code > pre.geshi-internal" is (aside from being horribly specific and not belonging in MediaWiki core) wouldn't even work because Geshi has an inline reset on elements it "owns" (which makes sense to some degree). Therefore the only reliable way to style the outline of a code is to use a stand-alone class ("mw-code" in this case). And let it be applied to whatever it be applied to. This can be applied to a <pre> directly, or to a wrapper. Works either way.

But due to bug 38800 it causes vertical lines to be prepended when used in Geshi with Tidy enabled (when not using Geshi or not configuring Tidy to do this, it works fine)

All right, this makes sense, thanks. I though .mw-code is <source>-specific.

This fix is a good middle ground for all issues involved and was merged in master (I7eec3ffeaa) and deployed as part of 1.20wmf8. However it turns out that due to some stupid feature in Tidy it manages to get screwed up in production (most non-wmf wikis - that is MediaWiki default and my personal test wikis) don't have Tidy enabled and thus we (Trevor and I) didn't see this.

The CSS rule works fine in and works as expected on a "normal" install. But due to bug 38800, Tidy inserts *additional* new lines causing stuff to look messed up.

I'm re-opening this since the display issues are now back again (Tim thankfully reverted it in I1977f09356 due to the issues with Tidy). However assuming we can fix bug 38800, this bug 260 doesn't need another interim solution.

Lets leave this bug open until bug 38800 is fixed, and then simply re-apply I7eec3ffeaa to master.

Are there any updates on these? I would like to see this fixed as well.

  • Bug 51831 has been marked as a duplicate of this bug. ***

Would there be any downside to using:

pre:not(.javascript) {

overflow-x: auto;

}

The primary objection to Krinkle's original solution was that it wouldn't be good for MediaWiki javascript pages. If we simply exclude those pages, it seems like it would be a good solution for most cases.

Apparently ':not' is supported in all major browsers except for IE 8 and earlier.

Apprently the 'javascript' class is added by the SyntaxHighlight extension, not by core :(

Why has this been moved to Vector as this is not a problem restricted to any one skin?

See attachment showing a screenshot of https://meta.wikimedia.org/wiki/User:AaronPeterson/pre_play in monobook (Firefox 30, Linux)

Created attachment 16336
screenshot of m:User:AaronPeterson/pre_play Firefox 30/monobook/Linux

screenshot referred to in previous comment

Attached:

pre_overflow.png (699×1 px, 74 KB)

Krinkle lowered the priority of this task from Low to Lowest.
Krinkle updated the task description. (Show Details)
Krinkle set Security to None.

Fixed again by https://gerrit.wikimedia.org/r/#/c/220701/ (054b1c9e3cd82ee96bb6ee2be3026497e5f9f099) together with T103780, now that the SyntaxHighlight/Tidy issue is fixed. Whoo!

matmarex assigned this task to Krinkle.
matmarex added a subscriber: ori.