SitePoint Sponsor

User Tag List

Results 1 to 13 of 13
  1. #1
    SitePoint Evangelist winterheat's Avatar
    Join Date
    Aug 2007
    Posts
    508
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    centering a variable width table in page complicated without using <center>, by CSS

    i want to make a page with nothing but a center column of content.

    this center column should have text left-aligned... and cannot have a specific width (it shrink wrapped by using a table with a border).

    so i found that to center this middle column with table, a <center> tag is very easy to do.

    but what if i don't use a <center> tag? since i can't specify a width for this column, i can't use left and right margin as auto to center it.

    if i also center the text inside this middle column, i can just use text-align: center... but since the text needs to be left-aligned inside this middle column, i can't use text-align.

    is there a good CSS method if i don't use <center> ? I think the need to specify a width and use auto left and right margin is not easy to center something that can shrink wrap some content. thanks.

    (i actually have some javascript code to size the text (like a poem) inside the middle column to small, medium, or large, and i don't want to use fixed width for the middle column but want it to shrink wrap to the text and also have a border).

  2. #2
    SitePoint Addict Poiesis01's Avatar
    Join Date
    Jun 2007
    Location
    Cape Town
    Posts
    233
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That sounds quite complicated. Have you tried
    Code:
    body {margin: 0 auto;}
    ?

    The rest of the problem can be accomplished easier using <div> rather than <table> as each <div> can have it's own text-align.

  3. #3
    SitePoint Evangelist winterheat's Avatar
    Join Date
    Aug 2007
    Posts
    508
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Poiesis01 View Post
    That sounds quite complicated. Have you tried
    Code:
    body {margin: 0 auto;}
    ?

    The rest of the problem can be accomplished easier using <div> rather than <table> as each <div> can have it's own text-align.
    i just tried adding
    body {margin: 0 auto;}

    but it is no use... (isn't a width needed for the margin left and right being auto to work as horizontal centering?)

    still, the simplest solution is to add a <center> tag just before the <table>

    any solution... and what about, can we style a <div> so that it act as a <center> tag?

    for example, should a <div style="padding: 0 auto"></div> suppose to center the content inside the div? i just tried padding: 0 200px and it created horizontal padding, but padding: 0 auto, won't center the content inside...

  4. #4
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,555
    Mentioned
    183 Post(s)
    Tagged
    6 Thread(s)
    Just add margin:auto to the table.


    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Untitled Document</title>
    <style type="text/css">
    .test {
        margin:auto;
        border:1px solid #000
    }
    .test td{padding:5px;}
    </style>
    </head>
    <body>
    <table class="test" cellspacing="0" cellpadding="0">
        <tr>
            <td><p>One line of a poem<br />
                    This is the second line of the poem<br />
                    third line<br>
                    Fourth line of a poem that's just a bit longer</p></td>
        </tr>
    </table>
    </body>
    </html>

  5. #5
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,555
    Mentioned
    183 Post(s)
    Tagged
    6 Thread(s)
    Or a css version:
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Centre an element of no specified width.</title>
    <style type="text/css">
    .wrap {
        width:100&#37;;
        overflow:hidden;/* ie7 fix*/
        position:relative;
    }
    .outer {
        position:relative;
        left:50%;
        float:left;
        clear:both;
        margin:10px 0;
        text-align:left;
    }
    .inner {
        border:1px solid #000;
        padding:10px 20px;
        position:relative;
        left:-50%;
        text-align:left;
    }
    </style>
    </head>
    <body>
    <div class="wrap">
        <div class="outer">
            <div class="inner">
                <p> This is some text of undefined width: </p>
                <p>This is more text </p>
                <p>This assumes text doesn't need to wrap</p>
                <p>otherwise it will stretch full width</p>
            </div>
        </div>
    </div>
    </body>
    </html>

  6. #6
    SitePoint Evangelist winterheat's Avatar
    Join Date
    Aug 2007
    Posts
    508
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Paul O'B View Post
    Just add margin:auto to the table.

    it does work well! is there a rule that says, for table, a width is not required to be specified and the auto margin for left and right will center it?
    Last edited by winterheat; Apr 11, 2009 at 07:26. Reason: oops - sorry I edited your post in error :(

  7. #7
    SitePoint Evangelist winterheat's Avatar
    Join Date
    Aug 2007
    Posts
    508
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Paul O'B View Post
    Or a css version:
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Centre an element of no specified width.</title>
    <style type="text/css">
    .wrap {
        width:100&#37;;
        overflow:hidden;/* ie7 fix*/
        position:relative;
    }
    .outer {
        position:relative;
        left:50%;
        float:left;
        clear:both;
        margin:10px 0;
        text-align:left;
    }
    .inner {
        border:1px solid #000;
        padding:10px 20px;
        position:relative;
        left:-50%;
        text-align:left;
    }
    </style>
    </head>
    <body>
    <div class="wrap">
        <div class="outer">
            <div class="inner">
                <p> This is some text of undefined width: </p>
                <p>This is more text </p>
                <p>This assumes text doesn't need to wrap</p>
                <p>otherwise it will stretch full width</p>
            </div>
        </div>
    </div>
    </body>
    </html>
    this method of having 3 divs also work well... now it has to be 3 divs huh? if the tags are "structure" of content, and CSS are styling, then supposedly, we can just use 1 <div> or 1 <p>, and we can use CSS to style that div to behave what we wanted in the original post? (supposedly). If so... will that be a shortcoming of CSS and can it be a future improvement? (that a div can be styled quite freely, such as styled into how 3 divs behave like above).

    thanks Paul. you are great.

  8. #8
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,555
    Mentioned
    183 Post(s)
    Tagged
    6 Thread(s)
    Yes the table doesn't needed a width because that's how tables have been designed and have certain special characteristics. You just need to give it auto margins and the whole element will be centred in the available space.

    You can use the text-alignment properties to align the text as you want within that element without upsetting the centring.

    this method of having 3 divs also work well... now it has to be 3 divs huh?
    Yes it needs to be that structure to work which is actually the same number of elements that a table needs (table,tr and td) so there is no saving in terms of mark up but avoids abusing tables for layout.

    The CSS display:table could be used also but doesn't work in IE7 and under.

    (Aplogies for editing your post I thought I was quoting it but must have pressed edit instead and couldn't restore it )

  9. #9
    SitePoint Evangelist winterheat's Avatar
    Join Date
    Aug 2007
    Posts
    508
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I changed the 3 divs code to

    HTML Code:
    .wrap {
        width:100&#37;;
        overflow:hidden;/* ie7 fix*/
        position:relative;
        border: 1px solid green;
    }
    .outer {
        position:relative;
        left:50%;
        float:left;
        clear:both;
        margin:10px 0;
        text-align:left;
        border: 1px dashed red; 
    }
    so as to understand it more. Wow...

    1) so the wrap div is to create a base div for the outer div to float inside, and
    2) it is floating so as to shrink-wrap the content
    3) the inner div is the content, and it also shrink wrap (for some reason), and move to 50% of the parent's width...
    4) but since the parent (outer div)'s width is the same as inner div's width,
    5) so essential, it is telling itself to move for half of its width off from the center line to the left
    6) and so, the centering of the div is achieved.

    wow, this is profound. i don't understand why the inner div is also shrink wrapping the content, as i recall only floated div and absolutely positioned div will shrink wrap... so the inner div is none of those, and should go as wide as it could? and when the inner is as wide as it could, then the outer can only shrink wrap something that already went as wide as it could?

    (by the way, will a fixed positioned div also shrink wrap? so there are 4 cases that an element can shrink wrap: floated, absolutely or fixed position, and table).

    is it true that if CSS had this:

    <div style="width:shrink-wrap; margin: 0 auto">ha<br>hello world</div>

    then the whole issue would be solved?
    Last edited by winterheat; Apr 10, 2009 at 07:13.

  10. #10
    billycundiff{float:left;} silver trophybronze trophy RyanReese's Avatar
    Join Date
    Oct 2008
    Location
    Whiteford, Maryland, United States
    Posts
    13,762
    Mentioned
    13 Post(s)
    Tagged
    0 Thread(s)
    Well you could try that.

    You have a syntaxerror

    Code:
    wrap{...}
    Always looking for web design/development work.
    http://www.CodeFundamentals.com

  11. #11
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,555
    Mentioned
    183 Post(s)
    Tagged
    6 Thread(s)
    1) so the wrap div is to create a base div for the outer div to float inside, and
    No the wrap is only needed for an IE7 bug where it shows a horizontal scrollbar on the viewport because it thinks the element is still hanging out the side. The overflow:hidden ensures that the scrollbar doesn't appear unnecessarily. If it wasn't for IE7 this element wouldn't be needed and in most cases there would be an existing wrapper you could apply the overflow to anyway.

    2) it is floating so as to shrink-wrap the content
    Yes floats, and absolutely positioned elements (which includes fixed elements) will shrink wrap theitr content,

    3) the inner div is the content, and it also shrink wrap (for some reason), and move to 50&#37; of the parent's width...
    Not quite

    The inner div is as wide as its parent which is the floated parent which is as wide as its content. Therefore the inner is as wide as the floated parent only.

    There would be issues if you tried to float more elements inside this box or gave elements haslayout because of bugs in IE where it will stretch the whole lot. This should not be an issue for text content.

    4) but since the parent (outer div)'s width is the same as inner div's width,
    5) so essential, it is telling itself to move for half of its width off from the center line to the left
    6) and so, the centering of the div is achieved.
    Position relative moves the outer element 50% of the available width of the parent (the viewport in this case). This makes the left edge sit at the 50% mark.

    Then the inner is moved back 50% which is taken as 50% of the outers width which is the content width only and thus centers the element perfectly.

    i don't understand why the inner div is also shrink wrapping the content, as i recall only floated div and absolutely positioned div will shrink wrap...
    The inner is contained within the shrukk-wrap float so is only as wide as its parent.

    <div style="width:shrink-wrap; margin: 0 auto">ha<br>hello world</div>

    then the whole issue would be solved?
    Well, the display:table methods would allow it to work anyway but a specific command may have been easier.

    We could use inline-block instead which will make it simpler.

    e.g.


    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Centre an element of no specified width.</title>
    <style type="text/css">
    .outer{
        width:100%;
        text-align:center;
    }
    .inner {
        border:1px solid #000;
        padding:10px 20px;
        position:relative;
        display:-moz-inline-box;/* ff2 and older*/
        display:inline-block;
        margin:auto;
        text-align:left;
    }
    </style>
    <!--[if lt IE 8]>
    <style type="text/css">
    .inner{display:inline}
    
    </style>
    <![endif]-->
    </head>
    <body>
    <div class="outer">
        <div class="inner">
            <p> This is some text of undefined width: </p>
            <p>This is more text </p>
            <p>This assumes text doesn't need to wrap</p>
            <p>otherwise it will stretch full width</p>
        </div>
    </div>
    </body>
    </html>
    The technique is explained here:

    http://www.search-this.com/2008/08/2...ck-in-a-block/

  12. #12
    SitePoint Evangelist winterheat's Avatar
    Join Date
    Aug 2007
    Posts
    508
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Paul, so i think using the table method is probably the simplest... it works in most modern browsers and what's more, it is more apparent to yourself and to your coworkers when they need to change or fix it? thanks.

  13. #13
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,555
    Mentioned
    183 Post(s)
    Tagged
    6 Thread(s)
    Yes sometimes the easiest solution is the one to go with


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •