As a final project in one of my interactive design courses, students are required to create an online portfolio that showcases their work in web development, page layout, graphic design, video and other creative areas. I created this portfolio to show them how such a site might be constructed and to provide resources, tips, and tricks that I can illustrate in class and for students to use for later reference. The sections below illustrate how students can incorporate many of the features found on this site.
Learn more about CSS Grid on my other tutorial site at grid-layout.com.
The site's overall layout was done using CSS Grid. This section can't completely cover CSS Grid, but the essential components of this layout are shown below. The six panels on the left are each individual grid containers that differ based on how many columns each needs.
The site uses a mobile-first responsive approach and the layout shown here represents how it might look on laptops and desktops. Therefore, the CSS code shown is based on the number of columns needed for those devices. On mobile devices, each grid item would stack one on top of the other vertically down the page.
AOS has documentation about how to use the libraries, but it's simple to add a few quick lines of code to create animations on your site that when scrolled to can fade, flip or zoom. Animation delay, duration and a range of other options are available.
AOS can be used in one of two ways.
1. Self-hosted: Download the CSS and JS files to your site.
2. Hosted from the AOS Content Distribution Network (CDN).
This lesson will use option number two.
Note: Too much motion can be undesirable and overwhelming. Luckily, there is a new CSS media query called prefers-reduced-motion that you can enable on your pages that allows those who choose reduced motion in their operating systems to turn off animations, transitions, transforms, and parallax scrolling. See the lesson below on User Preferences to learn how to provide that option.
AOS Website: https://michalsnik.github.io/aos
Font Awesome is a CSS library or toolkit for creating graphical icons using fonts. Libraries are essentially just files full of useful code where you can call on some pre-written CSS classes to do specific things on your site.
As vector-based fonts they are easily scalable (resizable) and can be styled using CSS to make changes to size, color etc. You can even add drop shadows.
Font awesome makes many of their font icons available without cost. To use the whole range of fonts you'd need to pay a fee.
Font Awesome can be used by downloading the fonts to your site. Follow these quick and easy steps.
1. Download Font Awesome files at:
(Look for the "Download Font Awesome Free for the Web" link. )
2. Extract the downloaded .zip file.
3. Move the folder you extracted into the root folder of your website.
(As of this writing, the folder was called fontawesome-free-5.15.3-web).
4. Add the following code to use Font Awesome.
NOTE: Font Awesome uses the italic <i> tag because it is an inline element and it has been deprecated (being phased out). Because of it being deprecated, web developers are therefore not likely to use the tag elsewhere on their sites, but browsers still support it. Another option is to use <span> which would be more semantically correct and is also an inline element. It would look like this: <span class="fas fa-car"></span>
A gallery showing all the font icons available: https://fontawesome.com/icons?d=gallery
Some cool examples: https://fontawesome.com/v4.7.0/examples
Font Awesome Homepage: https://fontawesome.com
The growth of long scrolling pages and infinite scrolling on both mobile and desktop has created the need for users to quickly navigate to the top of the page without needing to scroll. This trend has led to the use of "Back to Top" buttons as a navigation shortcut. The button is usually placed in the bottom right corner of the page and remains in position (sticky) while the user scrolls up and down. (See the bottom right of this page for this page's back to top button).
Feel free to change the CSS properties below to customize the button for your site.
jQuery Website: https://jquery.com
Responsiveness without Media Queries
One of the most powerful features in the CSS Grid specification is the ability to create responsive layouts without using media queries. This is done by using the repeat function along with auto-placement keywords auto-fit or auto-fill. These keywords allow you to place as many grid items of a particular size on a row that will fit within the width of the viewport.
An example of this in use can be seen on the Urbino, Italy page on this site. The video on the left below also shows how the number of images on a row changes based on the width of the browser. When making the viewport narrower, both auto-fit and auto-fill automatically push grid items down to another row once each of the grid items would become narrower than some specified number of pixels. Again, this is done without media queries.
The HTML markup is simple. There is a container that contains six images, each wrapped in a <div> with a class of card.
The CSS is done with CSS Grid in basically one line of code:
grid-template-columns:repeat(auto-fit, minmax(300px, auto));
This example uses the auto-fit keyword along with the minmax function. It sets each photo to be no less than 300 pixels. Auto means the image can stretch horizontally until at some point there would be room for another grid item to fit on the row.
This page shows the layout using just the code below. Try the code in your page and change 300px to some other value. You'll notice you can control how many photos appear on a row at a given width.
Fixed position headers/menus have many benefits. The main advantage is that they never leave the screen when a user scrolls, thus making the menu/navigation easy to access. This is especially helpful on long scrolling pages with a great deal of content.
The main disadvantage is that fixed navigation will always take up a portion of your valuable screen real-estate and thus hide other content. This is an even bigger problem on small screens or mobile devices.
It would be better if one could hide the menu/header when a user scrolls down, but then show it again when a user scrolls up.
You can see an example of this in action on this site. Right now, scroll up slightly. Notice that the header/navigation slides down from the top and back into view. Scroll down and watch it slide off the top of the page. We will make a simplified version of this approach, such as seen at drsteveanderson.com/scroll-nav.html.
The controversial "hamburger menu"
There has been a great deal of debate about the effectiveness of the hamburger icon/button/menu. It was invented in the late 1970s by Norm Cox for the Xerox "Star" personal workstation, the world’s first graphical user interface. The simple three line icon was originally meant to convey a list of items, but it was eventually found useful for navigation on mobile devices with small screens. (A good history can be found here).
Critics claim that from a user experience standpoint it is ambiguous and not everyone understands that clicking on it brings up a menu. Plus, it requires an extra click or tap to get to the menu and decreases navigation clicks overall. Proponents say it's a useful method for handling navigation on small devices and frees up screen space. Plus, its use for menus may now have reached a level where there's little confusion about what it communicates.
One thing is certain — if you're going to use a hamburger menu, don't place it on the left side of the screen. That's the hardest area to reach for a right-handed user and about 90% of people are right-handed. (Sorry left-handers).
In this lesson, we'll learn how to create a hamburger menu for mobile devices and narrow browser viewports that will convert to a regular "on page" menu when the browser reaches a minimum width of 900 pixels.
The page will contain a header in a <div> with a class of header-left. The navigation will be contained entirely within a <div> with a class of header-right.
Another feature of this lesson involves how to hide some of the navigation once the browser gets to 900 pixels width. That's shown below with a <div> with a class of hide. If you don't need to do that, simply remove <div class="hide"> and the closing </div> tags that surround those links.
If you don't need to indent any of the items in your hamburger menu, simply remove the nested unordered list <ul> and </ul> tags shown below for the "Urbino, Italy" and "Florence, Italy" links.
The code below is what was used to create the hamburger menu on this site, though it's been stripped down to its essential features for this lesson. An example of what we are about to create can be seen at drsteveanderson.com/hamburger.html. Here are links to two other files with slight changes to the layout (Link 1 | Link 2).
NOTE: In order to see the effect of the internal anchor links you'll need to add a few more paragraphs of text to the bottom of the page.
Parallax Scrolling | Above-the-Fold Header | Darkened Background Image
This section contains three lessons in one (for no extra charge).
First, we'll create a panel at the top of the page that uses what's called "parallax scrolling." Parallax scrolling is where the background image stays fixed while content on top of it scrolls up and down over it. In other cases, there might be multiple layers moving at different speeds. The visual effect creates the illusion of depth along the z-axis.
NOTE: Parallax scrolling using a fixed background image does not work on iOS devices (iPhones and iPads). However, you can use media queries to turn off the effect on mobile devices.
To create the parallax effect, we simply add background-attachment:fixed; and the three lines below it.
Second, we'll make the top panel fill the entire browser window (viewport) regardless of the size or shape of the window and regardless of what kind of device it's being viewed on. This allows an "above the fold" layout where you determine what the viewer sees before they start to scroll. The term "above the fold" comes from the world of newspapers where the most important material could be laid out above the fold on a newspaper as it sat in a newsstand. To make this happen, we'll simply add height:100vh; (vh stands for viewport height) to the <header> element which contains the background image.
Because we'll be placing text on top of the image we'll want to darken the image to provide better contrast. There are multiple ways to do that. The easiest way to do it might be to simply darken the image (reduce brightness) in Photoshop. However, a more effective method would be to use CSS to darken the image. One can't simply apply background-color:rgba(0, 0, 0, .5); because the background image would sit on top of it.
We'll need to use a property known as background-blend-mode. This property allows us to add a background color such as black background-color:rgba(0, 0, 0, 0.5); with 0.5 opacity and have it overlay the background image background-image:url("images/blend1.jpg");
Note in the code below that we have both a background image and a background color, but now both work because we've added the background-blend-mode property.
The result can be seen at: drsteveanderson.com/blend-color.html
The approach also works when overlaying two images, but you can get some pretty funky results when using this method. An example can be seen at: drsteveanderson.com/blend-images.html. Below shows the two separate images and the result after blending.
Note in the code below that blend2.jpg overlays blend1.jpg and that we have changed the value from darken to overlay. We have removed the background-color property by commenting it.
The CSS background-blend-mode property emulates the blending options found in the popular image editing program Adobe Photoshop. It takes two pixels laid on top of each other and combines them in different ways.
The background-blend-mode property allows the following values:
normal | multiply | screen | overlay | darken | lighten | color-dodge | saturation | color | luminosity
Sometimes, you may want some parts of the image to be darker than other parts. That is the case with the background image at the top of my home page. The text is on the left side of the layout, so we want to darken that area of the image more than the right side.
To do this, we'll use a linear gradient in conjunction with the background image. A linear gradient consists of two or more colors (or shades) along a straight line. Our code looks like this.
background: linear-gradient(to right, rgba(0,0,0,0.8), rgba(0,0,0,0.7), rgba(0,0,0,0.4), rgba(0,0,0,0.3), rgba(0,0,0,0.4)), url("images/background-panel1.jpg");
Notice that this one line of code includes both a black linear gradient with changes horizontally (left to right) to the alpha (opacity) at five different "stops" and a background image (background-panel1.jpg). Each stop is black (0,0,0), but we are varying the amount of opacity at each stop horizontally across the image.
Since the text will be on the left side of the layout, we have made the first stop the darkest with an opacity of point 8 (0.8). (The lower the value, the more transparent). We want the least darkening to be on the right side, so we've given that an opacity of point 3 (0.3) on the fourth stop.
We will create a page with parallax scrolling, an above-the-fold header, and a linear-gradient for shading like this one drsteveanderson.com/background-image.html
Download the Image for this Lesson
Another approach to darkening the background image is seen below with a pseudo element. Pseudo elements are used to insert content before, or after, the content of an element. In this case, we use an "after" pseudo element that looks like this. header::after
This method will use a vignette effect created with the box-shadow property to darken the outer edges of the image. In this case, it also leaves a lighter area on the right side of the screen.
Make the additions and changes below and see the effect.
The completed page using a vignette can be seen here: drsteveanderson.com/background-image-vignette.html
A slideshow is a sequence of images, most often with captions, that the user can manually cycle through one-by-one. Often, the slideshow is set up to automatically advance the slides over a certain interval of time.
To begin, you'll want to assemble a number of images that are all the same size and shape. You can use as few as two images in a slideshow, but most of the time they will contain somewhere between about 3 and 15 images.
We want the images to fill up the entire browser window from side-to-side, so we'll use rather large images. The images used in this lesson are all 2000 pixels X 974 pixels.
We will create a simple slideshow with four images, such as this one: drsteveanderson.com/slideshow.html
Here is an example of a slideshow that automatically advances the slides: drsteveanderson.com/slideshow-auto.html
In this section, we'll look at two of the newest CSS features that give users the power to determine how they want content on the page displayed based on settings in their operating systems. Media Queries Level 5 introduced so-called "preference media features" that use media queries to detect a user's preferred way to display content.
Two new media queries are shown in this lesson. The first one allows users to reduce or eliminate movement on their screens such as animations, transitions, and transforms. The second one allows users to switch from "light mode" to "dark mode" and vice versa. Browser support is relatively good for both features.
Not everyone appreciates fancy animations and transitions. Too much animation and parallax scrolling can be overwhelming and distracting. In some cases, people may even get motion sickness from too much movement on the screen. Motion sensitivity disorders may cause dizziness, migraine headaches, and even nausea.
Fortunately, there is a "reduce motion" setting in most operating systems. Those with motion sensitivity and those who simply want less motion can enable the setting in their device's preferences or settings.
Enable the setting on your device, then look at my portfolio home page to see how it removes the animations and the parallax scrolling effect. drsteveanderson.com
In order for the setting to work, web developers need to create pages that enable a new CSS media query known as prefers-reduced-motion. Note the @media (prefers-reduced-motion: reduce) media query in the lesson below.
The code above could be added to every page. Those who want animation will still see it, but those who prefer a non-amination experience will have that as well.
There has long been a bias against webpages with dark backgrounds. Light backgrounds have been considered cleaner and more professional. However, webpages with dark backgrounds can be elegant or dramatic and have been favored by entertainment (films, music, theater) sites that want to convey a sense of drama and excitement.
Dark backgrounds can actually be easier on the eyes and help you focus on your work. (Source) It's even been proposed that use of electronic devices before bedtime can lead to difficulty sleeping and shorter sleep duration. Using dark mode may help limit these problems.
Pages with dark backgrounds tend to draw less power and therefore lengthen battery life. That also means using less electricity for recharging. Power savings can be up to 60 percent. (Source)
Thanks to the new preference media features, one can now create pages that don't require a toggle and instead can deliver a light or dark color scheme based on a user's preference setting within their device's OS.
Users can enable light mode or dark mode in their device's preferences or settings, as shown below.
NOTE: In order for the changes to take effect on Edge for Windows, you need to tell the browser's default theme to use the "system default". (Edge: Settings and more (Alt+F) > Settings > Appearance > Default theme > System default).
Web developers need to create pages that enable a new CSS media query known as prefers-color-scheme. Note the @media (prefers-color-scheme: light) and @media (prefers-color-scheme: dark) media queries in the code below.
Visit any of the other pages on this site (such as the London, England page), then change the setting from light mode to dark mode on your device to see how the page can change. The difference is illustrated below.
In this lesson, we'll learn how to create a page with a few simple changes between dark and light. An example of what we'll create can be seen at: drsteveanderson.com/prefers-color-scheme.html.
The code base for this could be difficult to maintain without a smart implementation strategy. The use of "CSS custom properties" (or "variables") will help. Variables contain specific values that can be reused throughout a document. They are set using the following notation (--primary-color: red;) and are accessed with the var()function. See how variables are used in the CSS code below.
Note: Besides the values "dark" and "light", an earlier version of the spec included a third value, "no-preference". It was meant to indicate that the user has made no preference known to the system. Since no operating system or browser ever implemented it, the value was removed.
See the "Accessibility" section of http://css-tricks.com/a-complete-guide-to-css-media-queries for more preference media features.
The contact form on this site is located at the bottom of each page..
In this lesson, we'll learn how to create an HTML form where the form information is sent via email to a particular recipient or recipients. Due to concerns about spamming robots hijacking your form, we'll also add a CAPTCHA feature.
Spammers are constantly looking for exploitable web forms. At best, an unprotected form will simply mean your own spam will increase. At worst, the spammers can alter your email headers to send bulk unsolicited emails (known as "email injection") from your hosting account to thousands of others. This may result in a warning from your hosting company and they could even ban your site.
To avoid these problems, you'll want to enable form validation via CAPTCHA. CAPTCHA stands for Completely Automated Public Touring test to tell Computers and Humans Apart." The system requires that someone take some action, such as clicking a "I'm not a robot" checkbox, or correctly evaluating a sequence of letters or numbers contained within a distorted image. Another system has a user identify the areas of an image that contains certain objects (such as traffic lights). The form information will be sent only if the correct choices are made.
An even newer version (version 3) works transparently for website visitors. There are no challenges to solve. Instead, it continuously monitors the visitor’s behavior to determine whether it’s a human or a robot. Web developers need to decide which action to take depending on the score. Getting this configuration right is difficult for even the most experienced web developer. (Source)
Google provides a free CAPTCHA integration service known as reCAPTCHA. To set it up, simply login to your Google account and go to: http://www.google.com/recaptcha/admin. From there, you will need to "Register a new site."
On this screen, you can give your site a label. It's not important what you call it. This is only for distinguishing from among multiple sites. Give it a name that makes sense. You can choose as "reCAPTCHA type" the option reCAPTCHA v2. You can use the option "I'm not a robot" Checkbox. (Feel free to change these options and experiment later). Under "Domains", enter the domain name for the site you want to add reCAPTCHA to. The owner will be the email address you logged into Google with. Hit the submit button and it will take you to the next screen.
This page lists both your "SITE KEY" (aka public key) and your "SECRET KEY" (aka private key). I have blurred my keys so that the secret key won't be known to others. You'll need this information when you start coding.
Creating the HTML form is simple. Making the form send the data via email could be simple as well as long as the form action uses what's called a "mailto" action, as shown below.
<form action="mailto:firstname.lastname@example.org" method="POST">
The problem with using the "mailto" action is that once a user clicks on the submit button, they need to have their device set up to launch their email client application in order to send the form data. If the user has not done that or perhaps they are using someone else's device, the approach won't work.
To solve this problem, we'll use PHP to send the form data. PHP is a server-side scripting language meaning that in order for it to work, the PHP file (ending in .php) needs to be on a web server online. The submitted form data goes first to the PHP file which then formats it and sends it to the intended recipient (or recipients) as email. It can also work in conjunction with a MySQL database to store the data online.
NOTE: PHP stands for "PHP Hypertext Processor." It is what's called a recursive acronym in that the acronym refers to itself.
Using PHP will require a different form action, as shown below.
<form action="formsubmit.php" method="POST">
Notice that instead of using "mailto", the form action now forwards the form data to another file we've called formsubmit.php.
The diagram below shows how the process works. First, the user fills out the form (form.html) and hits submit. Next, the data from the form is passed along to a PHP file called formsubmit.php. Finally, the PHP file uses a built-in mail function to send the data via email to the specified recipient and it arrives in their in-box.
As you go through this lesson, remember that your HTML file and PHP file will need to be online to make the form work. All hosting companies (such as ionos.com or godaddy.com) should now make PHP available. Simply create form.html and formsubmit.php then upload them to your hosting account using an FTP application such as FileZilla.
We will create a basic form with reCAPTCHA like this one drsteveanderson.com/form.html
Another spam issue you'll want to consider is the harvesting of your email address that appears with your contact information. Most people will want to provide an email address as another way for people to get in touch with them. Email harvesting robots are constantly searching the web for valid addresses. If you leave yours unprotected, you'll end up with a significant amount of new spam.
There are a number of ways to protect this information from spam bots. Options include putting your email address into an image, replacing the address with a PHP script, or using HTML character entities. We'll focus on the latter two.
Instead of displaying your email address on the page, you simply provide a link to a PHP script that then loads the mailto for the address. Spam bots won’t be able to see the email address and if you ever need to change the email address, you'll only need to change it in the one PHP file.
You can see how it works at: drsteveanderson.com/email-hiding.html. Notice that even if you "View Source" on the page in your browser, the email address doesn't show up. You can't see it and neither can the spam bots.
With this method you'll change your ASCII email address into its equivalent decimal entity. You are essentially just encoding the characters of your email adress through the use of what are called "HTML character entities." (See https://www.w3schools.com/html/html_entities.asp). In this situation the ASCII character @ becomes @. The ASCII character for the lower-case letter a becomes a.
The characters of the email address email@example.com become...
Luckily, you don't have to look up all those substitutions yourself. Here's a website that will do it for you: http://wbwip.com/wbw/emailencoder.html. Just enter the text you want to convert, hit the encode button, and it will give you the HTML character entities you need.
Below is how you would make the email address firstname.lastname@example.org into a mailto link using HTML character entities.
Although it looks funny, it will look correct in the browser and will work fine in the client email application.
Using HTML character entities isn't as good a solution. Unfortunately, spam bots have gotten wise to this work-around and can automate the replacements.
In this lesson, we'll make a video playlist where YouTube videos are embedded into the page. "Embedding" means that the video will play right on the page instead of being linked and taking us off the page. Note: Besides using YouTube, this can also be done with other streaming services such as Vimeo. Or, it can be done with video files (such as .mp4 files) that are uploaded to your own hosting account.
We will create a playlist of six videos. The list of videos will appear on the left side of the screen in what's called an iFrame. An iFrame essentially allows you to put a web page (or pages) within another web page. The iFrame window can bet set to a particular size, thus allowing users to scroll up and down to see the whole list of videos. The videos will play in a second iFrame on the right side of the screen.
How it Works
In this example, the page video-playlist.html creates the layout with two iFrames. Shown below, they are labelled iframe-list and iframe-video. The page loads another html file into the iframe-list section called video-list.html. It also loads an image, tvnews.jpg, into the iframe-video section.
When the user clicks on one of the items in the iframe-list, it loads another HTML file (in this case vid-play1.html) into iframe-video. This HTML file contains the embed code to play the first YouTube video.
You can see what we'll be creating at: drsteveanderson.com/video-playlist.htmlSTEP 1
Next, we're going to have to acquire the embed code for each YouTube video. Follow these steps.
Do this for each of the videos you'll want to include in the playlist.
Next, we will need to create the following eight HTML files...
CREATE PAGES LIKE THE ONE ABOVE FOR THE REMAINING VIDEOS.
Instead of uploading to YouTube or Vimeo, simply upload your .mp4 video files to your hosting account. It might be a good idea to put them into a folder called videos.
Replace the HTML code in vid-play1.html with the code below.
Notice the code above includes an attribute called autoplay and an attribute called controls. If you don't want your video to autoplay, simply remove the attribute. If you don't want the video to bring up playback controls (such as play and stop), remove the "controls" attribute.
Other optional attributes include:
Another option eliminates the need for separate HTML files to play each of the .mp4 videos. Instead of linking to an HTML file that plays the video, video-list.html links directly to the .mp4 file. Below is how the link to the first video would look.
Of course, with this method you don't have the ability to utilize attributes.
Video backgrounds can be effective when used well. However, they can also be busy and distracting. Another big concern regards page load time. Videos are usually large files and can take a long time to load on a site potentially slowing down the rest of the content on your page.
Video backgrounds can be visually appealing and provide a dramatic effect. In some cases, a video may do more to communicate the essence of your site than a still image or text might accomplish. 11 Coffee & Co. is a site that does this well.
The Urbino, Italy page on this site also makes use of a video background at the top of the page. This is the way most video backgrounds are done -- using it in place of a "hero image."
You can see what we'll be creating at: drsteveanderson.com/video-back.html
Download the Video for this Lesson
Instead of laying in the video as a true background element, we'll use the power of CSS Grid to stack one <div> on top of another <div>.
Notice that the video will be in a <div> with a class of back. We'll give it a z-index of one. Notice that the text ("HELLO FROM URBINO") will be contained in a <div> with a class of front. We'll give it a z-index of 2 to make sure it sits on top of the video.
We'll place the front layer exactly on top of the back layer using CSS Grid. In this case, the container is set up to make a three column grid. Both elements will start on column line 1 and end on column line 4. And, they will start on row line 1 and end on row line 2.