Welcome back to Sharing Is The Key. Let’s continue digging deeper into the CSS world to build vital Web Developments’ fundaments to deliver a compelling user interface. As we discussed in the second post of this series, there are many essential concepts about CSS that we miss most of the time, and it causes many issues to the end-users.
Now that you’ve learned how to add styles with Cascading Style Sheets, let’s look at working with them more in-depth on your web pages. You’ll learn about the box model, how to create layouts for your web pages, how to target desktop versus mobile devices, and how to determine browser support for the styles you write.
The Box Model
Every element in your web page has a sense of presence on the page. The way the browser interprets this presence is called the box model. Let’s take a look at the button we did in the previous post, and let’s add
margin: 10px, and
height:50px to the existing
.button class. Save it and see the changes in the browser.
Let’s open up the developer tools and take a look at a utility that better depicts how the browser sees this element within the page. So I’ll right‑click on the button and choose Inspect. As we take a look at the Elements tab, bring your attention to the bottom right corner, where you can see a representation of how the browser sees this element. So for each element, we have margin, border, padding, and then the dimensions.
You can see that the values that we added into the style correspond to the diagram above. So the margin value that we created was for 10 pixels. Now the margin is the space between the border itself and everything else around the boundary of that element. As depicted here, the border was set to 1 pixel, so there’s a nice thin border around the element, and padding is the space inside the element, in between the border and the content of the element. And then lastly, we have the height and the width of the element itself.
Something is interesting you need to notice here. While I set the width for this element at 40 pixels, the actual width is 82 pixels. It is 10 pixels for the margin, 1 pixel for the border, and 10 pixels for the padding on both sides, and then 40 pixels for the width of the element inside the box. So as you’re styling elements on the page, you need to know how the margin, border, and padding values affect the dimensions of the elements on your page.
Now that you’re acquainted with the box model, let’s take a look at the type of style rules you’d need to write to create columns on your page.
Columns with Float
One of the fundamental features of creating a layout for a web page is to create columns, and unfortunately, that is a lot easier said than done when it comes to building a web page. So the first thing I’d like to do is show you a common way that people try to achieve a column layout, and I’d like to highlight a few of its problems, so then next I can show you a little more of a robust solution. Let’s add one
class="columns" with two divs inside right after the Hello button. And we’ll use this class name to add style to the elements inside of it. Let’s try to use Emmet as much as we can to get the hang of it.
So to start, let’s create a class for columns. Let’s give it a width of 100%. And I’ll put a border on there as well so you can see how much space it’s taking up within the browser. So when I press Save, you can see I have the columns container taking up 100% of the width of its parent container, and it’s got that border.
All right, now let’s see if we can get Column 1 and Column 2 to situate next to each other. For my next style rule, I’ll use a child selector. So what I want to do is target all of the
div elements that are children of my columns class selector. When you think about creating columns, essentially, what you’d like to do is take each one of these
div elements and make them take up the same amount of space on the page and then situate them next to each other. So I’ll give each one of these divs a width of 50%. Now, just so that we have a better idea of what’s going on, let’s add a red border around these elements.
Now we need to tell Column 2 to float up next to Column 1, and so we’ll use the float rule for that. We’ll say
float: left;, and what this rule should do is tell the Column 2 div to show up next to Column 1. Because the box model is at play, and the width and border values are calculated into the overall elements’ width, there’s not enough space to create the columns when each of the divs is set to be 50%. So let make this 49% and save it, now I have two columns floating right next to each other, but there’s still a problem. I have this space left over at the edge of the page. And when you begin designing layouts, small bits of extra space can be frustrating.
So instead of using the float rule, let’s take a look at how Flexbox can make our life so much easier.
Columns with Flexbox
Starting in the same spot as we did when we first tried to create columns for our layout, we’ll use Flexbox, and we have our columns class and our divs for Column 1 and Column 2 available on the page. Let’s start by getting rid of the
float rules in our class and class with a child selector. Let’s keep only the border for both of them. It takes up 100% of its parent’s width, so we can start creating some columns.
Now, I’d like to introduce you to
display: flex. By adding this one rule to our page, now when I save the file, you can see we’ve got two columns on the page.
It isn’t quite the type of layout that we want, so let’s customize it slightly more. In the child selector
.columns > div, we’ll add in the flex rule. Now, by saying flex equals 1, I’m telling the browser to evenly distribute all the space that’s available within the container and allow each one of my divs to take up one portion of that amount of space. So, essentially, since I have two columns, by setting flex equal to 1, I’m telling the browser, allow each
div to take up one column’s worth of space within the container.
Now, to illustrate this a little more clearly, let’s see what happens when we add a third column into the mix.
By merely adding a new
div onto the page, we have three columns that have equal widths, but I have even more control available to me with Flexbox than that.
For our layout, we want Column 1 and Column 3 to be more narrow, and Column 2 takes up a majority of the space within the page.
Well, we can do that by adding in another selector. I’ll start with another child selector based on the columns container. Now I’ll create another child selector, and then I’ll use a particular type of selector called a pseudo‑class. Now the syntax for this is to add a colon, and VS Code will give us many different options available for pseudo‑classes. So I can target the
first‑child of the container or the first of a specific type. I want to make Column 2 a little bit wider than Column 1 and Column 3, so I’ll use the
nth‑of‑type pseudo‑class. By using
nth‑of‑type, I’m telling the browser to look for a
div within the container based on its position. So when I add in 2 as an argument, it will skip the first
div and select the second
div. Now I can add a rule into this block and tell the style I want the flex value to be 2. So, what will happen when I save the file?
That’s right. Column 2 is wider than Column 3 and Column 1. What Flexbox is doing is calculating all of the available space needed for the columns, giving Column 2 a double portion of that space, and Column 1 and Column 3 get a single proportion of the space allotted for the columns. Now there’s so much more that you can do with Flexbox, this scratches the surface, but the rules you see here will get us where we need to build Bethany’s Pie Shop. Next, let’s look at how we can target rules to only apply to desktop or mobile devices.
Responsive Layouts: Viewport
Media queries allow you to target your CSS rules to different devices. It means you can create rules that target the desktop browser versus other rules that apply to mobile devices, so let’s take a look and see how this works.
Here, I have many elements on the page. We want that projects show up on the desktop, the Hello button and the class columns divs show up for mobile devices, and the table shows up only when you print the page. We need to add
Now when you’re designing for the web and creating styles that target different devices, often the best approach is to design for mobile devices first. It is essential because it forces you to make sure that your layout works in the smaller dimensions before it works in the larger ones. Therefore we will use this approach here. Before we start writing CSS rules, there is a specific metadata tag that you need to be aware of that’s essential to make our styles work correctly. The metadata element is named
viewport and is required to let the device know how to interpret its width.
This element is telling the browser that the viewport or the way that the page is rendered within the browser will have a width of whatever the device width is. It is important so that the page is rendered at the correct width of the device. An initial scale is a setting for the scaling or the zoom. So by setting an initial scale equal to 1, we’re telling the device to take on the 100% zoom setting, so you’re not zoomed in, and you’re not zoomed out.
Okay, well, with this in place, now we can write some CSS rules that target different devices.
Responsive Layouts: Media Queries
So now, with the viewport defined, I can start working on my styles. Now I want to make sure that I’m doing my styles for my mobile devices first. So the first thing that I’ll do here is to hide the Desktop and Print elements. To do that, I’ll create a list of class selectors and give it a style rule of
Now when I press Save, you’ll notice that those elements disappear from the page. With
display: none in place, it tells the browser that any of these elements no longer take up any physical presence within the layout. By setting display equal to none, I’ve essentially taken those elements out of any rendering on the page. So using
display: none is a very common way of hiding elements on the page.
Next, I’ll create a media query just for when the page is printed. Now I’m showing you the print media query because other rules we’ll use target the screen only. So we start with the at symbol
@ and use the media keyword. Then I tell it that this works for printing only. Within this media query, I want to create the reverse rules for what I initially set up. Here, I want to tell the Mobile and Desktop elements to be hidden and then show the Print element. So this will hide the Mobile and Desktop elements. And by setting display to block for the Print element, that will show that element as we print the page.
So when I press Save, you’ll notice that nothing happened in the browser. As it’s rendered on the screen, it looks just like our mobile stylesheet. However, if I come over to the browser and type Ctrl+P, you can see within the print preview that the only thing that’s rendered on the page to be printed is our Print element.
Next, we can target the desktop browser on the screen by using a different media query. So here, I’ll build the rule with the media screen and then add a selector. Now I’m adding the ‘and’ keyword in here to create a selector for the rules to be applied only in certain situations. So, in this case, I only want to apply the rule where the browser’s width is greater than 768 px. So to do that, I’ll use the
min‑width property. And so now I can tell the Mobile elements to hide and show the Desktop ones. So, again, any screen that’s 768 px in width or greater will hide the Mobile element and show the Desktop element.
So let’s save the page and see what happens. Since I’m showing my screen side by side, and the screen width is less than 768 px, nothing happened. So if I take my browser and expand it out, you’ll notice that it begins to show the Desktop element after it crosses over that threshold.
Now when you’re testing media queries and want to see what they look like in different environments, just changing the size of the browser is not the best way to go about it. And the browser developer tools once again make your life so much easier. So I can open them up by saying Inspect element, and then you’ll notice an icon where you can toggle the device toolbar. When I click on that, it creates a simulation of what this page might look like under different mobile contexts. So here, I can come up here and select from several different preconfigured devices. I can change the orientation and even the zoom level. And so you’ll notice on an iPad Pro, we’ll get the Desktop experience because of its dimensions. But on an iPhone 5, it renders the Mobile experience
Media queries give you a lot of power to target your layouts for different contexts. Next, let’s look at how you can determine browser support for the CSS you write.
Just like when you’re writing HTML, you’ll want to know about the browser support for the different CSS rules you write for your websites. And to find out which rules work in which browsers, we can use the website caniuse.com. So let’s take a look at one of those rules, and we’ll take a look at Flexbox. And so, through this table, you can see that Flexbox enjoys quite a bit of support throughout most browsers available in the world today.
And any feature with this type of support you can safely use in just about any production application. Scrolling down the page a little bit, you have the opportunity to read some of the developer notes about the feature, and I find the Known Issues tab to be incredibly enlightening. It is where you can dive into edge cases where certain features may have restrictions under particular circumstances. So that’s a well-supported rule.
Let’s take a look at something that’s not quite as ubiquitous. Let’s search the hanging‑punctuation rule. It allows some punctuation characters from the start or end of text elements to be placed outside the box to preserve the reading flow. Well, as you can see here, we have a whole lot of red, and this rule is not supported well enough for you to use it in a production application.
So chances are most of the rules you choose to use for your layouts will be supported well enough for you without worrying about it, but if you have any questions, make your way over to caniuse.com and find out for sure.
Building Content Pages
Well, you have come a long way since we first introduced the very basics of HTML. We made our way through style sheets, and now we’re ready to start building the website for Bethany’s Pie Shop. We will set the HTML foundation for the home page and develop the global style sheet and styles specifically for each of the content pages. Let’s start building the home page.
Create the Foundation
So let’s start by returning to the starter project that you downloaded in the first post. Now, let’s create the index file, order file, list of pies, contact file, and the global stylesheet file. Once again, we’ll be using Live Server to watch the changes as we make them here in VS Code.
Let’s start with the index file, and we’ll use the Emmet shortcut to create the basis of an HTML file. So I can type
ht and then come down and select
html:5. That will give us an HTML5 stub of a web page. And a lot of this should look familiar to you by now. So we have our doctype. We have our HTML element set with language
lang="en" for English. We know this will pass our validation rules. Here we have a meta tag. The character set is UTF‑8, which is the text encoding for this page. We have our
viewport. That’s already put in there for us, so they’ll work as expected when we create responsive styles. We’ve got a title and then our body element. So I’ll save this, and then I’ll right‑click on the page and say Open with Live Server.
That opens the browser for us automatically. And when I come back over to VS Code and hide the explorer. That gives us a bit more space. And now I’ll shrink VS Code so that we can see both windows at the same time. Now, when I type something in the file and save it, we can automatically see that change in the browser.
Now, to serve as a reminder of what we’re building, this is the home page.
So we’ll start by creating the navigation at the top of the page, add the logo image, generate the markup for the content of the page itself, and then add the markup for the footer. Once the structure is in place for the HTML, we’ll add the styles, and the final result will be this home page here for Bethany’s Pie shop.
So here I can add in the structure for the top navigation of the page. And we’ll start, of course, by using an Emmet shortcut again. So inside the body, what I want to build is a header by typing
header>. Inside that, the site navigation. The element that we can use here is the nav element
header>nav>. Then I want to create an unordered list
header>nav>ul>. And inside that list, I want to have three different list items
header>nav>ul>li*3>. I want to make an anchor for a link inside each one of the list items
header>nav>ul>li*3>a. So now, when I press Tab, all of that HTML will be generated for me.
If you recall our discussion about semantic markup in the first post of this series, it is telling a search engine that this section of the page is the header of the page. Inside of it, I have navigation, and the nav element is a container for links that apply just to this site. So we wouldn’t put a link to, let’s say, an outside website within the nav element. It is just navigation for our website alone. Then we can create an unordered list and then the list items here.
So we’ll create the first link for the home page. It is a little weird because we’re building the home page right now, but I put it on here just for consistency’s sake as you go through the different pages in the website. Adding the slash value for
href tells the browser to go to the very root of the website. In other words, if we had bethanyspieshop.com, that’s where this link will go.
Next, we want a link to the pies list page, and so we can add
pies.html in the second list item, so when you click on it, it’ll go to that page, and then we’ll give it the label of Pies. And lastly, we have a link to the contact page. Now when I press save, you’ll see that the result is pretty unimpressive visually, highlighting the value of stylesheets.
And we’ll implement the styles soon, but for now, let’s finish building the rest of the home page’s structure. So next, we’ll add Bethany’s logo to the page.
Add Main and Aside Elements
So now we’ll add the page’s main content. To do that, we’ll use an element called
main. The overall structure of the page will give us a header, the main content, and then a footer for the page. It is vital to use the main element for this page because that signals to a search engine that the content within this page inside this element is the primary content. Sure, the header and the footer are essential, but they are most of the time links around the site. We’ll probably have some branding information, maybe some contact information. But when it comes to the primary purpose of this web page, what is in the main element is what we most care about.
Now inside the
main element, I’ll use two different tags. One is the
aside, and the other is the
article element. Now, if you think of a typical magazine article, the page’s main content flow is the article text, and sometimes you’ll have pull quotes that show up over on the side. Well, that’s the difference between the
article element and the
aside element, which I’ll use here.
aside element is important and contextually relevant to the content on the page. But it’s not the most critical part. Here I’m using the aside with an image inside of it to show the logo on the page. Let’s use Emmet again, type
aside>img:s and hit Tab.
You’ve seen in the past, the source attribute is where we put the path to point to the image, and in this case, it’s
alt attribute gives a hint to machines about what this image is about. So whether it’s a search engine or a screen reader, the text we add here describes the image. So here I’ll just put in Bethany’s Pie Shop. And so now, when I save the page, the logo shows up on the screen.
Add Article and Footer Elements
Next to the aside element, we’ll add the article element with some different supporting elements. If you recall the finished product, inside the main, we have a banner, a title, and some text with a link to our pies list page. So that’s what we’ll add on the page now.
Now, rather than typing everything out character by character, I’ll paste in the markup for this page, and then we’ll discuss it.
So we’ve got the article element, and I’ve got an image element that renders out the banner, the h1 element, that’s the main title for the page. Again, for search engines, they’re going to key in on this h1 element. Then I’ve got a paragraph of text that welcomes people to the page. So it’s a message from Bethany and a link over to the pies list page.
Now we’ll use Emmet one more time to generate our footer, and then we’ll have everything we need for the home page. Here, we’ll create a footer with a navigation element that includes a list of anchors by typing
footer>nav>li. We want three list items, so that’ll be
footer>nav>li*3, and inside those list items, we’ll render some anchor tags
footer>nav>li*3>a. And again, rather than typing everything out, I’ll copy from the header and paste in the links and save it.
We’ve got our top navigation, logo, banner, welcome text, and the footer links on the page. So now we can move on towards adding the global styles for the website.
Global Styles: General and Body Rules
Okay, well, we’re off to a good start. We have the foundation set for the home page. We have all the pieces that we need to start styling it with a global style sheet. I mean by a global style sheet that we’ll create a style sheet that works for every page—all of the base styles that every page needs to make it look like Bethany’s Pie Shop.
Individual pages will have their own set of styles that customize what they need for those pages. But we’ll get started by creating the base required styles for our website.
Now we need to reference our style sheet file. Go to the
index.html and make sure that we add a reference to the site.css file so that all the styles we enter into
site.css end up getting loaded into the home page.
To do that, we’ll add a new element into the head of the page, and we’ll create a link to
site.css. We’re going to have
href will be
site.css. And then we need to tell this element that it’s reading CSS, so we’ll add a type attribute, and the value is
text/css. Now the type attribute is important because it tells the browser when it loads this file to read it as a CSS file.
The first thing that we want to do is reset the margin on all of the elements on the page. Some elements like title elements have a little bit of margin and maybe some padding built-in as their default styles. To get our layout working correctly, what I’d like to do is reset every single element so that it has no margin at all.
To do that, in the
site.css, I’ll use the
* selector. It says every single element on the page will get the following rule. So now I can set all margins 0. When I press Save, you can see that all of the margins around these elements are compacted. It is good because now we won’t be fighting with any default values, and so elements will only get the margin that we set.
Next, I want to add rules that will help make sure that it calculates the dimensions of the page correctly. So here I have a selector for HTML and the body. So essentially, this is the entire page within the browser. And here, I’m setting the height to 100%. While this didn’t visually make a change within the browser, it helps other styles to be able to calculate their position on the page correctly.
Now let’s add some styles just for the body itself. These rules will rely on inheritance to make sure all of the other elements on the page have the style rules that we’ll enter here. Here I’ll change the font, and you’ll notice that VS Code gives me some options. So here, we’ll select the Arial, Helvetica, sans‑serif option. And now I want the background colour of the body to be a light gray. I’ll press Save, and we can see the change made to the file.
Global Styles: P and Header Rules
Now you might be wondering, Why am I setting the background colour to that gray? When we look at the finished product, you’ll notice that the top navigation has its background colour. Within the body of the page, we have an image applied to the background that’s repeated to give us that striped look. And then, when we come down to the bottom of the page, the footer has a gray colour. By adding this rule at this point, the footer can just inherit the colour of the body.
We want to add a style for all of the paragraphs within our website to have its custom margin.
Now I’ll scroll down on the page, and when I hit Save, you’ll be able to see here within the paragraph how the margins will change.
Next, we can add styles for our header so that our navigation begins to look the way we want it. The first rule I’ll add
display: block. The second is
position: fixed. Now when I hit Save, notice what happens?
The logo shows up underneath the links at the top, but because I have the position as fixed, you’ll notice that the navigation links stay in place when I scroll the page. And that’s exactly what we see on the finished product. As I scroll the page, the top navigation stays fixed into position at the top of the browser.
And so we want to add in that position. So we’ll add top and left dimensions, the top rule telling the browser to fix that position at the very top of the browser window, as well as the very left‑most edge of the window.
Now let’s make it take up 100% of the width of the page, set its background colour, and add a little bit of padding. Here we’ll use the colour code specific to the theme for her website and add in the padding. So now we have a fixed element at the top of the page that includes our links. The links aren’t quite exactly like what we’d expect yet, but that’s just the style for the header.
Next, let’s look at how we can customize the links within the page’s header.
Global Styles: Nav Element
So we have the fixed header set up, now let’s add the rules to make our navigation links look a whole lot better.
First, I’ll start with a selector that styles the links depending on the click state. I want to style the appearance of the links after someone visits them. And the default state for all links underneath the navigation element on the page. So to do that, let’s use the pseudo-class link as
a:link. We’ll make the links white, use a rule called
text‑decoration, and set that to
text‑decoration: none says that our links won’t have any underlines underneath them.
So now, when I save the file, you can see that the links turn white, and they’ll stay white whether or not we’ve clicked on them before or not, and, of course, the underlining has been taken away from the text.
Next, let’s deal with how this list renders on the page. So we’ll look at the nav element and target the unordered list within that element
nav > ul. Now we’ll tell the browser to display this list inline and zero out all the padding around the list.
When I save the page, you can see that the bullets have disappeared from our list, and there’s no extra padding around the links.
For our final style for the list, we can add some rules that target the individual list items within that unordered list
nav > ul > li. For these, we want them to display as
inline‑block, set the
none, and set the left and right margin. So the first value is for the top, so we’ll fix it to 0, then we have the right, the bottom, and the left value. So what
display: inline‑block tells the browser to do is to display our element inline, so that means it stacks the elements right next to each other, but we put it within a particular mode of
inline‑block, saying that you can still have control over things like width, margin, padding, where you don’t usually have control over those aspects when you have a typical inline element.
list‑style: none; tells the browser not even to interpret this item as a list item, and then our margin values give a little bit of space between each link. You might be wondering, why using a list element at all when we’re trying to style it to look like a series of links right next to each other? And that goes back to semantic markup. When a search engine looks at our web page, it’ll see that there’s a list of links within a navigation element and has a better job of interpreting the meaning of those links, rather than just having random anchors scattered around on the page.
If you need any help or something is going wrong, let me know. It will be my pleasure to help you. If you want to extend some point, we have discussed, contact me so we can cover in the fllowing posts.
We also have pro bono projects just in case you are interested in learning more about them.
Be aware of why we started this project by clicking here.
Learn more about other posts here.
If you are a good reader like myself, I recommend the following readings:
- Docker Quick Start Guide: Learn Docker like a boss, and finally own your applications
- Docker for Developers: Develop and run your application with Docker containers using DevOps tools for continuous delivery
- Responsive Web Design with HTML5 and CSS: Develop future-proof responsive websites using the latest HTML5 and CSS techniques, 3rd Edition
See you in the next post!