SpyreStudios

Web Design and Development Magazine

  • Design
  • Resources
  • Showcase
  • Inspirational
  • Tutorials
  • CSS
  • Resources
  • Tools
  • UX
  • More
    • Mobile
    • Usability
    • HTML5
    • Business
    • Freebies
    • Giveaway
    • About SpyreStudios
    • Advertise On SpyreStudios
    • Get In Touch With Us

How To Code an HTML5/CSS3 Shopping Cart Webpage Layout

December 19, 2013 by Jake Rocheleau

I’ve wanted to put together a frontend web tutorial for a few months now. These types of articles provide an excellent point of reference for new designers who are growing accustomed to popular UI/UX trends. Specifically for designers who aren’t sure where to go on their next project, and may need a small boost of inspiration to get there.

For this tutorial I put together a small agile eCommerce checkout page. The structure itself is centered and running a fixed width to ensure an even layout regardless of the web browser. There are no jQuery animations or dynamic effects, so the layout itself is meant to be a single page running on CSS2/CSS3. Take a peek at my live demo to get an idea of the final product.

html5 css3 frontend webdev tutorial preview screenshot

Live Demo – Download Source Code

Getting Started

I have only included a single external file named styles.css in the document header. This will include a list of typical page resets along with common elements for structuring the cart itself. I chose to write this using an HTML table with the top heading and inner rows for shop products.

  <div id="w">
    <header id="title">
      <h1>HTML5/CSS3 Shopping Cart UI</h1>
    </header>
    <div id="page">
      <table id="cart">
        <thead>
          <tr>
            <th class="first">Photo</th>
            <th class="second">Qty</th>
            <th class="third">Product</th>
            <th class="fourth">Line Total</th>
            <th class="fifth">&nbsp;</th>
          </tr>
        </thead>

Naturally any table you write in HTML5 should utilize a thead followed by a table row with individual th elements. Every other row in the table should be using td cells, but the heading is a special circumstance. Also these headings will provide the spacing outline for how the table is structured – I’ve created a max width of 600px with 5 columns in total.

These columns break down into a product photo, the order quantity, the product name, the total cost for that item, and a trash can icon to remove any items from the cart with a single click. Each row is set to a fixed width using pixels for the width/height properties. Since the layout isn’t responsive I figured this makes the table sit nicer without any excess spacing.

<tbody>
  <!-- shopping cart contents -->
  <tr class="productitm">
    <!-- http://www.inkydeals.com/deal/ginormous-bundle/ -->
    <td><img src="images/design-bundle-pack.png" class="thumb"></td>
    <td><input type="number" value="1" min="0" max="99" class="qtyinput"></td>
    <td>Design Bundle Package</td>
    <td>$79.00</td>
    <td><span class="remove"><img src="images/trash.png" alt="X"></span></td>
  </tr>

I also created a number of items in the list, but the code above is just one example of the first product row. Inside the tbody element each row represents a product item when using the class .productitm. These rows have extra spacing and a border to separate them from each other. Also notice the quantity input uses the numeric type, as opposed to a text field type.

In Google Chrome this gives the user small up/down arrows to quickly update values. Other browsers don’t seem to have this native support just yet. But I’m almost positive there are jQuery plugins out there which can replicate this effect if you need full browser support.

Bottom Row Structure

Looking down towards the very bottom of the table you’ll find the last 3 lines are somewhat different. They contain the shipping+tax costs, then finally the grand total along with a checkout button. This button is styled in a way using open source CSS3 gradients from a CodePen entry. It’s also using a fixed width and height, but can be manually resized or updated to increase the font size or something similar.

  <!-- tax + subtotal -->
  <tr class="extracosts">
    <td class="light">Shipping & Tax</td>
    <td colspan="2" class="light"></td>
    <td>$35.00</td>
    <td>&nbsp;</td>
  </tr>
  <tr class="totalprice">
    <td class="light">Total:</td>
    <td colspan="2">&nbsp;</td>
    <td colspan="2"><span class="thick">$225.45</span></td>
  </tr>
  
  <!-- checkout btn -->
  <tr class="checkoutrow">
    <td colspan="5" class="checkout"><button id="submitbtn">Checkout Now!</button></td>
  </tr>
</tbody>

Since this isn’t a real form I used a <button> element in place of a typical submit input. Since these rows do not follow the same structure as the headings I’m including lots of colspan attributes on some of the table cells. This will span over a multitude of cells to better organize the prices so that they’re easier to read.

I find this to be an elegant solution because everything is fairly clear right off the bat. If you needed to add some extra features it wouldn’t be difficult to widen the layout and create more room for the content… or even create more table columns altogether!

CSS Page Styles

I’m using some typical page resets I created from the Eric Meyers template. The page background is called Old Map downloaded from Subtle Patterns. I also worked to include a simple rounded font creating one big bold title and finally settling on Fredoka One through Google Web Fonts.

