?
Solved

Laying out a school-timetable-like grid

Posted on 2004-11-10
16
Medium Priority
?
1,202 Views
Last Modified: 2008-01-09
I have a grid of data that I need to lay out with tight control over the layout.  Each row can have an arbitrary number of items, with arbitrary widths.  It's a bit like a school timetable:

|Monday |----- Maths --------|------------------ English --------------------|
|Tuesday|-- Maths --|--Science --|--Football--|-------Geography--------|

except that there are tens or hundreds of items per line, and their widths are arbitrary. The widths in a row always add up to the same total, so the whole thing is a rectangle.  The right-hand edge must be dead straight, as must any column within the grid (ie. a vertical set of items that start after the same cumulative total of preceding widths).

I'm converting this from a document that has exact layout (imagine it's a PDF), and I need to maintain its layout.  If I use pixels for the widths it all works perfectly, but then you can't view it at different text sizes (as in View / Text Size).

My thought was to use float:left divs for the items.  Here's an example:

<html>
<body>
<div style='width: 20em;'>
<div style='float: left; width: 4em; background-color: orange;'>Div A</div>
<div style='float: left; width: 4em; background-color: pink;'>Div B</div>
<div style='float: left; width: 4em; background-color: orange;'>Div C</div>
</div>
<div style='clear: both; width: 20em;'>
<div style='float: left; width: 3em; background-color: orange;'>Div A</div>
<div style='float: left; width: 5em; background-color: pink;'>Div B</div>
<div style='float: left; width: 4em; background-color: orange;'>Div C</div>
</div>
</body>
</html>

That should show the two 'Div C's lining up 8em from the left margin (the only difference between the two rows is 4em/4em vs. 3em/5em).  But in IE6 at the Smaller text size, they're off by one pixel.  There's also a problem in Firefox whereby single-pixel white horizontal or vertical gaps appear between the items at various font sizes, for which I have a partial workaround (http:Q_21201514.html), but it's not ideal.

These problems are almost certainly caused by rounding errors in the browsers, as they render my em units into pixels.  Similar problems occur if I use percentages.  How can avoid that?  How can I achieve the fine control over the layout that I need, and yet still have the page scalable using View / Text Size?
0
Comment
Question by:RichieHindle
  • 7
  • 4
  • 3
  • +1
16 Comments
 
LVL 14

Author Comment

by:RichieHindle
ID: 12545797
Just to clarify something: when I say "I'm converting this" I should say "I'm writing a C program to convert this" - I can't make any assumptions about what the grid contains beyond what I've said above.  And my program won't be able to make human judgements about how best to do its job.
0
 
LVL 3

Expert Comment

by:krakilin2001
ID: 12564570
Why not simply use tables.  You can use the colspan and rowspan attributes to join table cells.  You would start by calculating the maximum number of divisions (hours, minutes, etc) and then join cells of different time periods to create the table.
0
 
LVL 14

Author Comment

by:RichieHindle
ID: 12566450
krakilin2001: I need to precisely control the width of the items.  Setting the width of table cells causes the same problems as I get with setting the width of divs - for example:

<html>
<body>
<table border='0' cellpadding='0' cellspacing='0'><tr>
<td style='width: 4em; background-color: orange;'>A</td>
<td style='width: 4em; background-color: pink;'>B</td>
<td style='width: 4em; background-color: orange;'>C</td>
</tr></table>
</body>
</html>

In Firefox 1.0, I get white gaps between B and C when I go Ctrl+Minus to reduce the font size.  The margin-left: -1px workaround suggested in http:Q_21201514.html causes text truncation in IE.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 3

Expert Comment

by:krakilin2001
ID: 12573379
Could you give us an example of what exactly you are trying to lay out.  I feel this could help get us on the right track.
0
 
LVL 14

Author Comment

by:RichieHindle
ID: 12573550
It's the output of a report writer.  The file format is binary and needs a proprietary viewer, so there's no point making an example available, but I've put a sketch of how the output might look here: http://entrian.com/report.gif

