SitePoint Sponsor

User Tag List

Results 1 to 14 of 14
  1. #1
    SitePoint Member
    Join Date
    Aug 2012
    Location
    Dublin, Ireland
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question responsive layout, variable-dimension CSS table?

    I'm working on a responsive layout that displays some <div> boxes, ungrouped in the source, as part of a rectangular grid:


    Each of the boxes on this front page has this HTML structure:
    Code HTML4Strict:
    <div class="control">
    <div class="controlContent">
    <a>SOME VARIABLE-HEIGHT CONTENT including an image which might float</a>
    </div>
    </div>
    The control divs assign the boxes percentage widths to at first the whole, then 1/2 or 1/3 the screen width, so they double & triple up into rows as the screen size is increased. The controlContent divs assign properties like padding, margin, background, border-radius, etc.

    I have imagined this as a linear flow of content (which will be read by screenreaders in source order), to be displayed via CSS like a table. I know CSS2.1 allows elements to be assigned properties like:
    Code CSS:
    display: table;
    display: table-row;
    display: table-cell;
    My main problem: I have assigned display: table-cell to these elements (via the controlContent div) which prevents margin collapse inside the content but does not provide a uniform height to the cell-like divs. I need a way for all siblings on the same row to have matching height.

    The smaller cells have gaps below them where the gradient background only covers the box height of the cell. (Worse, the text after this array of cells sometimes fills into these gaps: another problem that could be fixed with presentation markup, though one which will probably go away when the first problem is fixed.)

    I think I understand the basics of the problem: each <div> which I have told to behave like a table cell has nothing to match its height to, since I have no way of grouping elements into a containing <div> to which I can assign the display: table-row property, since this grouping changes according to CSS media queries.

    In my reading about the problem I've heard of "anonymous table boxes" and "anonymous table rows" being created but don't know how to use them in this case. Since I'm using the CSS :nth-child() selectors to clear the floating boxes at the end of each row, I'd hoped I could use these selectors to establish a new table row at every such point... but how?

    I'm not married to any particular solution. I'd just like to know the best-practice way of doing this. I'm hoping to find a solution that doesn't involve presentation markup, especially considering that a general solution should provide a responsive variable-dimension table for any number of boxes, not just a small, easily factorable number like 6.

    Looking forward to your input & hoping I have missed something simple and straightforward.

  2. #2
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,175
    Mentioned
    454 Post(s)
    Tagged
    8 Thread(s)
    Hi rphair. Welcome to the forums.

    Display-table sounds like the best bet, though it's tough if you can't wrap the rows in divs. One thing you could try is

    Code:
    .control {
      display: inline-block;
      vertical-align: top;
    }
    It will align the boxes nicely, but not equalize their heights. You could set a min-height on them to help with this. For example:

    Code:
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
    
    <meta charset="utf-8">
    
    <title>Experiment</title>
    	
    <style media="all">
    .wrap {width: 900px; margin: 0 auto;}
    .wrap div {width: 30%; display: inline-block; background: yellow; vertical-align: top; min-height: 200px;}
    .wrap div + div {background: green;}
    .wrap div + div + div {background: orange;}
    .wrap div + div + div + div {background: red;}
    .wrap div + div + div + div + div {background: blue;}
    .wrap div + div + div + div + div + div {background: violet;}
    </style>
    	
    </head>
    
    <body>
    
    <div class="wrap">
    	<div>
    		<p>This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. </p>
    	</div>
    	
    	<div>
    		<p>This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. . </p>
    	</div>
    	
    	<div>
    		<p>This is text. This is text. This is text. </p>
    	</div>
    	
    	<div>
    		<p>This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. </p>
    	</div>
    	
    	<div>
    		<p>This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. This is text. </p>
    	</div>
    	
    	<div>
    		<p>This is text. This is text. This is text. This is text. This is text. </p>
    	</div>
    </div>
    
    </body>
    
    </html>
    We do have some experts here who probably have a real solution for this: @Paul O'B and @Rayzur .

  3. #3
    SitePoint Member
    Join Date
    Aug 2012
    Location
    Dublin, Ireland
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thanks for the suggestion, Ralph; I can't follow it in this case because:
    1) the layout is responsive and the typical box heights may vary substantially depending upon screen width
    2) the site itself is a CMS and the client will be free to change the box content, possibly going beyond the size boundaries that I have assumed.

    I'd still like to find a general solution for this & look forward to what your mates would think. I certainly can learn from such expertise. For now I'm going to apply rounded corners to the boxes and separate them since I think it will be fine for this layout, just having the top edges line up.

    But I'm also thinking of mobile apps in the future where one might want to tile a box with responsively sized active areas, all equally-sized. It would be wonderful to have a standards-compliant way of doing that.

  4. #4
    SitePoint Member
    Join Date
    Aug 2012
    Location
    Dublin, Ireland
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    there is also some related discussion on this page, my posting of the same problem... css table, varying dimensions

  5. #5
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,355
    Mentioned
    179 Post(s)
    Tagged
    6 Thread(s)
    Hi,

    You can't really do it with css (yet) although flexbox in css3 may be useful when it is finalised. The display:table wont work as it only works for rows and not wrapping cells. In the end you may need to add a little jquery to equal the heights out.

    You can make it appear to work like this but is very contrived.

    Code:
    <!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">
    .outer {
    	width:70%;
    	margin:auto;
    	list-style:none;
    	position:relative;
    	overflow:hidden
    }
    .outer li {
    	width:24%;
    	margin:5px 1% 5px 0;
    	float:left;
    	position:relative;
    	border-top:1px solid #fff;
    }
    .outer li:nth-of-type(4n+1) { clear:left; }
    .outer li:before {
    	content:"";
    	position:absolute;
    	display:block;
    	width:100%;
    	background:blue;
    	height:999em;
    	border-top:1px solid #fff
    }
    .box {
    	position:relative;
    	z-index:2;
    	padding:10px;
    }
    .outer li:hover:before { background:red }
     @media only screen and (max-width: 920px) {
    .outer li { width:32% }
    .outer li:nth-of-type(4n+1) { clear:none; }
    .outer li:nth-of-type(3n+1) { clear:left; }
    }
     @media only screen and (max-width: 620px) {
    .outer li { width:48% }
    .outer li:nth-of-type(4n+1) { clear:none; }
    .outer li:nth-of-type(3n+1) { clear:none; }
    .outer li:nth-of-type(2n+1) { clear:left; }
    }
    </style>
    </head>
    
    <body>
    <ul class="outer">
    		<li>
    				<div class="box">test</div>
    		</li>
    		<li>
    				<div class="box">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">test</div>
    		</li>
    		<li>
    				<div class="box">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">test</div>
    		</li>
    		<li>
    				<div class="box">test</div>
    		</li>
    		<li>
    				<div class="box">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">test</div>
    		</li>
    		<li>
    				<div class="box">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">test</div>
    		</li>
    		<li>
    				<div class="box">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">test</div>
    		</li>
    		<li>
    				<div class="box">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">test</div>
    		</li>
    		<li>
    				<div class="box">test</div>
    		</li>
    		<li>
    				<div class="box">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">test</div>
    		</li>
    		<li>
    				<div class="box">test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    </ul>
    </body>
    </html>

  6. #6
    SitePoint Member
    Join Date
    Aug 2012
    Location
    Dublin, Ireland
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    dear Paul: thanks for checking in. That's a really interesting approach & I appreciate the thought & presentation. I will definitely keep it on hand, though the layout currently calls for top-to-bottom CSS gradients in the cells... if the total height of the row is 999em then that would make the displayed portion of the gradient almost imperceptible (?).

    From an artistic point of view, after I tentatively decided to live with the empty space: with variably sized elements, extra space has to exist no matter what, and who's to say whether it looks better inside or outside the cell? Anyway I've added finishing CSS code to my simpler layout and the result is back on the original site, and I think I'm happy with it. Maybe it's even better this way than with a densely featured layout.

    Thanks to the contributors & hope to see you again soon. /robert

  7. #7
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,355
    Mentioned
    179 Post(s)
    Tagged
    6 Thread(s)
    Maybe it's even better this way than with a densely featured layout.
    Looks good to me

    Yes you are correct and with my demo you couldn't use a gradient to full effect so is not a viable solution but is too contrived anyway.

    I had a play around with it and just for fun and came up with something that looks exactly like you wanted (in Firefox not chrome) but is not usable as it removes elements to create the effect.

    However it does show what I think you were basically after.

    Code:
    <!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">
    .outer {
    	width:70%;
    	margin:auto;
    	list-style:none;
    	position:relative;
    	border-spacing:5px;
    }
    .outer li {
    	width:25%;
    	margin:0;
    	position:relative;
    	background: #051b00;
    	background: -webkit-gradient(linear, 0 0, 0 100%, from(#093700), to(#000000));
    	background: -webkit-linear-gradient(top, #093700, #000000);
    	background: -moz-linear-gradient(top, #093700, #000000);
    	background: -ms-linear-gradient(top, #093700, #000000);
    	background: -o-linear-gradient(top, #093700, #000000);
    	background: linear-gradient(top, #093700, #000000);
    	border-radius: 10px;
    	box-shadow: 0 0 5px black;
    	display:table-cell;
    	border-spacing:5px;
    	color:#fff;
    }
    .outer li a, .outer li a:visited{color:#fff}
    .outer li:nth-of-type(5n) {
    	display:block;
    	height:0;
    	width:0;
    	overflow:hidden
    }
    .box {
    	position:relative;
    	z-index:2;
    	padding:10px;
    }
    .outer li:hover:before { background:red }
     @media only screen and (max-width: 920px) {
    .outer li { width:33.33% }
    .outer li:nth-of-type(5n) {
    	display:table-cell;
    	height:auto;
    	width:auto
    }
    .outer li:nth-of-type(4n) {
    	display:block;
    	height:0;
    	width:0;
    	overflow:hidden
    }
    }
     @media only screen and (max-width: 620px) {
    .outer li { width:50% }
    .outer li:nth-of-type(5n) {
    	display:table-cell;
    	height:auto;
    	width:auto
    }
    .outer li:nth-of-type(4n) {
    	display:table-cell;
    	height:auto;
    	width:50%
    }
    .outer li:nth-of-type(3n) {
    	display:block;
    	height:0;
    	width:0;
    	overflow:hidden
    }
    }
    </style>
    </head>
    
    <body>
    <ul class="outer">
    		<li>
    				<div class="box">1 <a href="#test">test</a></div>
    		</li>
    		<li>
    				<div class="box">2 test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">3 test</div>
    		</li>
    		<li>
    				<div class="box">4  A test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">5 test</div>
    		</li>
    		<li>
    				<div class="box">6 test</div>
    		</li>
    		<li>
    				<div class="box">7 test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div id="test" class="box">8 test</div>
    		</li>
    		<li>
    				<div class="box">9 test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">10 test</div>
    		</li>
    		<li>
    				<div class="box">11 test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">12 test</div>
    		</li>
    		<li>
    				<div class="box">13 test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">14 test</div>
    		</li>
    		<li>
    				<div class="box">15 test</div>
    		</li>
    		<li>
    				<div class="box">16 test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    		<li>
    				<div class="box">17 test</div>
    		</li>
    		<li>
    				<div class="box">18 test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test </div>
    		</li>
    </ul>
    </body>
    </html>
    The above demo is just for fun and not meant to be used

  8. #8
    SitePoint Mentor bronze trophy
    ronpat's Avatar
    Join Date
    Jun 2012
    Location
    NJ, USA
    Posts
    2,507
    Mentioned
    61 Post(s)
    Tagged
    2 Thread(s)
    Is this too corny?

    Consider the ultimate of simplicity... at a price, of course.

    Construct at least 2 basic css tables: one with 2 rows of 3 columns, one with 3 rows of 2 columns.
    Assign the gradient to the background of the table-cells.
    Position header, image, and text within the cells as desired.

    Preset the tables to display:none;

    Allow the media query to determine which one to set to display:table;

    Content would have to be redundant across the tables, but the css would be much easier and would work smoothly today. This of it as faux responsive.

    Sounds plausible.

    Paul, are you secretly from Hogwarts?

  9. #9
    SitePoint Mentor bronze trophy
    ronpat's Avatar
    Join Date
    Jun 2012
    Location
    NJ, USA
    Posts
    2,507
    Mentioned
    61 Post(s)
    Tagged
    2 Thread(s)
    Is this too corny?
    Kinda thought my previous post might be a moaner.

    From Ralph and dresden_phoenix's discussion in the "adding multiple classes and id's" thread this evening, I see that I have a bit to learn about serving up content.

    If there is a silver lining to the hide-and-show-tables thought it's that I made it work; and insodoing, used media query code successfully for the first time <happy>.

    Living and learning.

  10. #10
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,175
    Mentioned
    454 Post(s)
    Tagged
    8 Thread(s)
    Quote Originally Posted by ronpat View Post
    Living and learning.
    I haven't had a chance to look closely at your suggestion, but keep experimenting! Your contributions here are great, ronpat, so keep it up.

    Could you post the code that you got working? I'd love to see it.

  11. #11
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,355
    Mentioned
    179 Post(s)
    Tagged
    6 Thread(s)
    Quote Originally Posted by ronpat View Post
    Is this too corny?
    Not too corny but maybe too expensive

    As you said you would need to have redundant tables full of data for every iteration which in my example would be 3 sets of duplicate tables for 2,3 and 4 columns. You'd also incur overheads in that you'd have to program it so that your same data is inserted into three different tables in 3 different manners. Having done all that then yes it would work as you simply show whichever layout you wanted at the suitable width

    The original premise was to take a single sequence of elements and have then auto adjust into columns as required of course .

  12. #12
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,355
    Mentioned
    179 Post(s)
    Tagged
    6 Thread(s)
    Here's a working example that works in Firefox and IE9 but Chrome isn't obeying the media query properly and needs to be refreshed when the media query kicks in (I've seen this happen before ion Chrome on other responsive layouts).

    It uses the same method as my other example but instead of hiding actual data it starts with an extra element in the sequences to start with which is then hidden and revealed to trigger the rows. As with Ronpat's example it uses redundant elements but the structure is still a sequence of elements that could easily be programmed.

    Again this is only for fun but interesting to see what can be achieved. If it wasn't for chrome/safari this could almost be viable

    (As I mentioned earlier it looks like flexbox may be able to do this when it is completed)

  13. #13
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,175
    Mentioned
    454 Post(s)
    Tagged
    8 Thread(s)
    Quote Originally Posted by Paul O'B View Post
    Chrome isn't obeying the media query properly and needs to be refreshed when the media query kicks in (I've seen this happen before ion Chrome on other responsive layouts).
    That's weird. I've never seen Chrome do that before. Is it anything in particular that seems to make this happen in Chrome?

  14. #14
    The CSS Clinic is open silver trophybronze trophy
    Paul O'B's Avatar
    Join Date
    Jan 2003
    Location
    Hampshire UK
    Posts
    40,355
    Mentioned
    179 Post(s)
    Tagged
    6 Thread(s)
    Quote Originally Posted by ralph.m View Post
    That's weird. I've never seen Chrome do that before. Is it anything in particular that seems to make this happen in Chrome?
    I can't remember what the problem was before but I've seen it twice now. It may be to do with the display:table properties where the browser needs to create anonymous table rows etc. and Chrome seems to only do this on refresh and not when the media query is triggered.


Tags for this Thread

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
  •