@import url(http://fonts.googleapis.com/css?family=Fredoka+One);

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
  outline: none;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  -ms-text-size-adjust: 100%;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
html { overflow-y: scroll; }
body {
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-size: 62.5%;
  line-height: 1;
  color: #414141;
  background: #caccf7 url('bg.png'); /* http://subtlepatterns.com/old-map/ */
  padding: 25px 0;
}

::selection { background: #bdc0e8; }
::-moz-selection { background: #bdc0e8; }
::-webkit-selection { background: #bdc0e8; }

br { display: block; line-height: 1.6em; } 

article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }
ol, ul { list-style: none; }

input, textarea { 
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  -ms-text-size-adjust: 100%;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  outline: none; 
}

blockquote, q { quotes: none; }
blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
strong, b { font-weight: bold; }
em, i { font-style: italic; }

table { border-collapse: collapse; border-spacing: 0; }
img { border: 0; max-width: 100%; }

h1 {
  font-family: 'Fredoka One', Helvetica, Tahoma, sans-serif;
  color: #fff;
  text-shadow: 1px 2px 0 #7184d8;
  font-size: 3.5em;
  line-height: 1.1em;
  padding: 6px 0;
  font-weight: normal;
  text-align: center;
}

This is all pretty easy to understand but not everyone is a supporter of total resets. Bootstrap doesn’t use tremendous blocks of resets and keeps more to a standard baseline – ultimately it’s your call as a developer. Now the title and page itself have been broken down into smaller divs contained inside the outer wrapper.

#title {
  display: block;
  width: 100%;
  background: #95a6d6;
  padding: 10px 0;
  -webkit-border-top-right-radius: 6px;
  -webkit-border-top-left-radius: 6px;
  -moz-border-radius-topright: 6px;
  -moz-border-radius-topleft: 6px;
  border-top-right-radius: 6px;
  border-top-left-radius: 6px;
}

#page {
  display: block;
  background: #fff;
  padding: 15px 0;
  -webkit-box-shadow: 0 2px 4px rgba(0,0,0,0.4);
  -moz-box-shadow: 0 2px 4px rgba(0,0,0,0.4);
}

Box shadows and other properties are used for a more elegant look. Designers are lucky that modern-day trends have evolved around CSS3 so that we can move away from repeating background images for shadows or rounded corners.

The Shopping Cart

Playing around with the table was a somewhat annoying process. Using border-box will redefine how content is structured internally, along with how margins & padding will be applied. My table also uses border-collapse for resetting as much default functionality as possible.

/** cart table **/
#cart {
  display: block;
  border-collapse: collapse;
  margin: 0;
  width: 100%;
  font-size: 1.2em;
  color: #444;
}
#cart thead th {
  padding: 8px 0;
  font-weight: bold;
}

#cart thead th.first {
  width: 175px;
}
#cart thead th.second {
  width: 45px;
}
#cart thead th.third {
  width: 230px;
}
#cart thead th.fourth {
  width: 130px;
}
#cart thead th.fifth {
  width: 20px;
}

#cart tbody td {
  text-align: center;
  margin-top: 4px;
}

tr.productitm {
  height: 65px;
  line-height: 65px;
  border-bottom: 1px solid #d7dbe0;
}

I’ve chosen to create individual classes for each of the columns in the header. The only purpose is to give them a fixed width setting that will not change, regardless of each internal cell’s contents. All this content is centered within each cell to provide a natural-looking space between each row. Products in the cart use a row height of 65px along with a line-height of this same value. Now we have text that is centered vertically and horizontally no matter what complete width is being applied to the document.

.remove {
  cursor: pointer;
  position: relative;
  right: 12px;
  top: 5px;
}


.light {
  color: #888b8d;
  text-shadow: 1px 1px 0 rgba(255,255,255,0.45);
  font-size: 1.1em;
  font-weight: normal;
}
.thick {
  color: #272727;
  font-size: 1.7em;
  font-weight: bold;
}


/** submit btn **/
tr.checkoutrow {
  background: #cfdae8;
  border-top: 1px solid #abc0db;
  border-bottom: 1px solid #abc0db;
}
td.checkout {
  padding: 12px 0;
  padding-top: 20px;
  width: 100%;
  text-align: right;
}

I wanted to use light text for the labels to keep visitors focused on the important text. This is also why you’ll notice a bright blue background appended to the tax+shipping row. This is similar in the row with the submit button and it makes everything easier to skim from a distance.

All of the button styles can be found on CodePen along with some additional button colors. I’ve merely updated the text to be larger and easier to read with an internal text shadow.

