W3C home > Mailing lists > Public > www-style@w3.org > April 2009

Re: css alignment?

From: Brad Kemper <brad.kemper@gmail.com>
Date: Mon, 6 Apr 2009 08:59:03 -0700
Cc: www-style@w3.org
Message-Id: <76BD71CA-0CE4-47BE-9FB5-C0AD77EAFE70@gmail.com>
To: inhahe <inhahe@gmail.com>

Forgot to reply all the first time...


On Apr 1, 2009, at 5:29 PM, inhahe wrote:
> I don't have much experience with CSS, but I've read the tutorials.   
> Maybe I'm wrong, but it seems that there's no good way to do  
> alignment.  Like, things that people prefer to do with tables,  
> because it Just Works, even though the CSS community chastizes  
> people for that.
>
> For example let's say I have two divs in a left column, and one on  
> the right.  (maybe the two left div's are within a larger div, and  
> the larger div and the right div are float:left.)  Now I want the  
> right div to size itself just as tall as necessary to go down  
> exactly as much as the two left div's do.  (say i have a background  
> and pretty borders and stuff.  using absolute positioning and  
> sizing  for this kind of stuff (alignment-related) isn't very  
> dynamic; it has to be changed every time content changes and changes  
> the sizes of things, to make things match.
>
> I tried an experiment (hope this e-mails okay):

No, but I fixed that:

<html><body>
<div>
   <div style="height: 100%; background-color: red; float:left">
     this<br/>
     is<br/>
     a<br/>
     test
   </div>
   <div style="background-color: blue; float:left">
     hi
   </div>
   <div style="height: 100%; background-color: green; float:left">
     foobar
   </div>
</div>

> </body></html>
>
> (please ignore my lack of proper doctype, etc.)
>
> hoping that would do the trick.. it didn't.  wouldn't it be nice if  
> it did?  (i was hoping that the left and right divs would both size  
> themselves to 100% of the available height of the outer div, while  
> the outer div auto-sizes itself to the minimum size necessary to  
> accomodate the contents of both the left and right div's.)

For display:block the outer DIV does that, but that is not what 100%  
height means for the inner DIVs. You can do that like this, however,  
with no float or height properties needed (or, more precisely, with  
{ float:none; height:auto; }:

DIV { display:table;  }
DIV DIV { display:table-cell; }

> that would be a simple solution and not even requiring any extra  
> syntax, but i thought of a whole new system that could improve on  
> this ability.  basically some sort of alignment commands for CSS,  
> which allow you to align certain things (left/right/top/bottom  
> border/margin/content edge) with certain things of other elements.   
> for example you could align an element's left and right margins with  
> another element's left and right margins, the other element being  
> referenced by its id attribute.  then additionally you could move it  
> left/right from that spot with relative positioning (using the  
> normal relative positoning syntax) if you wanted.
>
> i would imagine aligning a left margin with a left margin would  
> require a briefer syntax then aligning a left margin with, say,  
> another left border.  or another *right* margin.  (with the briefest  
> syntax would it align only the margin by default, or margin, border,  
> and content edge?)  for example maybe "align-left-border: someid" to  
> align the left border with someid's left border, or "align-left- 
> border: someid/right" to align left border with someid's right  
> border, or "align-left-border: someid/right/margin" (obvious  
> meaning), or "align-left-border: someid/margin" for someid's left  
> margin, or "align-left:someid" to align left margin with someid's  
> left margin (or left margin/border/content-edge?)
>
> of course you don't always want to just align one thing with  
> another, because hwat if the sizes of both things are dynamic (auto- 
> generated or frequently modified) and you're not sure which will  
> need more space, but you want both things aligned (like in my html  
> code above, only you don't know which div will be taller).  in that  
> case i think the simplest solution would just be to align all the  
> things you want to align with eachother to a common id attribute  
> which doesn't actually refer to an existing element.  but not to  
> make things confusing, such ad hoc referents should probably be  
> distinguished somehow from actual id's, for example by prefixing  
> with a certain character.

Please read the latest draft about a system under development that  
would allow elements to arbitrarily align to various grid lines. Its  
called  "Advanced Layout."

    http://www.w3.org/TR/2009/WD-css3-layout-20090402

It may be just what you are looking for.


> i wrote more about this in my blog at http://inhahe.blogspot.com  
> (after my ramblings about a few other things which may not be actual  
> issues).

Extra dot in your URL. Should be: http://inhahe.blogspot.com/

Here are some thoughts about that:

> So what tags do we have for containing content, other than div? Span  
> would be nice, except that it has strange limitations: it can't  
> contain certain other HTML tags, and apparently it can't even  
> contain line breaks.
DIVs and SPANS are very generic, but there are many HTML elements that  
can contain content. In HTML, an inline element, such as SPAN (or B,  
or I, or ACRONYMN, etc.) cannot contain a block element (like DIV, P,  
BLOCKQUOTE, etc.). But in CSS almost any element can be changed from  
inline to block, or vice versa, with the display property. DIVs and  
SPANs can both contain line breaks (BRs), but they are often not  
semantically correct. (If you are using them to divide paragraphs,  
then they are the wrong HMTL. If you are using them to adjust where  
the end of a line occurs within the paragraph, then there might be a  
more appropriate way to do that in CSS.)

> So we just have div, and then whenever we don't want a damn margin,  
> because all we want to do is demarcate data, we have to write CSS  
> code to specify that.
DIVs do not, by default, have any margin associated with them.

> Divs also by default come below each other in sequence, unlike  
> normal information which flows left to right, so that's another  
> thing you sometimes have go out of your way to change in CSS.
DIVs are display:block by default. SPANs are display:inline by  
default. You can easily change that in CSS quite easily, but it is  
usually the main reason one chooses DIV instead of SPAN.


> So clearly we're missing something here, something in between div  
> and span, or at least a span that likes people.

There are other values for the display property, such as inline-block,  
table-cell, etc.

> I've also seen ul's used with CSS, for menus. You have to modify  
> them extensively to get rid of the bullets and margins, maybe make  
> them go left-to-right, etc. It seems like they're being used in  
> cases like these for something other than their intended purpose,  
> and I tried doing the same thing in some other way than using ul's,  
> and it didn't work. So that implies that ul's are being used to fill  
> in for some other shortcoming.
If ULs and LIs are used for things that are lists, then that is their  
intended purpose. Those HTML lists have some default CSS styling that  
can be changed if you have a list and want non-default styling (to  
remove bullets and margin, for example).


> What I really was thinking right now, though, is that the degree of  
> separation of content from separation in CSS is very limited.  
> Basically you can specify sequences of information-elements and in  
> specific hierarchies, and then display those elements and  
> hierarchies in any way you want, but if the way you want to display  
> it involves changing the order of the information (without using  
> absolute positioning) that's a no-go. That can only be done by  
> editing the HTML or the scripting code. Since a CSS file is designed  
> to define only attributes of classes/tags on a syntactic level,  
> there really isn't remotely a way for it to specify order of  
> information. It would have to be changed dramatically.
There are a number of different proposals being reviewed and edited  
that would allow out-of-source-order layout via CSS.


> To preserve backward compatibility, and its ease of specifying  
> attributes, a new kind of syntactical entity should probably just be  
> introduced that can specify sequences and hierarchies of  
> information. The content itself, which would be found in the HTML  
> code, would simply be referred to by id attributes. In the interest  
> of the XML movement and consistency with HTML, the new syntax should  
> probably be HTML-like, perhaps a subset of HTML. But then again in  
> the interest of consistency/simplicity, why limit the HTML? Just  
> make it full HTML, the only difference being the referring to of  
> information by id attribute. And what if the HTML itself contains id  
> attributes? Just allow it to refer to those too, I think..
CSS can select and style HTML elements based on the id attributes in  
the HTML.


> But this just begs for a much simpler and somewhat more generalized  
> and versatile solution: a) allow *all* HTML to convey other parts of  
> the HTML, referred to by their id attributes, and b) allow HTML to  
> include other HTML files. B) isn't so radical, since HTML can  
> already include .css, .js, and image files. We're only making it  
> more consistent here.
(B) is currently allowed via the IFRAME element. Its not perfect, but  
it sounds like what you are asking for.


> Another shortcoming, and this is really the one that bugs me most  
> often, is alignment.
>
> There's a *big* issue in CSS where all the CSS gurus yell DON'T USE  
> TABLES, not for layout purposes. Now here's the rub: people use  
> tables for a reason. It's *easy*. In HTML, and in almost every other  
> area of computer technology and life itself, simple things should be  
> able to be done simply. Doing the same things you can do with a  
> table with CSS is a real P.I.T.A. It's not at all obvious how to do  
> it (to understate the problem), it's not quick and easy, and even a  
> highly paid web front-end guru admitted to me that CSS has  
> shortcomings in this area, when I asked him if there should perhaps  
> be a CSS-equivalent to tables.
Actually it is HTML, not CSS, that tells you not to use TABLEs for non- 
tabular information, because HTML structures are supposed to be  
semantic. CSS is not semantic, it is just a way of specifying how  
things display. Thus in CSS, there is a CSS-equivalent to tables;  
'display:table-cell' is perfectly acceptable for almost any container  
element you want to apply it to. It is only called table-cell because  
it describes the display method that is most familiar to people as the  
way cells are displayed in HTML TABLEs. But it is in CSS to be applied  
generally, not just to tables.


> Is there a way to create a feature something like tables, per se,  
> for CSS?
Yes.

> I don't know, because I don't know precisely what the contention is  
> with using tables; i.e., in exactly what ways does using tables  
> prevent one from customizing layout in CSS?
Nothing. HTML want you to use TABLEs for tabular elements, so that  
meaningful markup (without regard to presentation) is preserved. CSS  
is about presentation, so we're fine if you want to take things that  
are not TABLEs and present them using the same display qualities.

> Tables provide alignment. What do they disprovide, and would this  
> same limitation apply to adding, per se, a table-like feature to  
> CSS? How would we do that anyway, on a semantic level?
You can read all about that, here:

http://www.w3.org/TR/CSS21/tables.html


> I think a more generalized/flexible solution would be to provide  
> some kind of alignment tokenization. Like you insert a token A at  
> point B, then at point C say align this edge or that edge of this  
> element with token A. Since you don't really have a place *in* HTML  
> *at* the right/bottom/etc edge of a layout element, then either  
> Token A has to specify which edge of the padding, margin or border  
> it's binding to, or Token A can simply bind to a layout element and  
> Token B would specify which edge and such of Token A to align to.
>
> It can be much simpler than that, though. You'll almost always want  
> to align a left edge with a left edge, a right edge with a right  
> edge, a border with a border, a content edge with a content edge,  
> etc. This symmetry can be the only thing allowed, or it can be  
> assumed by default allowing a simpler syntax in the most common  
> usage, probably just by leaving out extra parameters: for example,  
> you could align B's left border with "A" (implying A's left border),  
> "A/content" (implying the left edge of A's content), "A/ 
> right" (implying A's right border), or "A/right/content".
>
> There should probably be even further shortcuts: for aligning both  
> the top and bottom with another element, both the left and the  
> right, or the content, margin and border all at once. To align B's  
> top and bottom with A's top and bottom, at all three box layers, we  
> could just align "B/horiz" with "A". To align only the top and  
> bottom borders, align "B/horiz/border" with "A".
>
> Then of course, we could also use relative positioning via the  
> normal syntax to shift Element B's left or right content, margin, or  
> border left or right of A's, if we so wanted.
>
> I've decided the only way to specify tokens we need is the id  
> attribute. So A is called A because that element's id="A". This  
> simplifies things.
>
> Exactly how to specify the alignment remains in question.  
> Associating somehow "B/left/border" with "A/margin" doesn't really  
> fall into either CSS's or HTML's syntax. There are just no  
> conventions for associating two relatively arbitrary values. We  
> could just say, within B's definition, align-top-border: A/bottom,  
> but then that would combinatorily create 12 to 24 new CSS key words.  
> If CSS's syntax were a little more flexible, we could say align {top- 
> border}: A/bottom, or better, something like position: relative; top- 
> border: {align: A/bottom; whatever: 2px} (to align B's top border  
> with A's bottom border and shift it down 2 pixels).
>
> And perhaps it should be. Then we could even then do this, for  
> example:
> top-margin: {position: absolute; whatever: 100px}
> bottom-margin: {position: relative; whatever: 2px}
> Or perhaps it would be
> top-margin: {position: absolute; 100px};
> bottom-margin: {position: relative; 2px}
>
> Of course another idea would be to simply have a completely separate  
> alignment table:
> align
>   {
>   B/horiz/border: A/content;
>   C/horiz: D;
>   }
> That syntax would have to exist alongside one of the other  
> formulations if at all, though, because it allows no cascading  
> definitions, it's not object/class-oriented, and it can't be done in- 
> line.
>
> This idea so far can't do everything tables do. It can't size a  
> bunch of cells (divs) according to the widest or highest automatic  
> size. Do we *really* need to do that for content layout, though?  
> (Actually, i think we do.) And what if we wanted to align two or  
> more left or top margins where they would naturally go if it were  
> one long margin? So in these cases we're not specifically aligning A  
> after B, nor B after A, but we want those margins all in the same  
> alignment class. What could we do? Probably the best solution is  
> just to align them to an arbitrary common name, the same way in  
> which we would otherwise use an id. This name would never be  
> followed by /top, /horiz/content, etc., though, because that would  
> be meaningless.
>
> *Now* our alignment can do everything tables can do (I think?).
>
> But this behavior should not be an automatic fall-back when no  
> object happens to have the given name as its id, because it's doing  
> a rather different thing. But instead of inventing new key words to  
> align this way, we probably should just precede the name with a  
> special symbol, like a %.
> <div style="align-top: %hitop; align-bottom: %hibot; float:left">
>   This div's<br/>
>   height adjusts<br/>
>   to the height<br/>
>   of its text.
> </div>
> <div style="align-top: %hitop; float:left">
>   This div is smaller.
> </div>
> <div style="align-top: %hitop; align-bottom: %hibot; float:left>
>   This div goes down just as far as the first div does.
> </div>
> That was just an example to summarize and to show how simple it can  
> all be, but it also raises a minor issue I hadn't thought of: how  
> can we do a "horiz" or "vertical" align (implying left & right or  
> top & bottom) with a %-preceded name? Well I can't think of a sound  
> and consistent way, so we may have to do it just as coded above. We  
> *could* just have the right or bottom margin be a second value  
> that's used only for "horiz" or "vertical" alignments, while  
> anything else referring to that name simply uses the top or the left  
> value, and if only *one* element does a horiz or vertical align with  
> it, but other elements do single aligns, then said element would  
> only align its left or its top side. But that's if CSS has a  
> "tolerant" coding philosophy, which I know browsers do but I don't  
> know if the w3c does.
>
Received on Monday, 6 April 2009 16:12:59 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Tuesday, 22 May 2012 03:46:58 GMT