The underlying format is a character grid, with pieces of text laid out on it.  So for instance, the item "Really Good Electronics" is at roughly position (15, 5), 15 characters in and 5 rows down (assuming rows 2 and 4 are blank).  Pieces of the output are tabular, but that's up to the report designer - the layout can be arbitrary.

If the whole thing were in the same fixed-width font, you could lay it out using <pre> and it would look fine.  But the user can change the fonts, which changes the layout.  If you put "12th November 2004" into a huge font, the first 18 character columns of the grid would grow wider to accommodate it, pushing the other items across the page so that everything still lined up.

It's that underlying character grid that makes the layout like a school timetable.  Imagine a timetable divided into 10-minute columns, where each column can have its own width.  For an 8-hour day, there would be 48 columns.  Now imagine a 48-character-wide report: same thing only with narrower columns.  Each character column can have its own width, determined by the fonts of all the items that intersect that column.

Looking at the example, you'd be tempted to convert to HTML by using a sequence of tables, one for "12th..." and "Page 1", one for "Total...", one for "Really Good..." and the address, one for the data grid, and one for "(This is...".  But note how "(This is..." lines up with "Really Good...".  That's why I need precise control over the layout - that sort of relationship must be preserved.  Also note how the data for Australasia is indented by one character under the heading - subtleties like that must be preserved as well.

If I didn't care about users changing their browser's font size, I could lay it all out by specifying pixel widths and it would be fine, but I need it to work at different browser font-size settings.

Sorry for the lengthy explanation, but it's a difficult problem to describe!  If I could award more than 500 points, I would.
0
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 12574889
Given the athe requirement is that an arbitray number of variables arbitray value can be presented without restrictions on format; and the expectations is to produce a predictable layout my response is that the requirements are not reasonable and unless there is some limit to the variabilty of the input then the only reliable prediction of output is that it will produce out with unpredictable properties.

In other words given the current requirements... not going to happen with the browser technology currently available in this universe.  You need a piece in the middle to convert to a predictable format for the browser.

Cd&
0
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 12574894
An XML dataset might be the intermediate format you need.

Cd&
0
 
LVL 3

Expert Comment

by:krakilin2001
ID: 12574951
I agree with COBOLdinosaur.  The way you are describing the layout, it would be very difficult to accomodate all circumstances.  An XML document could work well.  If well-designed, you would simply need to create an XSLT document afterwards.  However, you may also want to consider creating some type of graphic image format or even PDF.  In either case, if you already have the coordinates of each element calculated, you should be able to position each element with relative ease.
0
 
LVL 14

Author Comment

by:RichieHindle
ID: 12575792
I was right with you, nodding sadly, thinking you were right that what I want is beyond current browsers, until you started talking about XML.  Now I'm wondering what I've missed.  Why would using XML/XSLT change the limits of how the browsers can render the data?  As I understand it, the XSLT would convert the XML into HTML/CSS and I'd be back where I started.

As for using a more suitable format like PDF, yes, the product can already do that.  The requirement is for purely browser-based report viewing, without any reliance on plugins.  We already have HTML output for this, but it's not as WYSIWYG as we'd like.  This is an attempt to use modern HTML/CSS to make the HTML output more WYSIWYG.
0
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 12576058
Insert tags or attributes during generation of the xml file to indicate the infromation about size and co-ordinates; or anything else that is need for rendering.  Then when the xml is processed through xslt the additional information makes dynamic styling much more a task in coding a few rules instead of data content analysis.

Cd&
0
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 12576068
You could also put the raw xml file in the page as a data island and use Javascript to parse it and generate the HTML, but that will be less efficient and marginally less reliable.

Cd&
0
 
LVL 14

Author Comment

by:RichieHindle
ID: 12585478
Sorry, I really don't follow.  Using XML/XSLT can move some of the work to the client, sure.  But at the end of the day, either the browser can render the data how I want, or it can't.  The delivery mechanism doesn't matter - whether I do all the work in C, or move some of it to XSLT, I'll still get little white gaps in Firefox.  I can't even hand-craft HTML to work properly (which is where we came in).  I'm inclined to agree that "given the current requirements... not going to happen with the browser technology currently available".
0
 