#submitbtn {
  width: 150px;
  height: 35px;
  outline: none;
  border: none;
  border-radius: 5px;
  margin: 0 0 10px 0;
  font-size: 1.3em;
  letter-spacing: 0.05em;
  font-family: Arial, Tahoma, sans-serif;
  color: #fff;
  text-shadow: 1px 1px 0 rgba(0,0,0,0.2);
  cursor: pointer;
  overflow: hidden;
  border-bottom: 1px solid #0071ff;
  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #66aaff), color-stop(100%, #4d9cff));
  background-image: -webkit-linear-gradient(#66aaff, #4d9cff);
  background-image: -moz-linear-gradient(#66aaff, #4d9cff);
  background-image: -o-linear-gradient(#66aaff, #4d9cff);
  background-image: linear-gradient(#66aaff, #4d9cff);
}
#submitbtn:hover {
  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #4d9cff), color-stop(100%, #338eff));
  background-image: -webkit-linear-gradient(#4d9cff, #338eff);
  background-image: -moz-linear-gradient(#4d9cff, #338eff);
  background-image: -o-linear-gradient(#4d9cff, #338eff);
  background-image: linear-gradient(#4d9cff, #338eff);
}
#submitbtn:active {
  border-bottom: 0;
  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #338eff), color-stop(100%, #4d9cff));
  background-image: -webkit-linear-gradient(#338eff, #4d9cff);
  background-image: -moz-linear-gradient(#338eff, #4d9cff);
  background-image: -o-linear-gradient(#338eff, #4d9cff);
  background-image: linear-gradient(#338eff, #4d9cff);
  -webkit-box-shadow: inset 0 1px 3px 1px rgba(0,0,0,0.25);
  -moz-box-shadow: inset 0 1px 3px 1px rgba(0,0,0,0.25);
  box-shadow: inset 0 1px 3px 1px rgba(0,0,0,0.25);
}

Using CSS3 gradients in backgrounds can give your layout a modern look that isn’t always possible with regular CSS2 properties. The button’s active state also appends an inner shadow into the button, appearing to sink down into the page itself. I hope these CSS examples can provide some inspiration when building a newer style layout. Also try browsing through CodePen in some free time – you may be surprised at the quality of code snippets you can find there.

html5 css3 frontend webdev tutorial preview screenshot

Live Demo – Download Source Code

Closing

There are probably 1001 different ways to create a checkout/shopping cart webpage. It’s given me deeper insight towards frontend web development, and how tutorials like this can become a prominent learning tool. Feel free to download a copy of my source code and try building a similar cart into your own eCommerce project. Additionally if you have any questions or comments about the article you can share with us in the post discussion area below.

Filed Under: Tutorial Tagged With: ecommerce, freebie, howto, open source, website layouts

Recent Posts

  • How to Choose a Stunning Font Package for Your Brand
  • 31 Fresh Design Elements for Spring and Easter
  • 10 Templates for Music Concert Flyers
  • How to Build a Web Scraper Using Node.js
  • Best PHP Books, Courses and Tutorials in 2022

Archives

  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • April 2018
  • March 2018
  • February 2018
  • January 2018
  • December 2017
  • November 2017
  • October 2017
  • September 2017
  • August 2017
  • July 2017
  • June 2017
  • May 2017
  • April 2017
  • March 2017
  • February 2017
  • January 2017
  • December 2016
  • November 2016
  • October 2016
  • September 2016
  • August 2016
  • July 2016
  • June 2016
  • May 2016
  • April 2016
  • March 2016
  • February 2016
  • January 2016
  • December 2015
  • November 2015
  • October 2015
  • September 2015
  • August 2015
  • July 2015
  • June 2015
  • May 2015
  • April 2015
  • March 2015
  • February 2015
  • January 2015
  • December 2014
  • November 2014
  • October 2014
  • September 2014
  • August 2014
  • July 2014
  • June 2014
  • May 2014
  • April 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • November 2013
  • October 2013
  • September 2013
  • August 2013
  • July 2013
  • June 2013
  • May 2013
  • April 2013
  • March 2013
  • February 2013
  • January 2013
  • December 2012
  • November 2012
  • October 2012
  • September 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
  • March 2010
  • February 2010
  • January 2010
  • December 2009
  • November 2009
  • October 2009
  • September 2009
  • August 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • May 2008
  • April 2008

Categories

  • Accessibility
  • Android
  • Apps
  • Art
  • Article
  • Blogging
  • Books
  • Bootstrap
  • Business
  • CSS
  • Design
  • Development
  • Ecommerce
  • Fireworks
  • Flash
  • Freebies
  • Freelance
  • General
  • Giveaway
  • Graphic Design
  • HTML5
  • Icons
  • Illustrator
  • InDesign
  • Infographics
  • Inspirational
  • Interview
  • Jobs
  • jQuery
  • Learning
  • Logos
  • Matrix
  • Minimalism
  • Mobile
  • Motion Graphics
  • Music
  • News
  • Photoshop
  • PHP
  • Promoted
  • Rails
  • Resources
  • Showcase
  • Tools
  • Tutorial
  • Twitter
  • Typography
  • Uncategorized
  • Usability
  • UX
  • Wallpapers
  • Wireframing
  • WordPress
  • Work

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

SpyreStudios © 2022