homepage Welcome to WebmasterWorld Guest from 54.211.68.132
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / CSS
Forum Library, Charter, Moderators: not2easy

CSS Forum

    
Why doesn't CSS have basic vertical align?
woop01

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4482037 posted 8:14 pm on Aug 5, 2012 (gmt 0)

Just wondering.

Why doesn't CSS have a simple way to vertically align within a div similar to the way valign works in a table?

(vertical-align isn't what I'm talking about)

I realize there are slightly convoluted hacks to get around the lack of function but for the life of me I can't figure out why such a basic layout function would be left out.

 

SevenCubed

WebmasterWorld Senior Member



 
Msg#: 4482037 posted 9:03 pm on Aug 5, 2012 (gmt 0)

I'm not sure if I'm understanding your question properly but as simple a way as I know to vertical align is by using margins such as:

<html>
<body>
<div style="margin:300 0 0;">
<p>This is vertical alignment</p>
</div>
</body>
</html>

woop01

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4482037 posted 9:40 pm on Aug 5, 2012 (gmt 0)

I understand that there are numerous work arounds, I'm asking why the ability to simply say something like "valign: middle;" doesn't exist.

It's something that's obviously relevant that it doesn't make sense that it's not there.

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4482037 posted 11:22 pm on Aug 5, 2012 (gmt 0)

You have to use three layers.

Here I've called them div, div and p, but I first worked out the code in a page where the nesting was div, p and img. Note that the alignments in the CSS are the exact opposite of what you would expect. Using "top" and "bottom" alone instead of "text-top" and "text-bottom" didn't work in Opera (it interpreted both as "bottom", and took "middle" as "top"). It doesn't work in MSIE5; don't know about newer versions.

The borders, padding and margins are of course for illustrative purposes.

CSS:
div.holder {padding: 1em; margin: 1em; border: 1px dotted black;}

div.holder div {display: inline-block; padding: 0; margin: 0; border: 1px solid black;}
div.holder p {display: inline-block; padding: 1em; margin: 1em;}

