3
\$\begingroup\$

I would appreciate som feedback on my fictional product landing page. I am doing the freeCodeCamp curriculum and Product Landing Page is one of the Responsive Web Design Projects using only HTML/CSS.

I am especially interested in feedback regarding best practice, naming conventions and efficient code.


The code is also on GitHub.

HTML file:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <link rel="stylesheet" href="css/style.css" />
        <script src="https://kit.fontawesome.com/4dd9b52bee.js"></script>
        <title>Fireworks</title>
    </head>
    <body>
        <header id="header">
            <div class="flex-row-center">
                <div>
                    <img
                        id="header-img"
                        src="img/Logo.png"
                        alt="Company logo"
                        width="1068px"
                        height="132px"
                    />
                </div>
                <nav id="nav-bar">
                    <ul class="flex-row">
                        <li><a href="#showcase" class="nav-link">Home</a></li>
                        <li><a href="#pricing" class="nav-link">Pricing</a></li>
                        <li><a href="#newsletter" class="nav-link">Newsletter</a></li>
                    </ul>
                </nav>
                <div class="social-icons">
                    <ul class="flex-row">
                        <li>
                            <a href="#"><i class="fab fa-facebook-f"></i></a>
                        </li>
                        <li>
                            <a href="#"><i class="fab fa-twitter"></i></a>
                        </li>
                        <li>
                            <a href="#"><i class="fab fa-instagram"></i></a>
                        </li>
                    </ul>
                </div>
            </div>
        </header>

        <aside class="social-icons">
            <ul>
                <li>
                    <a href="#"><i class="fab fa-facebook-f"></i></a>
                </li>
                <li>
                    <a href="#"><i class="fab fa-twitter"></i></a>
                </li>
                <li>
                    <a href="#"><i class="fab fa-instagram"></i></a>
                </li>
            </ul>
        </aside>

        <main>
            <section id="showcase">
                <div class="flex-column-center left-align content">
                    <p class="sub-header">Get ready for</p>
                    <h1>
                        <i class="logo-icon fas fa-haykal fa-xs"></i
                        >Fireworks<br />of flavors
                    </h1>
                </div>
                <div class="product-video flex-row-center">
                    <div class="video-container">
                        <video id="video" autoplay loop muted>
                            <source src="video/fireworksHD.mp4" type="video/mp4">
                            <source src="video/fireworksHD.webm" type="video/webm">
                            <source src="video/fireworksHD.ogv" type="video/ogv">
                        </video>
                    </div>                  
                </div>
                <div class="product-img flex-row-center">
                    <img class="standard_img" src="img/Product.png" alt="Fireworks coffee" />
                    <img class="mobile_img" src="img/Product_mobile.png" alt="Fireworks coffee" />              
                </div>
            </section>

            <section id="pricing">
                <div class="flex-row-center content">
                    <div class="flex-column-center left-align">
                        <h2>Pricing</h2>
                        <h3 class="sub-header">Monthly subscription</h3>
                    </div>                    
                    <div class="flex-row container-centered shadow">
                        <div class="price-tag">
                            <h3>Personal</h3>
                            <ul>
                                <li>&dollar;<strong class="price-strong">10</strong>/mo</li>
                                <li>10 bags of coffee</li>
                                <li><a class="btn" href="#">Order Now</a></li>
                            </ul>
                        </div>
                        <div class="price-tag focus-line">
                            <h3 class="focus">Professional</h3>
                            <ul>
                                <li>&dollar;<strong class="price-strong">150</strong>/mo</li>
                                <li>200 bags of coffee</li>
                                <li><a class="btn focus-bg" href="#">Order Now</a></li>
                            </ul>
                        </div>
                        <div class="price-tag">
                            <h3>Corporate</h3>
                            <ul>
                                <li>&dollar;<strong class="price-strong">600</strong>/mo</li>
                                <li>1000 bags of coffee</li>
                                <li><a class="btn" href="#">Order Now</a></li>
                            </ul>
                        </div>
                    </div>
                </div>
            </section>

            <section id="newsletter">
                <div class="flex-row-center content">
                    <div class="flex-column-center left-align">
                        <h2>Newsletter</h2>
                        <h3 class="sub-header">Let's keep in touch</h3>
                    </div>                    
                    <div class="flex-row container-centered shadow">
                        <form class="flex-column"
                            action="https://www.freecodecamp.com/email-submit"
                            method="GET"
                            id="form"
                        >
                            <h3 class="focus">E-mail subscription</h3>
                            <input
                                id="email"
                                type="email"
                                name="email"
                                placeholder="Enter your e-mail"
                            />
                            <input class="btn focus-bg" id="submit" type="submit" value="Submit"/>
                        </form>
                    </div>
                </div>

            </section>
        </main>

        <footer>
            <p class="footer-text">
                &copy; 2019 Fireworks all rights reserved
            </p>
            <div class="footer-logo">
                <img
                        id="header-img"
                        src="img/Logo.png"
                        alt="Company logo"
                        width="1068px"
                        height="132px"
                    />
            </div>
        </footer>
    </body>
