joedotnot
joedotnot

Reputation: 5153

Layout with CSS (or should I give up and use tables?)

I am trying to achieve the following Layout, as per screenshot.

Layout using tables

Main features are

Using HTML-tables took me about 2 hours to generate the above screenshot, with the above features.

After stuffing around with CSS for two days, I cannot get it looking as above, my attempt at CSS and associated screenshot follow below:

<html> 
<head> 
    <title>My Layout</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style type="text/css"> 
    body{
        height:100%;
        background:beige;
    }

    #header { 
        width:100%;
        height:60px;
        text-align:center;
        background:#A7C942; 
        color:#fff;
        float:left; 
        font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
        font-size:2em;
    } 

    #leftDiv { 
        float:left; 
        width:150px;
        height:90%;
        background:aquamarine; 
    } 
    #midDiv { 
        float:left; 
        width:auto; 
        height:90%;
        background:lightsalmon; 
        display:block;
    } 
    #rightDiv { 
        float:right; 
        width:365px; 
        height:90%;
        background:green; 
        display:block;
    }


    #topRow {
        background-color:lightgoldenrodyellow;
    }

    #bottomRow {
        background-color:lightpink;
        height:200px;
    }
    </style> 
</head> 

<body> 
<div id="body"> 
    <div id="main"> 
        <div id="header">my header</div>

        <div id="leftDiv">
            <p>LEFT</p>
        </div> 

        <div id="midDiv">
            <p>MIDDLE</p>
        </div> 

        <div id="rightDiv">
            <p>RIGHT</p>
            <div id="topRow">
                TOP
            </div>
            <div id="bottomRow">
                BOTTOM
            </div>
        </div>
    </div> 
</div> 
</body> 
</html>

Screenshot with CSS: Layout using CSS

Problems with the CSS attempt are:

Therefore, I am about to unleash my solution using tables, unless some die-hard CSS fanatic comes to the rescue with a working answer:-)

Update Great answers, at the time of this update there were 4. I tried out all 4 on Firefox and Chrome, and every answer is acceptable. But i can only choose one as the accepted answer, and i will go with the one that's plain and simple using only css and absolute positioning (no flexbox nor css-tables).

Thank you muchly to @matthewelsom, @Pangloss, @Shrinivas, @Paulie_D; I am sure anyone who stumbles upon your answers will find it useful for their use case. Upvotes for everyone, your efforts are appreciated!

Upvotes: 5

Views: 303

Answers (4)

Stickers
Stickers

Reputation: 78786

Here we go the CSS table layout, adjusted the markup slightly - added a couple of <div> containers for applying the styles.

JsFiddle Demo

html, body {
    height: 100%;
    margin: 0;
}
#page, #main, #rTable {
    display: table;
    border-collapse: collapse;
    width :100%;
    height: 100%;
}
#page > div {
    display: table-row;
}
#page #hRow {
    background: lightgreen;
    text-align: center;
}
#page #mRow {
    height: 100%;
}
#main > div {
    display: table-cell;
    vertical-align: top;
}
#leftDiv {
    width: 100px;
    background: aquamarine;
}
#midDiv {
    background: lightsalmon;
}
#rightDiv {
    width: 200px;
    background: green;
}
#rTable > div {
    display: table-row;
}
#rTable #topRow {
    background: lightgoldenrodyellow;
}
#rTable #bottomRow {
    height: 100px;
    background: lightpink;
}
<div id="page">
    <div id="hRow">
        <div id="header">HEADER</div>
    </div>
    <div id="mRow">
        <div id="main">
            <div id="leftDiv">
                <p>LEFT</p>
            </div>
            <div id="midDiv">
                <p>MIDDLE</p>
            </div>
            <div id="rightDiv">
                <div id="rTable">
                    <div id="topRow">RIGHT-TOP</div>
                    <div id="bottomRow">RIGHT-BOTTOM</div>
                </div>
            </div>
        </div>
    </div>
</div>

Upvotes: 3

matthewelsom
matthewelsom

Reputation: 944

Here is a quick flex layout, very rough but you'll get the idea. You can read more about Flexbox on CSS tricks.

I have also made the design responsive so the layout will fill 100% width on screens under 480px width.

CODEPEN HERE

html, body {
  height: 100%;
  padding: 0;
  margin: 0;
}
.wrapper {
  height: 100%;
  display: flex;         /* NEW, Spec - Firefox, Chrome, Opera */
  display: -webkit-box;  /* OLD - iOS 6-, Safari 3.1-6, BB7 */
  display: -ms-flexbox;  /* TWEENER - IE 10 */
  display: -webkit-flex; /* NEW - Safari 6.1+. iOS 7.1+, BB10 */
  
  -webkit-flex-direction: column;
  flex-direction: column;
}

.wrapper > * {
   flex: 1 100%;
  -webkit-flex: 1 100%; 
}

.header {
  flex: 1;
  -webkit-flex: 1; 
  
  background: green;
  width: 100%;
  max-height: 80px;
}

.below {
  flex: 1;
  -webkit-flex: 1; 
  
  display: flex;        
  display: -webkit-box;  
  display: -ms-flexbox; 
  display: -webkit-flex;  
  
  -webkit-flex-direction: row;
  flex-direction: row;
}