div.holder div p.linedown {vertical-align: text-top; border: 1px solid red;}
div.holder div p.linemiddle {vertical-align: middle; border: 1px solid #090;}
div.holder div p.lineup {vertical-align: text-bottom; border: 1px solid blue;}

HTML:
<div class = "holder">
<div>
<p class = "lineup">
#*$!</p>
</div>
<div>
<p class = "linemiddle">
#*$!</p>
</div>
<div>
<p class = "linedown">
#*$!</p>
</div>
</div>

Edit: For heaven's sakes, Forums, I wasn't swearing. I just typed ex, ex, ex so the inmost boxes would have some content. Sheesh.

woop01

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4482037 posted 12:15 am on Aug 6, 2012 (gmt 0)

Yup, just another example of how poorly such a basic layout idea is handled in CSS.

Does anybody know WHY it was left out?

SevenCubed

WebmasterWorld Senior Member



 
Msg#: 4482037 posted 12:20 am on Aug 6, 2012 (gmt 0)

It has not been left out it's just accomplished in different manners that are just as easy.

woop01

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4482037 posted 12:43 am on Aug 6, 2012 (gmt 0)

How are those methods just as easy as "valign: middle"?

Even the work around you posted has to be customized for the specific situation.

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4482037 posted 1:13 am on Aug 6, 2012 (gmt 0)

If you read the w3c specs closely you'll see that it's the table cells that are really anomalous. Everywhere else, "vertical-align" has an entirely different definition. A further complication is that CSS has to allow for vertical scripts. Changes in their alignment will be expressed as "left" or "right" rather than "top" or "bottom".

CSS3: [dev.w3.org...]
The alignment of text and inline-level content is defined in [CSS3TEXT] and [[CSS3LINEBOX]].

leading to

CSS3-text [w3.org]
and
CSS3-line [w3.org]

Anyway, not much point to asking retroactively why something wasn't done ten years ago. The question is what's happening now.

woop01

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4482037 posted 2:19 am on Aug 6, 2012 (gmt 0)

I'm not a designer or CSS expert, could you put that into a bit more straight forward explanation?

Honest, I'm not trying to argue, I'm actually interested in the reasoning behind not putting what seems to me to be such a basic design functionality into CSS.

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4482037 posted 4:01 am on Aug 6, 2012 (gmt 0)

It really goes back to HTML. There can be HTML without CSS but there can be no CSS without HTML.

A web page is essentially a scroll. The width of an element is determined by the width of the viewport. (Your browser window, or the size of your cell phone, or whatever it may be.) The height is determined by the content. So in most circumstances, "vertical-align" for a block-level element would be meaningless. It is already just as tall or short as it needs to be. Vertical alignment is for inline things, like footnote tags or subscripts or fancy text.

Table cells are the obvious exception, because there will normally be two or more side by side. The tallest cell in each row forces all the others to be the same height. So that's where you get leftover vertical space and you have to decide where to put it: above or below the text. The default vertical alignment for a table cell is "center". I don't know about you, but that's generally the last way I'd want it.

Other than in tables, the only time vertical alignment is meaningful is when you've got pieces arranged side by side in an "inline-block" configuration. Technically this option has been around for a long time-- that is, long by www standards ;) --but it's still a pretty newfangled idea. I think most people are scared to change the "display:" option in CSS. Stick with block vs. inline, whatever the default is, and there's a lot less room for calamity.

Paul_o_b

10+ Year Member



 
Msg#: 4482037 posted 7:57 am on Aug 6, 2012 (gmt 0)

CSS2 does have a way to vertical align elements and always has. It's just that IE didn't support it until IE8 so is not a failing of CSS but a failing of a specific browser.

It's pretty simple for everyone apart from ie7 and under and you just use the display:table-cell properties.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style type="text/css">
div {
display:table-cell;
width:400px;
height:400px;
border:1px solid #000;
margin:auto;
vertical-align:middle;
text-align:center;
}
p {
display:inline-block;
width:200px;
height:200px;
line-height:200px;/* one line of text only*/
background:red;
margin:auto;
}
</style>
</head>

<body>
<div>
<p>vertically centred</p>
</div>
</body>
</html>


alt131

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4482037 posted 7:09 pm on Aug 6, 2012 (gmt 0)

Why doesn't CSS have a simple way to vertically align within a div ...

(vertical-align isn't what I'm talking about)

... I can't figure out why such a basic layout function would be left out.


Thanks for asking an interesting question woop01, and great discussion everyone. I haven't kept up with the evolution of this property, but I'd speculate the reason lies in the origins of html/css.

Recall the origin of HTML was sharing primarily text documents, and css focussed on styling the content - which to start was mostly text. Aligning vertically within a block element is more about using style to lay out elements. Take a quick scan of the css1 [w3.org] recommendation - there's very little about "lay out", and that's reflected in the concept of 5.4.4 'vertical-align' [w3.org] being dealt with in the "Text Properties" sub-section:

Also recall that while css2.1 contains more tools for laying out elements, it is still old and retains the original focus. Hence vertical align survives as a tool for dealing with text/line alignment 10.8.1 Leading and half-leading [w3.org].

To me, the issue isn't that a way to align elements vertically was "left out".
To me the issue is that coders suddenly expected css to provide a way to lay out page elements, even though it was designed to style the content. That doesn't make css deficient. However, those expectations did mean re-thinking the function of css - one of the reasons it has taken so long to get any "progress" on newer versions.

templatesofty



 
Msg#: 4482037 posted 5:00 am on Aug 7, 2012 (gmt 0)

If you recognize the height of your containing div, and therefore the height of your inner targeted div, or, if you the height of your inner div doesn\'t matter, then vertical positioning is easy. However, if you\'re vertically centering something that\'s variable, like text, vertical centering is a lot of complicated and need hacks.

[edited by: incrediBILL at 7:42 am (utc) on Aug 7, 2012]
[edit reason] removed URL, no sig links [/edit]

woop01

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4482037 posted 8:22 pm on Aug 7, 2012 (gmt 0)

That's what we're doing, dynamic stuff. It'd sure be nice to have a one line tag to do it.

Paul_o_b

10+ Year Member



 
Msg#: 4482037 posted 9:00 pm on Aug 7, 2012 (gmt 0)

The example I gave above handles variable height and is effectively just one line of html.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style type="text/css">
div {
display:table-cell;
width:100%;
height:400px;
border:1px solid #000;
margin:auto;
vertical-align:middle;
text-align:center;
}
p {
display:inline-block;
width:50%;
background:red;
margin:auto;
}
</style>
</head>

<body>
<div>
<p>Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text </p>
</div>
</body>
</html>


It will work in IE8+ with no problems.

woop01

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4482037 posted 10:02 pm on Aug 7, 2012 (gmt 0)

As mentioned above, I realize it can be accomplished.

There are numerous ways your specific example 'breaks' once you try to go beyond that situation and I'm not sure how it's essentially 'one line' when it needs both the table-cell hack and then verticle-align.

alt131

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4482037 posted 10:24 pm on Aug 7, 2012 (gmt 0)

We need to avoid forking the thread into "how to" answers, but Paul, I so enjoy the way you explain the finer details of position (in the broadest meaning of that word). If you have time, feel free to indulge us briefly :)

