Web Design

Chapter 4   Fluid Layout

(1) The evolution of layout

∗ In the early stage, tables are used for layout

▸ The layout is fixed; unable to change dynamically

▸ It required human intervention to change the layout

∗ And then, the size of a block is defined as percentage

▸ E.g., aside: 20%, content: 80%

▸ However, different screen resolutions result in very different looks of the page (deformatio)

∗ And then, pixels are used to define block sizes

▸ Since a screen is composed of pixels, difining sizes in pixels results in exacltly the same look the page deformation problem solved

▸ Usually, the page width is set as a number of pixels, e.g., 1,000 pixels (with left and right blanks for wider screens)

▸ Such an ideal state was changed again by mobile devices

∗ Recently, responsive webs using thresholds

▸ Query the viewport, and then dynamically set the appropriate layouts

▸ Problem: if the viewport size is within thresholds, the horizontal scroll bar will still show up

∗ True responsive webs

▸ Go back to the percentage method; i.e., scale the size according to viewports until next threshold fluid layout

(2) Scaling the element sizes

∗ Turn the fixed size into a percentage

▸ Resulting width is the target width divided by the environment width; i.e.:

result = target/context

∗ Exercise: set the sizes of layout related elements into percentages

▸ The main layout elements:

<div id="wrapper"> 

  <header> 
    <nav>
    </nav> 
  </header> 

  <div id="content">
  </div> 

  <aside>
  </aside> 

  <footer>
  </footer> 
 
</div>

▸ The settings of the layout element sizes:

#wrapper {
  width: 960px;
  margin: 0 auto;
}

header {
  padding: 60px 20px 20px 20px;
}

nav {
  padding: 20px 0;
}

div#content {
  float: right;
  width: 700px;
  margin-top: 50px;
  padding: 20px;
}

aside {
  width: 260px;
  margin-top: 50px;
  padding: 20px;
}

footer {
  clear: both;
  margin-top: 20px;
  padding: 20px 20px 60px 20px;
}

▸ Exercise: save oscar3-4.html and oscar3-4.css as oscar4-1.html and oscar4-1.css,respectively, and modify as follows

✶ HTML:update the CSS link <link rel="stylesheet" href="css/oscar4-1.css">
✶ CSS:
# Set the proportional width of the outer block
* Currently, all settings are based on px, now set as percentage from the outer element
* #wrapper: assuming the screen width is 1000px, the percentage of #wrapper is 96%:
#wrapper {
  width: 96%;    /* 960px */
}
* If the viewport width is wide enought, aside and #content will flow left and right, respectively
# When setting percentage, the reference is the containing element; hence, the widths of elements in #wrapper is proportional to #wrapper
div#content {
  width: 73%;    /* 700/960 */
}

...

aside {
  width: 27%;    /* 260/960 */
}
* Except nav li a, change the margin and padding of the layout elements according to #wrapper :
10px: 1.04%;    /* 10/960 */
20px: 2.08%;    /* 20/960 */
50px: 5.21%;    /* 50/960 */
60px: 6.25%;    /* 60/960 */
# For media query (@media screen and (max-width: 800px) {):
* The width of #wrapper is set to be 100%
@media screen and (max-width: 800px) {
  div#wrapper {
    width: 100%;
  }
  ...
}
* Set the percentage of h1#first
aside h1#first {
  margin-right: 5.21%;
}
✶ Test: change the width of the browser and observe the changes of the page

(3) Fluid images

▸ Fluid images: image sizes are scaled according to containing elements

▸ Exercise: save oscar4-1.html and oscar4-1.css as oscar4-2.html and oscar4-2.css, respectively, and modify as follows:

✶ HTML: update the CSS link <link rel="stylesheet" href="css/oscar4-2.css">
✶ CSS:
# Set the sizes of the images in <aside> as percentages
* Delete the padding in aside
* The original size of aside is 260px; if the left and right paddings are both 20px, the width of h1 would be 220px, i.e., 85% (220/260)
* Set the alignments of h1 and texts inside to be centered, and set padding value to be percentage also
* Set padding for the p in aside
* Set the width of the images in h1 to 45% (two images would be 90%)
aside { 
  ...
  margin-top: 5.21%;    /* 50/960 */
  padding: 2.08%;   /* 20/960 */
}

aside h1 { 
  ...
  width: 85%;   /* 220/260 */ 
  margin: 0 auto; 
  text-align: center;
  padding: 4% 0;  /* 10/260 */
}

aside p { 
  padding: 4% 0;  /* 10/260 */
}

aside img.poster {
  width: 45%;
}
# Set the width of oscar.png as percentage of #content (200/700)
div#content img#oscar {
  width: 29%;    /* 200/700 */
}
# Another problem: when scaling the page, oscar.png might be too large; we may set its max width as 200px
div#content img#oscar {
  ...
  width: 29%;    /* 200/700 */
  max-width: 200px;
}
# In addition, to prevent various element from being too large, we may set a max width for #wrapper
#wrapper {
  ...
  margin: 0 auto;
  max-width: 1200px;
}
# Media query
* Set the width of h1 as percentage, delete h1#first setting, and set the width of the images as percentage
@media screen and (max-width: 800px) {
  ...
  
  aside h1 {
    display: inline-block;
    width: 45%;
  }

  aside h1#first {
    margin-right: 5.21%;    /* 50/960 */
  }
  
  aside img.poster {
    width: 40%;
  }
}
* HTML: delete the id in <h1 id="first">
oscar4-2.html
<h1 id="first">
   ...
</h1>

(4) Responsive images

▸ Responsive images: provide differnt image files for different viewports

▸ Solution: use the picture tag

<picture>
  <source media="(min-width:...)" srcset=...> 
  <source media="(min-width:...)" srcset=...> 
  ... 
  <img src=... alt="Original image"> 
</picture>
source: the source of the image
media: the viewport condition
srcset: one or more image sources

▸ Example

<picture>
  <source media="(min-width:800px)" srcset="large.jpg">
  <source media="(min-width:600px)" srcset="medium.jpg"> 
  <source srcset="small.jpg">
  <img src="small.jpg" alt="Original image">
</picture>

▸ Exercise: save oscar4-2.html and oscar4-2.css as oscar4-3.html and oscar4-3.css, respectively, and modify as follows

✶ Create four images: oscarLarge.png (200x500), oscarMedium.png (150x375), oscarSmall.png (100x250), and oscarStandard.png (180x450)
✶ HTML:
# Update the CSS link <link rel="stylesheet" href="css/oscar4-3.css">
# Provide different image files for different viewports, and if the browser does not support the picture tag, fall back to the standard image
...

<div id="content">
  <img id="oscar" src="img/oscar.png" alt="Oscar statue">
  <picture>
    <source media="(min-width:900px)" srcset="img/oscarLarge.png">
    <source media="(min-width:700px)" srcset="img/oscarMedium.png">
    <source media="(min-width:500px)" srcset="img/oscarSmall.png">
    <img src="img/oscarStandard.png" alt="Oscar statue">
  </picture>

...
✶ CSS:
# Set the width of the image as percentage
...

div#content img#oscar {
div#content picture {
  ...
}

div#content picture source,
div#content picture img {
  width: 100%;
  height: 100%;
}

/* Aside */
...
# May add more responsive elements: show different text sizes in different viewports
...

/* Responsive design */
/* At 1000px */
@media screen and (min-width: 1000px) {
  nav ul li a {
    font-size: 1.8em;
  }
}

@media screen and (max-width: 1000px) {
  nav ul li a {
    font-size: 1.6em;
  }
}

/* At 800px */
@media screen and (max-width: 800px) {
  ...
  
  nav ul li a {
    font-size: 1.4em;
  }
}

/* At 600px */
@media screen and (max-width: 600px) {
  nav ul li a {
    font-size: 1.2em;
  }
}