Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Themes 2.0 overflow problems

From MoodleDocs

This document examines the overflow:hidden - fixed width problem currently plaguing several areas of Moodle 2.0 (as of October 26, 2010)

The problem

Content that is too wide for the main content area is not displayed correctly is obscured behind the side blocks or off-screen, and the browser doesn't scroll horizontally.

To see it, shrink your browser window and look at:

It is caused by oversized, unwrappable content:

  1. Large images or other media of one form or another.
  2. Tables, any table that has numerous columns and/or large content in columns.
    • Tabulated data
    • Tables for internal layout (like the forum)
  3. Unwrappable content
    • This is normally always user-entered text or images.
    • Different browsers handle things differently.

The technical description

The cause is a combination of the fixed width that gets set on the core layout XHTML, and the overflow:hidden setting that is required by the layout.

The layout used in the base theme within Moodle is based on Matthew James Taylor's Holy grail layout which is an excellent layout, however (and it does state this in the description of the layout) wide content is a known problem.

This problem starts on the very first div that contains content within the body *<div id="page-content">....</div>* which has the following style:

  1. page-content {clear:both;float:left;overflow:hidden;position:relative;width:100%;min-width:900px;}

Setting the width to 100% instantly boxes the displayable area to just the browsers internal display width, and then overflow:hidden ensures that any overflow is not visible.

This is required because the premise of this layout is to move everything out of the viewport and then move things back into the correct position and in doing this it goes as far as expanding content divs out to 200% width.

Because of this if we remove the width 100% and/or overflow hidden everything breaks because the page will ALWAYS expand beyond the browsers displayable area even if the content is easily displayed.

As far as I can see there is no way to avoid this problem while using this layout.

On the other hand there are very good reasons for using this layout:

  • it is cross browser,
  • columns are orderd 2,1,3 which is good for accessibility and search engine optimisation, and
  • in EVERY other respect it works well

Proposed solution 1

A couple of days ago I sat down with Martin and explained this to him and we looked into it and came up with the following three part solution:

  1. Wrap format_text output within a div with a class that allows us to manage overflow. The themes can then turn on overflow:auto for these areas to make sure that user content wraps correctly (eg forum post content).
  2. Convert places that use tables for layout to divs (eg forum posts) so that they wrap cleanly. Without this the large user content causes the table cells to grow too large, causing wrapping issues.
  3. Locate places where tables are likely to require horizontal scrolling and wrap them in divs with a class like `flexible-wrap` that sets an overflow:auto so that the table is scrollable if required.


Advantages

  1. A standard way for developers and themers to deal with these issues (can go in coding guidelines)
  2. Will remove the possibility for users to intentionally/accidentally destroy the interface by posting large content

Possible problems

  1. Because all format_text calls will be wrapped by this special div there might be regressions throughout Moodle - we will have to review the calls and possibly disable the new wrapping divs for some of them. (For example, quiz multiple choice options are processed by format_text, then output inside a Label. The wrapping div would break that horribly.)
  2. Some parts of Moodle can never be made to fit in a sensible width. For example the gradebook, and other reports.
  3. IE6/7 (and possibly IE 8/9?) render their scrollbars INSIDE an element rather than outside like most other browsers meaning that there is a *VERY* high chance there will be redundant scrollbars within some elements that don't actually require wrapping (on these browsers)
  4. Elements that require scrolling will have their own scrollbars and particularly in the case of tables this is likely to require scrolling the page vertically to locate the horizontal scrollbar, scrolling horizontally and then locating the desired row vertically again.
  5. Elements with a set width (e.g.style="width:2000px") greater than the content area will need to be wrapped in a div with the wrapping class as well.


Proposed solution 2

Compromise, and use a 1, 3, 2 or 1, 2, 3 layout (with skip links for accessibility).

Advantages

  1. It can be made to work for all pages.
  2. We use a 1, 3, 2 at the OU, and it is reliable.

Possible problems

  1. Slightly less accessible (unless you are comparing with the current situation that actually chops off text for most users even before you start resizing fonts, and is therefore infinitely less accessible, of course).
  2. Hurts our pride to give up on a 2, 1, 3 layout.

Proposed solution 3

Add some JavaScript to the page, so that once everything has been laid out, it computes how side the page need to be to avoid truncation, and then changes the min-width: 900px to whatever width is needed to make the content fit.

Advantages

  1. Might be the easiest solution to implement.

Possible problems

  1. Ewwwwwww! This is clearly a horrible hack.
  2. JavaScript for layout is deeply evil.


Opinions

Tim: I vote for 2, or failing that 3. I think 1. will not work.

sam: agree with Tim except I don't think 3 is likely to be reliable either.