To fix box-model positioning

I don't have a certain proposal for a new property anymore, but I'm
going to lay out some use-cases so that the more intelligent/experienced
people on this group can figure out the *right* way to do this.

Requirement: The CSS box model should be more powerful than the HTML
table model, should require less code than the HTML table model, and its
code should be more readable than the HTML table model when laying out
web pages.

My (arguable) opinion on a result of this requirement: Using
"margin:auto" to center things horizontally is not as readable as the
mechanism should be. The "float" property is better, but I don't think
it's powerful enough, and, again, it could be named better. "Float" was
originally intended for images that text should wrap around. Let's keep
it that way.

The following Use Cases are written in pseudo-CSS. The <style> tag
contains a stylesheet, and the <body> tag contains an HTML document. I'm
(incorrectly) using <body> as the root of the document to shorten my
stylesheets. The Use Cases are only concerned with block layout, not the
text inside the blocks.

Use Case 1:

Centering Boxes:

<style>
body {height: 100%; width: 100%; background-color:blue;}
#center (block-align: center; background-color: white; height: 300px;
width: 300px;}
</style>
<body>
  <div id="center">
    This div is centered in the viewport. It's always 300px by 300px,
with a variable blue border, and a white background.
  </div>
</body>

Note: The CSS to achieve this effect should be very simple, as the
desired effect is very simple.


Use Case 2:

Arbitrary positioning:

<style>
body {height: 100%; width: 100%; background-color:blue;}
#topleft (block-align: 10% 10%; background-color: white; height: 20%;
width: 20%;}
#topright (block-align: 90% 10%; background-color: white; height: 20%;
width: 20%;}
#bottomleft (block-align: 10% 90%; background-color: white; height: 20%;
width: 20%;}
#bottomright (block-align: 90% 90%; background-color: white; height:
20%; width: 20%;}
#centered {block-align: center center; background-color: white; width:
50%;
</style>
<body>
  <div id="topleft">
    This div is positioned in the top left of the screen. It is 20% of
the width of the document and 20% of the height. The body's blue
background is visible on all sides.
  </div>
  <div id="topright">
    This div is positioned in the top right of the screen. It is 20% of
the width of the document and 20% of the height. The body's blue
background is visible on all sides.
  </div>
  <div id="bottomleft">
    This div is positioned in the bottom left of the screen. It is 20%
of the width of the document and 20% of the height. The body's blue
background is visible on all sides.
  </div>
  <div id="bottomright">
    This div is positioned in the bottom right of the screen. It is 20%
of the width of the document and 20% of the height. The body's blue
background is visible on all sides.
  </div>
  <div id="centered">
    This div is in the center of the document. It is 50% of the width of
the screen and its content determines its height. If there's enough
content, the document could be longer than one screen, so fixed
positioning won't work. Absolute might work for the corner boxes, but if
we add a min-width to them, I think it breaks too.
  </div>
</body>

Note: I don't know why someone would do this, but it should be possible.


Use Case 3:

A 3-column layout:

<style>
#left   {align:left top; min-width: 100px; width: 15%; height:
remaining; border: 1px solid green}
#body   {align:center center; width: remaining; height: remaining;}
#right  {align:right bottom; min-width: 100px; width: 15%; height:
remaining; border: 1px solid green}
</style>
<body>
  <div id="left">
    This column fills the left side of the page. It is 15% of the window
or 100px wide, whichever is greater.
  </div>
  <div id="body">
    This column fills the center of the page. It expands horizontally to
fill any space left between the left and right columns.
  </div>
  <div id="right>
    This column fills the right side of the page. It is 15% of the
window or 100px wide, whichever is greater.
  </div>
</body>

Note: This one can be done with floats.


Use Case 4:

Pseudo-frames:

<style>
body {width: 100%; height: 100%;}
#top {left: 0; top:0; min-height: 100px; height: 15%; width: remaining;
border: 1px solid red}
#left {left: 0; bottom: 0; min-width: 100px; width: 15%; height:
remaining; border: 1px solid green}
#right {right: 0; top: 0; min-width: 100px; width: 15%; height:
remaining; border: 1px solid blue}
#bottom {right: 0; bottom:0; min-height: 100px; height: 15%; width:
remaining; border: 1px solid purple}
#content {align: center; width: remaining; height: remaining; border:
1px solid black}
div {overflow: scroll;}
</style>
<body>
  <div id="top">
    This div touches the top-left corner, extends downward 100px or 15%
of the window, whichever is greater, and extends rightward until it
touches the #right div.
  </div>
  <div id="left">
    This div touches the bottom-left corner, extends rightward 100px or
15% of the window, whichever is greater, and extends upward until it
touches the #top div.
  </div>
  <div id="right">
    This div touches the top-right corner, extends leftward 100px or 15%
of the window, whichever is greater, and extends downward until it
touches the #bottom div.
  </div>
  <div id="bottom">
    This div touches the bottom-right corner, extends upward 100px or
15% of the window, whichever is greater, and extends leftward until it
touches the #left div.
  </div>
  <div id="content">
    This div fills the center of the screen and touches all four
side-divs. Every div's content will scroll if it overflows, mimicking
frames. I'm pretty sure this effect with pixel lengths cannot be
achieved with the current box model.
  </div>
</body>


Wishlist, wouldn't-it-be-cool-if stuff:

Use Case 5:

Making Square Boxes:

<style>
body {height: 100%; width: 100%; background-color:blue;}
#center (block-align: center center; background-color: white; height:
50%; width: square;}
</style>
<body>
  <div id="center">
    This div is centered in the viewport. Its height is 50% of the
window height, and its width is equal. It has a variable blue border and
a white background.
  </div>
</body>


Use Case 6:

This one would be very useful for pop-up menus by eliminating lots of
JavaScript code:

<style>
#body {block-align: center; width: remaining; height: remaining;}
#menubar {block-align: left top; width: 15%; border: 1px solid green;}
.menuitem {width: 100%;}
.popupmenu {position: relative-to; element-ref: id(attr(submenuof));
vertical-align: top; 
  horizontal-align: right-side; display:none; border: 1px solid red;}
</style>
<body>
  <div id="menubar">
    <div class="menuitem" id="item1">
      Item 1. As wide as the menu.
    </div>
    <div class="menuitem" id="item2">
      Item 2
    </div>
    <div class="menuitem" id="item3">
      Item 3
    </div>
  </div>
  <div id="body>
    Fills the right side of the document; all space except what the menu
takes up.
  </div>
  <div class="popupmenu" submenuof="item1">
    This box, if its display were set to block by JavaScript code, would
appear with its top left corner concurrent with the top right corner of
Menu Item 1. It would not affect document flow. "left" and "top" could
be used to displace it from there.
  </div>
  <div class="popupmenu" submenuof="item2">
    This box, if its display were set to block by JavaScript code, would
appear with its top left corner concurrent with the top right corner of
Menu Item 2. It would not affect document flow.
  </div>
  <div class="popupmenu" submenuof="item3">
    This box, if its display were set to block by JavaScript code, would
appear with its top left corner concurrent with the top right corner of
Menu Item 3. It would not affect document flow.
  </div>
</body>


My and Vadim's block-align property might help with some of this, but
it's definitely not enough by itself.

Jeffrey Yasskin

Received on Friday, 26 October 2001 02:02:23 UTC