woop01, we're not in css to argue either. We survived NN4 - there are bigger battles to fight than each other. So I'm not being argumentative when I say that I don't believe the use of a legitimate property/value pair such as display:table-cell can really be called a "hack".

Returning to the main thrust of this thread, have you looked at box alignment [w3.org]? The intro parallels your opening question:
However, except in table cells, vertical alignment was not possible. As CSS3 adds further capabilities, the ability to align boxes in various dimensions becomes more critical. This module attempts to create a cohesive and common box alignment model to share among all of CSS.

Combine that with the flex-box [dev.w3.org] concept and we are well on the way to having more tools that deal with this particular lay out issue.

Paul_o_b

10+ Year Member



 
Msg#: 4482037 posted 8:39 am on Aug 8, 2012 (gmt 0)

Hi,

If we return to the original question:


Why doesn't CSS have a simple way to vertically align within a div similar to the way valign works in a table?


Then the answer I gave above does exactly that although it may not be quite as a simple but is by no means difficult. It behaves in the same way that it would in a table because it is mimicking the table structure as it was designed to do.

When you use display:table-cell the browser in fact automatically creates the table wrapper thus saving on equivalent html had you used a table in that situation.

You will have to explain where that method breaks compared to the same method in a table as I can't see an obvious difference?

The display:table properties don't cover all the aspects of tables (colspan, rowspan etc) but for vertical alignment and equal columns they work in much the same way.

It is effectively one line of html and less html than would be needed for the table counterpart as mentioned above!

The css is of course only effectively two lines : "vertical-align:middle and display:table-cell". The rest of the css is for the structure and display and can't be seen as part of the solution.

As alt131 said it is not in any sense a hack and is doing the exact job it was designed to do. I don't really understand this misconception. The display:table properties were never meant to be for tabular data but as a way of providing some of the features of tables such as vertical-align and equal columns.

However, after saying all that I do understand where you are coming from. It would indeed have been useful if margin:auto would vertically center an element inside its container in the same way that it centers horizontally but the problem is that height is a complicated subject. An auto height element has no height so the element cannot really be vertically centred, however once you give the element a height then it cannot grow unlike table-cells that treat height as a minimum. This means you'd be looking for specific cases of when an element has a fixed height and then saying please vertically center the child div. I'm sure this could have been overcome with a bit of thought but CSS was such a drastic change from what went before that there were bound to be a few holes that needed to be plugged. We are indeed still waiting for the perfect layout tool but CSS3 shows much promise.

As alt31 points out css3 does address these issues in more details but as to your original question then the display:table-cell properties from css2 do already address this issue.

It may be helpful if you have a specific scenario in mind and we can discuss the options available.

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4482037 posted 11:00 am on Aug 8, 2012 (gmt 0)

I don't think he was ever asking "How do I...?" That was my initial mistake. He's asking, philosophically, "Why...?"

Paul_o_b

10+ Year Member



 
Msg#: 4482037 posted 12:55 pm on Aug 8, 2012 (gmt 0)