LVL 30

Accepted Solution

by:
GrandSchtroumpf earned 2000 total points
ID: 12607780
Now if you want to use the margin -1 trick, you will need to add -1 per number of unit elements of your div, this way you'll get the same total offset at the end of each line, no matter how many divs are in the line.  e.g.  if your div is 3 unit-increments, you will use left-margin = -3.
This will work for all divs except for the first one of course... so, you would need to find another trick for that... but it would be a big headache.

However, if you use tables with 'table-layout: fixed', everything looks perfect in both browsers:
You set the total width of your table (either an 'em' value or a '%' value) and use colspan do define your cell weight.  It's very flexible.  The only thing is that the colspan values must be positive integer values and the total for each line should be equal.  It's now up to you to divide your timetable in as many cells you want.

The only thing is that IE does not handle the size of the cells too well... take a look at the 100% table and resize your IE window.  You can see that the resize is made by chunks while in FF is seems very smooth (that's the great thing about FF not rounding the values).  If you multiply the colspan values by 10, you'll see it even better.  So, here is one more point for FireFox.
Anyway, if you use a table, you'll be certain the borders of the cells in different lines will align correctly.

here is the code:


<div style='padding: 3em;'>

<table class='TimeTable' border='0' cellpadding='0' cellspacing='0' style='table-layout: fixed; width: 12em;'>
<tr>
<td colspan='4' style='overflow: hidden; background-color: orange;'>A</td>
<td colspan='4' style='overflow: hidden; background-color: pink;  '>B</td>
<td colspan='4' style='overflow: hidden; background-color: orange;'>C</td>
</tr>
<tr>
<td colspan='3' style='overflow: hidden; background-color: orange;'>A</td>
<td colspan='5' style='overflow: hidden; background-color: pink;  '>B</td>
<td colspan='4' style='overflow: hidden; background-color: orange;'>C</td>
</tr>
</table>

</div>
<div style='padding: 3em;'>

<table class='TimeTable' border='0' cellpadding='0' cellspacing='0' style='table-layout: fixed; width: 100%;'>
<tr>
<td colspan='4' style='overflow: hidden; background-color: orange;'>A</td>
<td colspan='4' style='overflow: hidden; background-color: pink;  '>B</td>
<td colspan='4' style='overflow: hidden; background-color: orange;'>C</td>
</tr>
<tr>
<td colspan='3' style='overflow: hidden; background-color: orange;'>A</td>
<td colspan='5' style='overflow: hidden; background-color: pink;  '>B</td>
<td colspan='4' style='overflow: hidden; background-color: orange;'>C</td>
</tr>
</table>

</div>
0
 
LVL 14

Author Comment

by:RichieHindle
ID: 12613358
GrandSchtroumpf: That looks very promising!  Many thanks - I'll see how well I can apply it to my problem and report back.
0
 
LVL 14

Author Comment

by:RichieHindle
ID: 12665559
GrandSchtroumpf: Your 'table-layout:fixed' technique works very well - many thanks!
0
 
LVL 30

Expert Comment

by:GrandSchtroumpf
ID: 12669758
you are welcome Richie, <:°)
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

SASS allows you to treat your CSS code in a more OOP way. Let's have a look on how you can structure your code in order for it to be easily maintained and reused.
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
In this tutorial viewers will learn how to position overlapping items using z-index in CSS. They will also learn the restrictions on the z-index property.  Create a new HTML document with an internal stylesheet.: Create a div in CSS and name it Red.…
In this tutorial viewers will learn how to style a decorative dropcap for the first letter in a paragraph using CSS. In CSS, create a new paragraph class by typing "p.fancy": Then, to style only the first letter of the first sentence, include the ps…
Suggested Courses
Course of the Month14 days, 5 hours left to enroll

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question