Posted By: intelman | Oct 21st @ 9:58 PM
page 2 of 2
Comments: 45 | Views: 552

Also a canvass tag which lets you draw graphics using Javascript (example), FWIW.

 

Does CSS3 let me say "I want these two elements to be the same height as whichever is tallest" (and similar things) without there having to be any other relationship between the two elements? I hope so but I suspect that both HTML5 and CSS3 are icing on a big smelly poo that someone really should have scooped up by now. Sad

 

Harlequin
Harlequin
http://twitter.c​om/TrueHarlequin

"Also a canvas tag which lets you draw graphics using Javascript"

 

But what about the backwards compatability aspect of that. Now we're back to the same old "if you can't see canvas, show a generated jpg"...and now we're doing things twice.

brian.shapiro
brian.shapiro
things go on as always

You can already do that, all browsers support some type of vectors, IE uses VML instead of SVG. See Raphaël (http://raphaeljs.com/) which is a Javascript library for vectors.

 

HTML5 is a lot about establishing standards for things that already exist , instead of allowing new functions, a lot of it is about going against Microsoft--there was a whole controversy about OGG being recommended as the video format.

 

SVG in HTML would be cool if it were integrated with CSS and you could do things like wrap the text of a div to a certain shape defined by SVG ( <div style="shape:url(egg.svg)" />. As far as I know, HTML5 is introducing nothing new like that.

You can make two equal-height elements using display: table, display: table-row, and display: table-cell, which are part of CSS 2.1.

 

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <style type="text/css">
    .table { display: table; }
    .tr { display: table-row; }
    .td { display: table-cell; padding: 10px; }
  </style>
</head>
<body>
  <div class="table">
    <div class="tr">
      <div class="td">

         [Column 1 here]
      </div>
      <div class="td">
         [Column 2 here]
      </div>
    </div>
  </div>
</body>
</html>

 

It works in Internet Explorer 8 (but not 6 or 7) and the other browsers.

 

And yes, it's a totally silly solution.

 

I don't think it's all about going against Microsoft. Some of the features were first introduced in Internet Explorer, like the contenteditable attribute, for instance.  It's funny that some of Apple's recent CSS "innovations" implemented in WebKit were first done with (albeit) proprietary DirectX filters in Internet Explorer.  The difference, of course, is that WebKit is an open source project and Internet Explorer is not.

stevo_
stevo_
Human after all

Canvas.. (hopefully) which will allow lots of amazing things.. whats new in CSS3? well.. they certainly haven't realized yet that key/value pairs are terrible for styling components.

stevo_
stevo_
Human after all

You can do it easier than that, but you have to pre specify which content goes into which column.. if this is dynamicaly driven that can be .... essentially impossible.

brian.shapiro
brian.shapiro
things go on as always

[edit] Sorry I posted an incorrect solution but I've figured this out before so I'm going to try to see if I can come up with it again

Harlequin
Harlequin
http://twitter.c​om/TrueHarlequin

What you can't currently do, is something with 2 divs stacked. One 100px high, the 2nd one filling the rest of the height.

 

LIke Silverlight does with RowDefinitions with grids(e.g.)

<Grid.RowDefinitions>

   <RowDefinition Height="100" />

   <RowDefinition Height="*" />

</Grid.RowDefinitions>

 

HTML/CSS has always been bad with:

- Designing to fill 100% height

- Vertically aligning in center

 

If HTML5 fixes these, I'll be a happy camper Smiley

True, but the same with all new web features really.

 

joechung: Yeah, the table-layout stuff works but I figure I might as well just use a real table then since it works in more browsers. I guess it should be more accessible to do it using the CSS table-layout though, since screenreaders should know it's a table for layout and not data.

 

The non-table solutions all seem to fall over unless you have fixed widths and/or positioning, but maybe they can be made to work if you spend an entire week playing around with them. I found whenever I thought I had something which worked it didn't really when I changed the content (e.g. it depended on one thing always being bigger than another) or when I tried in another browser.

 

It's a bit silly that there isn't a simple, obvious, cross-browser solution to such a basic layout problem and it makes me wonder why any technology is being added to the web when there are such glaring problems with the web does the very basics. Video? We haven't got text and images right yet! Smiley

 

 

brian.shapiro
brian.shapiro
things go on as always

Anyway I'm not sure what I was thinking of when I wrote up that solution... but you can hack anything you want regarding positioning in CSS, it will just be inelegant.

 

For example, to achieve what we're talking about without styling it as a table, you could do this:

 

<div style="position:relative;"> 
    <div style="position:absolute; left:0px; top:0px; height:100%;
        width:50%; background:coral;"></div>
    <div style="position:absolute; left:50%; top:0px; height:100%;
        width:50%; background:skyblue;"></div>
    <div style="float:left; position:relative; width:50%;">hello</div>
    <div style="float:left; position:relative; width:50%;">hello<br/>goodbye</div>
    <div style="clear:both;"></div>
</div>

 

The relative elements are determining the size of the parent element, while the absolute elements fit to the size of the parent element (for background colors).

 

What CSS should do, is that if you set 'height:auto;' to a parent element, and 'height:100%;' to child elements, is do what we're saying automatically. But there's no difference in CSS between height:auto; and leaving the height value empty, so it doesn't work that way.

 

Harlequin--- 

 

You can do what you want with stacking

 

<div style="height:200px;">
    <div style="height:100%; background:coral;">robot</div>
    <div style="height:50px; background:green;">robot</div>
    <div style="height:100%; background:gold;">robot</div>
</div>

 

But there are a lot of bugs with it, and you're right generally that there are problems with vertical alignment. These aren't things to be fixed in HTML though but in CSS.

 

 

brian.shapiro
brian.shapiro
things go on as always

Sorry, I forgot all about the height:100% problem in CSS, so thats wrong, but you can hack it like this:

 

<div style="height:100%; overflow:hidden;">
    <div style="height:50%; top:-25px;">
        <div style="height:100%; background:coral;">test</div>
        <div style="height:50px; background:gold;">test</div>
        <div style="height:100%; background:coral;">test</div>
    </div>
</div>

 

Where a parent element has a hidden overflow and then a child element has a top thats half the height of the element with set height and is half the height of the parent element

That goes wrong if the divs' content is bigger than their natural sizes:

brian.shapiro
brian.shapiro
things go on as always

Yes , you just have to do more work to get it to work the way you want to use all three divs for content. The top div should have a top padding of 25px and the bottom a bottom padding of 25px (or have empty 25px spacer divs if you want those two to have borders). [edit: no, you need to do the spacer divs, the padding messes up the layout]

 

Then you need to set overflow to hidden on all of the visible divs. Which isn't a problem considering if you wanted those divs to be those sizes.

 

Now are you asking about having the center div automatically change its size to its content and still stay centered to the page? I'll have to look at that.

 

edit -- oh wait are you talking about the text affecting the sizes of the sections? actually I forgot you have to do some absolute/relative positioning to get the centering working right. I edited that out before I pasted the code in here.

 

you have to do something like this

 

<div style="height:100%; float:left; width:100%; overflow:hidden; position:relative; ">
    <div style="height:50%; width:100%; position:absolute; top:-25px;">
        <div style="height:100%; background:coral;">test</div>
        <div style="height:50px; background:gold;">test</div>
        <div style="height:100%; background:coral;">test</div>
    </div>
</div>

 

Either that or use top-margin instead of top

 

<div style="height:100%; float:left; overflow:hidden; ">
    <div style="height:50%; margin-top:-25px;">
        <div style="height:100%; background:coral;">test</div>
        <div style="height:50px; background:gold;">test</div>
        <div style="height:100%; background:coral;">test</div>
    </div>
</div>

 

a negative top works for position:absolute; for position:relative you need a negative top-margin

brian.shapiro
brian.shapiro
things go on as always
Anyway, this is the markup you need to do the vertical centering properly, so text and borders can be in all three divs, but without the center div resizing like you may also want:
<div style="height:100%; float:left; overflow:hidden; width:50px;">
    <div style="height:50%; margin-top:-26px;">
        <div style="height:100%; background:coral; border:1px solid green;
            overflow:hidden;">
            <div style="height:25px;"></div>
            <div style="border-top:1px solid green;">test one, two,
                three, four</div>
        </div>
        <div style="height:50px; background:gold; overflow:hidden;">test one, two,
                three, four</div>
        <div style="height:100%; background:coral;  overflow:hidden;">
            <div style="height:100%; border:1px solid green; margin-top:-28px; ">
                <div style="height:27px;"></div>
                <div style="border-top:1px solid green; overflow:hidden;">test one,
            two, three, four</div>
            </div>
            
        </div>
    </div>
</div>
<div style="float:left; height: 100%; background:skyblue;  width:50px;">test</div>
The 25px, -26px , -28px, 27px are all set like that to make room for the borders.
brian.shapiro
brian.shapiro
things go on as always

This will vertically align a single box, regardless of size in a modern browser which support inline-block (I think its all of them now)

<div style="height:100%; float:left; overflow:hidden;
    width:50px;">
    <div style="display:inline-block;height:100%; width:0px; vertical-align:middle;">
    </div>
    <div style="display:inline-block; width:40px; background:coral;
    vertical-align:middle;">test one, two, three, four;</div>
</div>

 

Get rid of the whitespace to make the width 100%; if theres any whitespace that counts as a space character with inline-block

<div style="height:100%; float:left; overflow:hidden;
    width:50px;">
    <div style="display:inline-block;height:100%; width:0px;
    vertical-align:middle;"></div><div style="display:inline-block; background:coral;
    vertical-align:middle;">test one, two, three, four;</div>
</div>

brian.shapiro
brian.shapiro
things go on as always

I got something pretty close:

 

 

One minor issue: when the browser height is less than the height of the text, the bottom border on the top block will disappear.

 

<div style="height:100%;">
<div style="height:50%; background:gold;  width:48px; position:relative;
    border:1px solid green; overflow:hidden;">
    <div style="overflow:hidden; position:absolute;  height:100%;">
        <div style="display:inline-block;height:100%; width:0px;
        vertical-align:bottom;"></div><div style="display:inline-block;
        background:coral;
        vertical-align:bottom; position:relative;">
            test one, two, three, four;
            <div style="position:absolute; top:0px; border-bottom:1px solid green;
            margin-top:-2px;
            background:gold; width:100%; height:50%;"></div>
            </div>
    </div>
    <div style="position:absolute;">
    block 1
    </div>
</div>
<div style="height:50%;  background:skyblue; width:48px; border:1px solid green;
    overflow:hidden;">
    <div style="background:coral; position:relative;">
        test one, two, three, four;
        <div style="position:absolute; border-top:1px solid green; top:50%;
        margin-top:-3px;
        background:skyblue; width:100%; height:100%;">
        block 3
        </div>
    </div>
</div>
</div>
<div style="height:100%; overflow:hidden; position:absolute; top:0px;
    width:50px;">
    <div style="display:inline-block;height:100%; width:0px;
    vertical-align:middle;"></div><div style="display:inline-block; width:50px;
    background:coral;
    vertical-align:middle;">test one, two, three, four;</div>
</div>

 

Which can be fixed, by putting the border on the middle block instead of on the top block.

brian.shapiro
brian.shapiro
things go on as always

And this works perfectly:

 

<div style="height:100%;">
<div style="height:50%; background:gold;  width:48px; position:relative;
    border:1px solid green; overflow:hidden;">
    <div style="overflow:hidden; position:absolute;  height:100%;">
        <div style="display:inline-block;height:100%; width:0px;
        vertical-align:bottom;"></div><div style="display:inline-block;
        background:coral; width:100%;
        vertical-align:bottom; position:relative;">
            test one, two, three, four;
            <div style="position:absolute; top:0px; 
            margin-top:-2px;
            background:gold; width:100%; height:50%;"></div>
            </div>
    </div>
    <div style="position:absolute;">
    block 1
    </div>
</div>
<div style="height:50%;  background:skyblue; width:48px; border:1px solid green;
    overflow:hidden;">
    <div style="background:coral; position:relative; width:100%;">
        test one, two, three, four;
        <div style="position:absolute; top:50%;
        margin-top:-3px; left:0px;
        background:skyblue; width:100%; height:100%;">
        block 3
        </div>
    </div>
</div>
</div>
<div style="height:100%; overflow:hidden; position:absolute; top:0px;
    width:50px;">
    <div style="display:inline-block;height:100%; width:0px;
    vertical-align:middle;"></div><div style="display:inline-block; width:50px;
    background:coral; border-top:1px solid green; border-bottom:1px solid green; 
    vertical-align:middle;">test one, two, three, four;</div>
</div>

 

The bottom border for the top block and the top border for the bottom block are just on the middle block. Borders on the middle block can be inserted inline.

brian.shapiro
brian.shapiro
things go on as always

It has some problems in Opera and IE. Opera seems not to want to vertically align anything against a div that has a width of 0px. That can be solved by making the container pixel larger for a 1px div, and then having a negative margin-left in a container with overflow:hidden.

 

I'm not sure whats wrong in IE yet. It works in Safari and FF. I'm actually interested in getting it working so I'll play around with it.

 

edit --IE isn't doing the inline-block correctly. which i don't understand, since its been in IE since at least IE6.

 

Also across browsers, its not aligned correctly because the borders are giving the 50% divs extra padding that adds up to more than 100% of the height. That can be fixed by putting the borders in an interior div.

The myriad of "solutions" you've presented and how much goes into trying to figure them out/debug them just shows how utterly appaling HTML+CSS is for doing layouts. This really shouldn't be a hard thing to do at all.

 

It's why I've said many times over that HTML needs a <grid> equivalent. Of course nobody in the standards body wants that because they'll claim it breaks the seperation of layout and content, which is true. The real problem with HTML+CSS is that it's approach to seperating content and presentation is flawed from the start. If HTML took the approach of a single document that describes layout, which then pulls content into the various sections vi something like databinding, the web would be a much, much, richer platform already. I had hoped that whatever came along to eventually replace HTML might take that route, but sadly we'll just get exactly the  same problems from XHTML+CSS.

Amen to that!

 

It's too complex to do very simple layouts and the results are too fragile.

 

HTML+CSS gives very little separation between content and data since the page layout is extremely dependent on the order and nesting of elements in the HTML. The separation is better done at another level via CMS systems, XML+XSLT, etc.

 

brian.shapiro
brian.shapiro
things go on as always

I know there's problems -- I was just demonstrating my theory that you could 'technically' do any positioning in css with a lot of work -- but the fixes can be in css, not html. All you have to do is have something equivalent to the * value in WPF.

 

<div>
    <div style="height:*"/>
    <div style="height:auto"/>
</div>

 

That would be a grid.

page 2 of 2
Comments: 45 | Views: 552
Microsoft Communities