He's asking, philosophically, "Why...?"


My example was not a "how do I" but more of a "yes you can". The point I was making was that it was not left out as such and that there were means available since css2 to do it :).

I agree that perhaps there could have been a more specific rule invented for this but the beauty of CSS is that there is nearly always a way to do something without having specific pre-built properties just built for one purpose.

There are many things I would like to see added to CSS but things that can be done already are not on my wish-list :)

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4482037 posted 9:56 pm on Aug 8, 2012 (gmt 0)

Everything can be done in some way-- but there are limits to clunky workarounds.

For example, I have at different times coded sidenotes in three entirely different ways. (Using floats, absolute positioning or-- yes-- tables.) But none of them is a really good substitute for a built-in "side footnote" option in HTML. And I can fake up an imitation of a run-in header-- but the now-you-see-it-now-you-don't* CSS "display: run-in" is cleaner and more intuitive.


* Somewhere there has got to be a list of properties that were left out of 2.1 but mercifully restored in 3.

lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4482037 posted 5:17 am on Aug 20, 2012 (gmt 0)

Uhm. Ahem. I have to come slinking back here because I have just figured out that the code I posted early in this thread doesn't do what I thought it did. Mea culpa. It only works because

#1 I have all three kinds of vertical alignment (top, middle, bottom) in the same block
and
#2 the sample bit of text only take up one line

"vertical-align: top" (or "bottom" or "middle") don't refer to the overall alignment of the text block. They mean, in practice:
"top" = align the top of your text snippet with the overall baseline
"bottom" = align the bottom of your text et cetera (this is basically the default)
"middle" = align the vertical middle of your text with the overall baseline

Think lined writing paper. You can write along the top of the line, or you can hang the tops of your letters under the line like laundry (or, seriously, like devanagari-based scripts), or you can splat your writing right over the line.

This explains why the words "top" and "bottom" seemed to do the opposite of what I thought they did.

In order for the posted code to work, you have to use very short bits of text and there have to be at least two different alignments within the block. You can cheat by marking one of them as "visibility: hidden". But, well, there is a time and a place for cheating. And there is a time and a place for being entirely on the wrong track.

Dang it all.

Conversely, "display: table-cell" flatly refuses to do what I want when it comes to left or right alignment :( I can probably make it behave by nesting at least three divs, each with a slightly different set of styles.

Paul_o_b

10+ Year Member



 
Msg#: 4482037 posted 8:47 am on Aug 20, 2012 (gmt 0)


"bottom" = align the bottom of your text et cetera (this is basically the default)


Not to split hairs but baseline is the default not bottom :)


Conversely, "display: table-cell" flatly refuses to do what I want when it comes to left or right alignment :


You'll have to give an example as simply using text-align:left or right will align the block in my example (but I guess that wasn't what you meant):


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style type="text/css">
div {
display:table-cell;
width:100%;
height:400px;
border:1px solid #000;
margin:auto;
vertical-align:middle;
text-align:right;
}
p {
display:inline-block;
width:50%;
background:red;
margin:auto;
}
</style>
</head>

<body>
<div>
<p>Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text Lorem ipsum text </p>
</div>
</body>
</html>


lucy24

WebmasterWorld Senior Member lucy24 us a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month



 
Msg#: 4482037 posted 9:45 am on Aug 20, 2012 (gmt 0)

Aha. I was nesting in the wrong order. If I now apply a "text-align: left" to the paragraph, its internal text comes out left-aligned while the paragraph remains nicely on the right side of the page. Even works in Chrome, which may have replaced MSIE as "If it works in {--}, it will work in anything." ;)

I've got a vague notion it doesn't work in MSIE <= 7. Well, to heck with 'em. I checked MSIE 5. It gets it wrong in a quite hilarious way by putting the paragraph below the div. But hey, it's on the right edge of the screen AND the text is left-aligned!

The word "background" by itself makes me think of old-fashioned, pre-CSS HTML. I've always said "background-color" when that's the only property I'm setting. Although I seriously doubt any modern browser would take a measurable amount of time figuring out what was meant. ("If MSIE 5 can get it right...")

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / CSS
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved