Weather Forecast has now been on our site. Check it out!
📖 1.6.1. Introduction
Way to go! The Run Buddy landing page is nearly complete. Along the way, you've learned a lot of new web development concepts that you'll use throughout your career as a full-stack web developer.
The following image shows the current state of the Run Buddy landing page:
In this lesson, you'll accomplish the following objectives:
Reuse CSS rules to avoid writing duplicate code.
Create a two-column layout with the CSS display property.
Implement an <iframe> element to bring in information from another website.
📖 1.6.2. Preview
We have a new request from the folks at Run Buddy. The sales team wants us to build a contact section (called Reach Out) that invites visitors to ask questions or voice concerns. Like the sign-up form on the homepage, it's also another opportunity to encourage customer interaction and generate sales leads.
Just like we always do, let's start by looking at the mock-up, shown in the following image:
Here's a quick look at the build process, which (as usual!) starts with adding the HTML and then the styling:
Build the map. You'll embed code from Google Maps to add an interactive map to the contact section.
Create the contact info. You'll add Run Buddy's contact info using a new <address> element and a special URL for the company's email address.
Add some class. Use CSS to set the correct background colors and text alignment.
Add styles to the <iframe> and contact info. You'll use CSS instead of HTML attributes to define the <iframe>'s dimensions.
Design a two-column layout. You'll learn how to target multiple, different selectors with a single CSS rule.
📖 1.6.3. Build the Map
Let's start with building the map. The following image shows what we're aiming for:
Begin with the HTML for the Reach Out section that you set up previously:
<!-- "reach out" section -->
<section>
<h2>Reach Out</h2>
</section>
Under the <h2> element, inside the Reach Out section, we need to add a <div> which will act as a container for the body of content in this section. All of the contact information is conceptually related, so wrapping it in a parent element enables us to constrain its flow. Let's add a class called contact-info to this <div>, which we can now call the contact container.
The requirements from the design team made it clear that this map needs to be interactive, meaning that visitors must be able to scroll, move, and zoom on the map. But how do we make that happen?
Fortunately, there is a special HTML element called an <iframe> that helps us do just this! An <iframe>, which means inline frame, nests browsing content and embeds an HTML page into the current page. An <iframe> can add rich features to a website, including videos with playback controls, GIFs, and maps. One caveat, however, is that not all websites support this feature.
In this case, the <iframe> will contain a map of Run Buddy's address from Google Maps. Let's place the <iframe> inside the contact container.
Follow these steps to retrieve an <iframe> for the address:
Enter your address in the search box on Google Maps
Select the Share icon.
Choose the Embed a map tab.
Select the COPY HTML link to copy the <iframe> element.
The Google Maps page should look something like the following image:
Paste the <iframe> element into the contact-info container. After adding the <iframe> element, the HTML for the map should look similar to the following code:
<div class="contact-info">
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3147.1079747227936!2d-120.42364418397035!3d37.92790791110593!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x8090c49129b6ac57%3A0xb56c7eb95a2cd8bd!2sMain%20St%2C%20California%2095327!5e0!3m2!1sen!2sus!4v1616426329495!5m2!1sen!2sus"
width="600"
height="450"
style="border:0;"
allowfullscreen=""
loading="lazy">
</iframe>
</div>
Notice how the <iframe> element includes not only the URL but also some other attributes, like the width and height. Let's adjust a few of these attributes to enable the interactive controls for Google Maps, as shown in the following code:
<iframe
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3147.1079747227936!2d-120.42364418397035!3d37.92790791110593!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x8090c49129b6ac57%3A0xb56c7eb95a2cd8bd!2sMain%20St%2C%20California%2095327!5e0!3m2!1sen!2sus!4v1616426329495!5m2!1sen!2sus"
width="400"
height="400"
style="border:0;"
allowfullscreen=""
loading="lazy">
</iframe>
IMPORTANT
We edited the height and width attributes of the <iframe> to render a larger map that allows us to test user interactivity; the default size wasn't ideal to enable controls.
Let's examine the attributes for the <iframe>:
The src attribute is the most important attribute; without it, nothing will render. The src value is a URL path linking to the external website content that will be embedded. This should be familiar because it's the same attribute used in the <img> element.
The style attribute is an inline style to set no border, for newer browsers.
The allowfullscreen attribute offers a link to view the map on a new page in full-screen mode. Some attributes are properties that can be turned on by simply adding the attribute. Notice how allowfullscreen doesn't have any value assignment. Another popular attribute that doesn't have a value assignment is checked for a checkbox input element.
LEGACY LORE
The frameborder attribute is no longer supported by HTML5 and new browsers, so we'll use the border property from CSS to declare this property. We wouldn't typically worry about old-browser support, but Google likes to cover all its bases because they have a global reach and billions of visitors every day.
Like all technology, browsers have changed over time. Browser enhancements, such as tabbed browsing and phishing filters, have improved user experiences, but certain properties were deprecated or no longer supported in favor of offloading the work onto new technologies like CSS. For more information, see Wikipedia on browser histories and the browser wars.
The following image shows what the <iframe> looks like now:
Take a moment to play with the map using the zoom and scrolling functionality. Pretty cool!
These interactive controls aren't actually a part of the <iframe>, but rather helpful controls that Google adds when it detects a map being rendered inside an <iframe>.
It's important to note that with the power of the <iframe> also comes responsibility. Be careful when using an <iframe> from websites that might be copyrighted. Security risks should also be assessed because an <iframe> from a compromised website might prove to be dangerous.
📖 1.6.4. Create the Contact Info
In this step, we'll add Run Buddy's company contact information to the Reach Out section. The design team wants the contact info contained in a column format, so let's look at the mock-up and plan how we'll proceed.
You can see the mock-up of that section in the following image:
Let's add the heading and text first. Create a <div> container with an <h3> and a <p> element, and add their content.
When you're done, the first part of the HTML after the <iframe> should look like the following code:
<div>
<h3>Run Buddy</h3>
<p>
Any questions or concerns before signing up?
<br />
Let us know and we'll be happy to talk to you!
</p>
</div>
This part should've been more or less straightforward. We chose the <h3> element because, as you'll remember from earlier lessons, best practice states that headings with less importance should have a higher heading number.
Let's look at a new element introduced in the preceding code: <br />. This element creates a line break. We're using a self-closing tag because this element has no content or child elements. We could've just added another <p> element for the second line of text, but in programming, sometimes there are multiple "correct" solutions and we happened to choose <br />.
Now save and render this in the browser. You should see something resembling the following image:
The next step will be to add the address content to the HTML using another new (to us) element called <address>.
The <address> element defines the contact information for the author/owner of a document or an article. If the <address> element is inside the <body> element, it represents contact information for the document. The <address> element will contain Run Buddy's physical address, phone number, and email address. Please note that the design team requires that the email address be a link that opens the user's default email application and begins a new email with the "To:" field populated with Run Buddy's email address, info@runbuddy.io.
Go ahead and add the following HTML:
<div>
<h3>Run Buddy</h3>
<p>
Any questions or concerns before signing up?
<br />
Let us know and we'll be happy to talk to you!
</p>
<address>
55 Main Street <br/>
Some Town, Ca <br/>
12345<br />
P: 555.RUN.BUDZ (555.786.2839)<br/>
E: <a href="mailto:info@runbuddy.io">info@runbuddy.io</a>
</address>
</div>
Let's examine the preceding code:
The <address> element defines the contact information for the author or owner of the document or parent element.
The <a href="mailto:info@runbuddy.io"> element uses the mailto: prefix in the anchor tag's href attribute to instruct the browser to open the default mail client application upon clicking the link. Then it populates the address field with the email address in the href value.
For more information, refer to the MDN Web Docs on the anchor element
Let's save and then refresh again in the browser to see something like the following image:
Before moving on, use the following commands to save your progress using Git:
git add -A
git commit -m "add iframe"
git push origin main
Great! All the content is there, so it's time to apply some CSS styling to jazz it up.
📖 1.6.5. Add Some Class
Now that the HTML for this section has been added, it's time to flex the CSS muscles again. The first step is to add classes to the HTML elements that we want to target for styling in the style sheet.
Let's practice some of the skills we've learned in previous lessons on the HTML that's already in place, beginning with the Reach Out section, shown in the following code:
<!-- "reach out" section -->
<section>
<h2>Reach Out</h2>
...
</section>
Currently, the link in the nav element that should bring us to this section on click doesn't work, so let's fix it. Apply an id attribute to the <section> tag so that the href value inside the nav element is linked to it:
<section id="reach-out">
While you're at it, add class attributes to the <section> and <h2> tags. Create the corresponding CSS rules to add the blue background (#024e76) and center alignment to the <section>. We can call this class contact.
The <h2> should have classes to give it a yellow font color (#fce138), center alignment, and a teal bottom border. The result should look something like the following image:
Look at the HTML for the previous sections and headings for a workable template for this step. Whenever a style pattern starts to emerge, it is important to recognize where code might be repeated and try to assign that class to the element to replicate the styles.
After having spent some time adding classes to the HTML, the opening <section> and <h2> tags in the Reach Out section should now look something like the following code:
<!-- "reach out" section -->
<section id="reach-out" class="contact">
<h2 class="section-title secondary-border">Reach Out</h2>
Let's review this solution and see if our choices made sense. We created a new class called contact for this section's blue background color and center alignment. We reassigned the class section-title to the section heading because many of the same styles are needed for style consistency in the document such as font-size, margin, padding, and border.
The font color for the section heading will need to be reassigned, but that's still a nice optimization of code as opposed to rewriting these four declarations again. For reference, the following code shows the .section-title style rule that we created earlier:
.section-title {
font-size: 55px;
display: inline-block;
padding: 0 100px 20px 100px;
border-bottom: 3px solid;
margin-bottom: 35px;
color: #024e76;
}
If, however, three or four of these declarations were not complimentary to the heading for this section, we probably would've needed to rewrite the rule.
What else did we do here? Knowing that we need a teal bottom border, we added the secondary-border class to the <h2> element. And we added the id reach-out to the section element to connect to the "#reach-out" link in nav element.
Now let's examine the following solution for the CSS rules:
/* REACH OUT STYLES START */
.contact {
text-align: center;
background: #024e76;
}
Let's save and render the changes into the browser to review the current progress, as shown in the following image:
Just as we did in previous sections, we added declarations to the CSS rule that targets the contact class to add some distinct style to the Reach Out section. For this rule, we updated the background color and center-aligned the <div> container that includes the map and contact info.
The section heading appears to be missing, however, and the design team would certainly not be happy about that! What did we forget to do? Ah yes, we were supposed to reassign the heading font color to yellow.
Let's add that now, as shown in the following code:
.contact h2 {
color: #fce138;
}
Save and view the page in the browser to see your changes. You should see something like the following image:
Very nicely done! Now it looks like we're ready to style the <iframe> and contact info container.
📖 1.6.6. Style the Contact Info
It's time for the final styling steps to complete the Reach Out section. When this is done, you'll be finished with the entire landing page!
Let's start with the <iframe> and create the CSS rule that will give us some of the size dimensions. But wait, didn't we do that already in the HTML with the attributes?
We can use CSS to declare the height and width of the <iframe>. Remove the attributes that were declared in the <iframe> for the width and height.
The Principle of Single Responsibility is a doctrine in computer science for best practice design patterns that (in this case) would suggest that styling should be contained to the style sheet and the HTML file reserved entirely for HTML markup purposes. This way, if a style needs to be changed, we would go to the style sheets and not the HTML. Also note that reassignment of a CSS property isn't possible with inline styling because external style sheet references are overwritten by inline styles. In other words, a style on an HTML element created with "style=" takes precedence over any style rules that a CSS sheet would normally apply to it.
To learn more, refer to the Wikipedia page on software design patterns
In this next styling step, we'll give the <iframe> a height and width.
When creating a new rule, always start with the selector. Think about the element you want to target.
In style.css, to style the <iframe>, add a CSS rule that looks like the following code:
.contact-info iframe {
width: 400px;
height: 400px;
}
This might be a little different than your implementation, so let's break down this rule a little further to see the "why" behind our choices.
.contact-info iframe was chosen, but iframe would've worked just as well, because there is only one <iframe> in this project. But what happens if another <iframe> is added, either in this HTML file or in any HTML file linking to this style sheet? This rule would style every <iframe> element, which could add styling where it wasn't wanted and lead to surprising results.
A type selector is a CSS selector (in this case, iframe) that selects every HTML element of that type. This is a potentially dangerous choice due to possible side effects (unless a global rule is needed). By using the class as the CSS selector, also called a class selector, we can safely target the <iframe> that's a descendant or child of the element with this class.
📖 1.6.7. Design a Two-Column Layout
The design team has requested that the map and contact information containers sit next to each other in a two-column layout. Let's look at the following mock-up image and figure out what to do from there:
How would you go about doing this? Try it on your own.
Create a CSS rule with the direct child <div> nested in the <div> parent element with the class .contact-info to reassign the display and width properties.
Your code should look something like the following example:
.contact-info div {
width: 410px;
display: inline-block;
vertical-align: top;
text-align: left;
margin: 30px 0 0 60px;
color: white;
}
It is important to note that in the preceding CSS rule targeting the child <div>, we overwrote the default display property for a <div> and changed it from block to inline-block. This allows the .contact-info container to sit on the same row as the <iframe> element and allows us to assign a width, something that the property value inline wouldn't let us do.
Another important property used here is the vertical-align property.
PAUSE What's the purpose of the vertical-align property, and what problem does it solve here?
Because the content of this <div> naturally rests at the bottom of the container, we need the vertical-align property to lift this content up to the top. In conjunction with the text-align property, this allows the contact information to begin at the top of the <div> and start aligned from the left for an easy-to-read layout.
Let's take a break to see how the code is rendering in the browser. Also, it's a good time to add and commit because you just made a big leap in progress. Use these commands to do that:
git add -A
git commit -m "style contact info"
In the following CSS rules, let's refer to the mock-up and see what the following steps must be. Looks like we'll be applying some font color (#fce138) and size to the <h3>, adding spacing, line height, and font size to the contact info content, and changing the link color to yellow (#fce138).
Using Chrome's DevTools is a great way to try out different spacing and color combinations. Use the CSS box model to add some pixels to the different layers for each element to see what looks best.
Use the property for line-height to adjust how to stretch out or shrink the text to find the best matching measurement that aligns with the mock-up.
The following code shows the last CSS rules that we need to add to style.css to adjust some of the text:
.contact-info h3 {
color: #fce138;
font-size: 32px;
}
.contact-info p, .contact-info address {
margin: 20px 0;
line-height: 1.5;
font-size: 20px;
font-style: normal;
}
.contact-info a {
color: #fce138;
}
/* REACH OUT STYLES END */
Note that the second CSS rule targets two different elements. The comma separates the two selectors, indicating that the subsequent declaration block will apply to both CSS selectors.
Save the file, reload index.html in the browser, and behold the beautiful result! It should resemble the following image:
Congrats! You've completed the landing page and created a professional layout.
That completes the work for this lesson, so it's time to push it up to GitHub by using the following commands:
git add -A
git commit -m "meet the trainers section"
git push origin main
Before you move on, take the following knowledge check:
📖 1.6.8. Reflection
Modern websites demand interesting ways to deliver content. The skills you learned today will allow you to deliver that in your career as a web developer. You continued to build on your skills by using more advanced HTML elements, including building an interactive map and implementing a two-column layout. Nice job!
Here is what you accomplished during this lesson:
Gained more experience with the webpage build process, starting with the HTML and then adding style.
Reused CSS rules by applying CSS class selectors to achieve an efficient and clean codebase without repeating code.
Created a two-column layout by creating container elements to a set width and declaring the display: inline-block;.
Implemented a unique HTML element called an <iframe>, which allows nested browser content from another HTML page to be embedded into the current one. This offers user interactivity and interoperability with another website, and adds rich visual features without needing to write a lot of code.
In the next lesson, you'll get a chance to add a page to the site when you create Run Buddy's Privacy Policy page.
Download the code snapshot for this lesson to compare with your own code. It’s okay if your code isn’t exactly the same—use this code snapshot as a starting point for the next lesson.