.main {
  background: deepskyblue;
  flex: 3 0px;
  -webkit-flex: 3 0px;
  
  -webkit-order: 2;
  order: 2;
}

.left {
  background: yellow;
  max-width: 100px;
  flex: 1 auto;
  -webkit-flex: 1 auto;
  
  -webkit-order: 1;
  order: 1;
}

.right {
  background: hotpink;
  max-width: 300px;
  position: relative;
  
  display: flex;        
  display: -webkit-box;  
  display: -ms-flexbox; 
  display: -webkit-flex;  
  
  flex: 1 auto;
  -webkit-flex: 1 auto;
  
  -webkit-order: 3;
  order: 3;
  
  -webkit-flex-direction: column;
  flex-direction: column;
}
.top {
  background: lightpink;
  
  flex: 1 auto;
  -webkit-flex: 1 auto;
}
.bottom {
  background: salmon;
  max-height: 200px;
  width: 100%;
  
  flex: 1 auto;
  -webkit-flex: 1 auto;
}
@media screen and (max-width: 479px) {
  .below {
    -webkit-flex-direction: column;
    flex-direction: column;
  }
  .left, .right, .main {
    max-width: 100%;
    
    flex: 1;
    -webkit-flex: 1;
  }
  body, html, .wrapper {
    height: auto;
  }
}
<div class="wrapper">
  <header class="header"><h3>Header</h3><p>Fixed height 80px, 100% width</p></header>
  <div class="below">
    <article class="main">
    <h3>Flexible width Article</h3>
    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est.
      Mauris placerat eleifend leo.</p>
  </article>
    <aside class="left">
      <h3>Left</h3>
      <p>100px fixed width</p>
    </aside>
    <aside class="right">
    <div class="top">
      <h3>Right Top</h3>
      <p>Flexible Height, Fixed width 300px</p>
    </div>
    <div class="bottom">
      <h3>Right Bottom</h3>
      <p>Fixed width 300px, Fixed Height 200px</p>
    </div>
  </aside>
  </div>
</div>

Upvotes: 3

Paulie_D
Paulie_D

Reputation: 115342

Using flexbox this is actually pretty simple.

Codepen Demo

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
html,
body {
  min-height: 100%;
}
.wrapper {
  width: 80%;
  margin: auto;
  display: flex;
  flex-direction: column;
  border: 1px solid red;
  height: 100%;
}
header {
  height: 50px;
  background: green;
  text-align: center;
  line-height: 50px;
}
main {
  flex-grow: 1;
  border: 1px solid red;
  height: 100%;
  display: flex;
}
.left {
  width: 200px;
  background: lightblue;
  flex: none;
}
.center {
  flex-grow: 1;
  background: salmon;
}
.right {
  width: 300px;
  flex:none;
  background: yellow;
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
}
.top {
  flex-grow: 1;
  background: 000;
}
.bottom {
  height: 50px;
  flex: none;
  background: pink;
}
<div class="wrapper">
  <header>
    <h2>Header</h2>
  </header>
  <main>
    <div class="col left">Fixed Left</div>
    <div class="col center">Flexible Center</div>
    <div class="col right">
      <div class="top">Top Flexible Height inside fixed Right</div>
      <div class="bottom">fixed Height Bottom</div>
    </div>
  </main>
</div>

CSS-Tricks.com Ultimate Guide

Prefixes will be required.

Support Reference: CanIUse.com

Upvotes: 2

Shrinivas Shukla
Shrinivas Shukla

Reputation: 4463

Check out this fiddle.

It uses basic CSS and HTML and NO framework.

The key elements which allows this type of positioning are these css properties: left, right, top, bottom.

The demo uses these properties.

Here is the snippet.

body {
  background: beige;
  margin: 0;
}
#header {
  width: 100%;
  height: 60px;
  text-align: center;
  background: #A7C942;
  color: #fff;
  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  font-size: 2em;
}
#leftDiv {
  position: absolute;
  float: left;
  width: 150px;
  top: 60px;
  bottom: 0;
  background: aquamarine;
}
#midDiv {
  position: absolute;
  float: left;
  top: 60px;
  bottom: 0;
  left: 150px;
  right: 365px;
  min-width: 50px;
  background: lightsalmon;
}
#rightDiv {
  position: absolute;
  float: right;
  width: 365px;
  top: 60px;
  bottom: 0;
  right: 0;
  background: green;
}
#topRow {
  position: absolute;
  width: 100%;
  top: 0;
  bottom: 50px;
  min-height: 20px;
  background-color: lightgoldenrodyellow;
}
#bottomRow {
  position: absolute;
  background-color: lightpink;
  width: 100%;
  height: 50px;
  bottom: 0;
}
<div id="body">
  <div id="main">
    <div id="header">my header</div>
    <div id="leftDiv">
      <p>LEFT</p>
    </div>
    <div id="midDiv">
      <p>MIDDLE</p>
    </div>
    <div id="rightDiv">
      <div id="topRow">TOP</div>
      <div id="bottomRow">BOTTOM</div>
    </div>
  </div>
</div>

Upvotes: 3

Related Questions