</html>

CSS file:

/* Color scheme */
:root {
    --background: #000;
    --background-dark: #555;

    --text-standard: #ccc;
    --text-subtle: #777;
    --text-title: #fff;
    --focus: #f98836;
    --focus-highlight: #e27426;
}

/* Basic Reset */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/* Setup */
body {
    background-color: var(--background);
    color: var(--text-standard);
    font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
    font-size: 1rem;
    font-weight: 400;
    overflow-x: hidden;
}

img {
    width: 100%;
    height: auto;
}

a {
    text-decoration: none;
    color: var(--text-title);
}

ul,
li {
    list-style: none;
}

input[type="submit"] {
    border: none;
    font-size: 1rem;
}

.logo-icon {
    color: var(--focus);
    margin-right: 0.1em;
    transform: translateY(-0.1em);
}

h1 {
    font-size: 4rem;
    color: var(--text-title);
    text-transform: uppercase;
}

h2 {
    font-size: 3rem;
    color: var(--text-title);
    text-transform: uppercase;
}

h3 {
    font-size: 1.1rem;
    color: var(--text-title);
    text-transform: uppercase;
}

.sub-header {
    color: var(--focus);
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    margin-top: 1rem;
}

/* Utility classes */
.flex-row-center {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
}

.flex-column-center {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
}

.flex-row {
    display: flex;
}

.flex-column {
    display: flex;
    flex-direction: column;
}
.container-centered {
    margin: auto;
}

.left-align {
    align-items: flex-start;
    text-align: left;
    width: auto;
}

.content {
    position: relative;
    z-index: 2;
    padding: 12rem 10rem 12rem 6rem;
}

.shadow {
    box-shadow: 5px 20px 60px rgba(0, 0, 0, 0.7), 5px 5px 100px rgba(255, 255, 255, 0.2)
}

.focus {
    color: var(--focus);
}

body .focus-bg {
    background-color: var(--focus);
}

.mobile_img {
    display: none;
}

/* Buttons */
.btn {
    background-color: var(--background-dark);
    padding: 0.5rem 1.5rem;
    width: 100%;
    color: var(--text-title);
}

body .btn:hover {
    background-color: var(--focus-highlight);
}

/* Header */
header {
    position: fixed;
    top: 0;
    left: 6rem;
    padding-top: 3rem;
    z-index: 100;
}

header::before {
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 7rem;
    background: linear-gradient(to bottom, #0006, #0006 60%, #0000);
    z-index: -1;
}

header img {
    width: 12rem;
}

header .social-icons {
    display: none;
    position: fixed;
    right: 3rem;
    top: 2.5rem;
    align-items: flex-end;
}

header .social-icons li {
    margin-left: 2rem;
}

/* Nav */
#nav-bar a {
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0.5em;
    margin-left: 5rem;
    text-transform: uppercase;
}

#nav-bar a:hover {
    color: var(--focus);
}

/* Aside */
.social-icons {
    position: fixed;
    top: 50%;
    right: 4rem;
    transform: translateY(-50%);
    z-index: 100;
}
.social-icons a {
    color: var(--text-subtle);
}

.social-icons li {
    margin: 2rem 0;
}

/* Showcase */
#showcase {
    width: 100vw;
    height: 100vh;
    background: radial-gradient(#ffffff34, #ffffff17);
}

#showcase .product-img {
    position: absolute;
    top: 0;
    left: 10rem;
    z-index: 1;
    overflow: hidden;
}

#showcase img {
    max-width: 1600px;
}

#showcase .product-video {
    position: absolute;
    top: 0;
    left: 10rem;
    z-index: -1;
    overflow: hidden;
}

#showcase .video-container {
    max-width: 1600px;
}

#showcase .product-video video {
    width: 100%;
}

#showcase .sub-header {
    margin-bottom: 1rem;
}

/* Pricing */
#pricing {
    width: 100vw;
    height: 100vh;
    background: radial-gradient(#ffffff34, #ffffff17);
}

.price-tag {
    color: var(--text-subtle);
    width: 12rem;
    padding: 2rem 1rem 1rem 1rem;
    border: 1px solid;
    border-color: var(--text-subtle);
    justify-content: flex-start;
}

.price-strong {
    color: var(--text-title);
    font-size: 2em;
    margin: 0 0.1em;
}

#pricing li {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 2rem 0 0 0;

}

#pricing li:first-child {
    margin-top: 0.3rem;
    margin-bottom: 0;
}

#pricing li:last-child {
    margin-top: 2rem;
}

.focus-line {
    border-color: var(--focus);
    border-width: 1.5px;
    outline: 2px solid;
    outline-color: var(--focus);
    z-index: 100;
}


/* Newsletter */
#newsletter {
    width: 100vw;
    height: 100vh;
    background: radial-gradient(#ffffff34, #ffffff17);
}

#newsletter form {
    width: 32rem;
    border: 1px solid;
    border-color: var(--text-subtle);
    padding: 2rem 4rem;
}

#newsletter form h3 {
    margin-bottom: 1rem;
}

input[type="email"] {
    padding: 0.5rem;
    margin: 1rem 0;
}

/* Footer */
footer {
    position: relative;
    z-index: 100;
}

footer::before {
    content: "";
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 7rem;
    background: linear-gradient(to top, #0006, #0006 60%, #0000);
    z-index: -1;
}

.footer-text {
    position: fixed;
    left: 6rem;
    bottom: 3rem;
    color: var(--text-subtle);
    text-transform: uppercase;
}

.footer-logo {
    position: fixed;
    right: 8rem;
    bottom: 3rem;
    color: var(--text-subtle);
    width: 7rem;
    opacity: 0.3;
}

/* Media queries */

@media only screen and (max-width: 1200px) {
    #pricing > .flex-row-center,
    #newsletter > .flex-row-center {
        flex-direction: column;
    }
    #pricing .left-align,
    #newsletter .left-align {
        align-items: center;
        text-align: center;
        justify-content: flex-end;
        flex: 0;
    }
    #pricing .sub-header,
    #newsletter .sub-header {
        margin-bottom: 4rem;
    }
}

@media only screen and (max-width: 1000px) {
    aside.social-icons,
    #nav-bar {
        display: none;
    }
    header .social-icons {
        display: flex;
    }
    header img {
        width: 8rem;
    }
    .content {
        padding: 6rem 3rem 6rem 3rem;
    }
    #pricing .content,
    #newsletter .content {
        padding: 10rem 3rem 10rem 3rem;
    }
    header {
        left: 3rem;
        padding-top: 2rem;
    }
    #showcase .left-align {
        align-items: center;
        text-align: center;
        justify-content: flex-start;
    }
    .footer-text {
        left: 3rem;
        bottom: 2rem;
    }
    .footer-logo {
        right: 3rem;
        bottom: 2rem;
    }
    #showcase .product-img,
    #showcase .product-video {
        top: 15%;
        left: 0;
    }
    h1 {
        font-size: 3rem;
    }
    h2 {
        font-size: 2.3rem;
    }
}
/* Tablet 768px */
@media only screen and (max-width: 768px) {
    #showcase .product-img,
    #showcase .product-video {
        top: 10%;
        left: 0;
    }
    #pricing {
        height: auto;
    }
    #pricing .flex-row {
        flex-direction: column;
    }
    #pricing .flex-row,
    .price-tag {
        width: 100%;
    }
    .price-tag {
        padding: 2rem; 
    }
    #newsletter .flex-row,
    #newsletter form {
        width: 100%;
    } 
    #newsletter form {
        padding: 2rem 2rem;
    }
}

/* Phone 568px */
@media only screen and (max-width: 568px) {
    header .social-icons li {
        margin-left: 0.8rem;
    }
    #pricing .content,
    #newsletter .content {
        padding: 1rem 2rem 5rem 2rem;
    }
    h1 {
        font-size: 2rem;
    }
    h2 {
        font-size: 1.8rem;
    }
    .footer-logo {
        display: none;
    }
    .footer-text {
        left: 0;
        width: 100%;
        text-align: center;
        padding: 0 2rem;
        font-size: 0.8rem;
    }
    #newsletter {
        height: auto;
    }
    #showcase img,
    #showcase video {
        width: 150%;
        left: -25%;
    }
    #video {
        display: none;
    }
    .standard_img {
        display: none;
    }
    .mobile_img {
        display: inline-block;
    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to Code Review! "this is one of the Responsive Web Design Projects", which one specifically? \$\endgroup\$ – Mast Aug 29 '19 at 11:47
  • 1
    \$\begingroup\$ Thank you! Build a Product Landing Page. Link to website \$\endgroup\$ – Øyvindsen Aug 29 '19 at 11:52
3
\$\begingroup\$
width="1068px"
height="132px"

The width and height attributes can’t contain "px".

width="1068"
height="132"

The alt value for the logo should not contain "logo", just the company name.


<i class="fab fa-facebook-f"></i>

Don’t use the i element if you just want to display an icon via CSS. The i element has a meaning which isn’t appropriate for this (details). Use the span element instead.

<span class="fab fa-facebook-f"></span>

<h1>
  <i class="logo-icon fas fa-haykal fa-xs"></i
  >Fireworks<br />of flavors
</h1>

Don’t use the br element if you want to show a line break just because of aesthetic reasons. The br element must only be used for meaningful line breaks (details). Use a span element and CSS to add the line break.

<h1>
  <span class="logo-icon fas fa-haykal fa-xs"></span
  >Fireworks <span class="separator">of flavors</span>
</h1>

Your use of heading elements is not consistent. Your first section starts with h1, your second section starts with h2. While this is not an error, it’s a good practice to be consistent: either use h1 everywhere, or (preferably) use the heading elements of the correct rank, i.e., start with h2 in top-level sections.


<h2>Pricing</h2>
<h3 class="sub-header">Monthly subscription</h3>

Don’t use a heading element for sub-headings (details). This creates a wrong document outline. Use a p element instead.

<h2>Pricing</h2>
<p class="sub-header">Monthly subscription</p>

/mo

You can use the abbr element here.

<abbr title="per month">/mo</abbr>

<p class="footer-text">
    &copy; 2019 Fireworks all rights reserved
</p>

You can use the small element here (details).

<p class="footer-text">
  <small>&copy; 2019 Fireworks all rights reserved</small>
</p>

Both of your logo img element have the same id value. An id value can only be used once per page.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Thank you for your detailed feedback! Exactly what I was looking for. Regarding heading elements, I have now wraped a h1 tag around my logo image in the header and changed all my top-level-sections to h2. I'm a bit unsure if this is the correct use of the h1 tag, but I see Facebook is doing the same so I guess it is ok. \$\endgroup\$ – Øyvindsen Aug 30 '19 at 11:35
  • \$\begingroup\$ @Øyvindsen: I would say having the site name (whether it’s text or a logo) as h1 is ideal; many people disagree because they have the (outdated, I would say) assumption that h1 should only be used for the main content, but this would typically lead to a wrong document outline. -- You can check the document outline with validator.w3.org/nu -- there is a checkbox "outline". \$\endgroup\$ – unor Aug 30 '19 at 12:28
  • \$\begingroup\$ Thanks. I'm already familiar with the validator. Guess I need to remember to use it more often. Now the outline looks good. It just takes the alt value from the image as the h1 text. \$\endgroup\$ – Øyvindsen Aug 30 '19 at 14:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.