2
\$\begingroup\$

I would appreciate som feedback on my fictional survey form. I am doing the freeCodeCamp curriculum and a Survey Form 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" />
        <title>Healthy Eating</title>
    </head>

    <body>
        <main>
            <form id="survey-form" action="#" method="GET">
                <header>
                    <h1 id="title">Survey Form</h1>
                    <div class="grid-columns">
                        <p id="description">
                            Our job at <strong>Healthy Eating</strong> is to map
                            the eating habbits of the population.

                            <span class="new-line">Please
                            fill in the form below to help us with our work.</span>
                        </p>
                        <div class="col">
                            <img src="img/carrot-solid.svg" alt="Icon" />
                        </div>
                    </div>
                </header>

                <div class="row">
                    <section id="p-info">
                        <h2>
                            Personal information
                        </h2>
                        <label class="main-label" id="name-label" for="name"
                            >Name</label
                        >
                        <input
                            type="text"
                            name="name"
                            id="name"
                            placeholder="Enter your name"
                            required
                        />
                        <label class="main-label" id="email-label" for="email"
                            >Email</label
                        >
                        <input
                            type="email"
                            name="email"
                            id="email"
                            placeholder="Enter your e-mail"
                            required
                        />
                        <div class="row">
                            <div class="col">
                                <label
                                    class="main-label"
                                    id="number-label"
                                    for="number"
                                    >Age</label
                                >
                                <input
                                    type="number"
                                    name="age"
                                    id="number"
                                    min="1"
                                    max="100"
                                    placeholder="Age"
                                />
                            </div>
                            <div class="col">
                                <label class="main-label" for="dropdown"
                                    >Sex</label
                                >
                                <select name="sex" id="dropdown">
                                    <option value="male">Male</option>
                                    <option value="female">Female</option>
                                </select>
                            </div>
                        </div>
                    </section>

                    <section id="eating-habits">
                        <h2>Eating habits</h2>
                        <div class="row">
                            <fieldset class="fset-sub">
                                <legend class="main-label legend-sub">
                                    Meals per day
                                </legend>
                                <div class="option">
                                    <input
                                        id="meals-per-day-1"
                                        type="radio"
                                        name="meals-per-day"
                                        value="1"
                                    />
                                    <label for="meals-per-day-1">One</label>
                                </div>
                                <div class="option">
                                    <input
                                        id="meals-per-day-2"
                                        type="radio"
                                        name="meals-per-day"
                                        value="2"
                                    />
                                    <label for="meals-per-day-2">Two</label>
                                </div>
                                <div class="option">
                                    <input
                                        id="meals-per-day-3"
                                        type="radio"
                                        name="meals-per-day"
                                        value="3"
                                    />
                                    <label for="meals-per-day-3">Tree</label>
                                </div>
                                <div class="option">
                                    <input
                                        id="meals-per-day-4"
                                        type="radio"
                                        name="meals-per-day"
                                        value="4"
                                    />
                                    <label for="meals-per-day-4">Four</label>
                                </div>
                                <div class="option">
                                    <input
                                        id="meals-per-day-5"
                                        type="radio"
                                        name="meals-per-day"
                                        value="5"
                                    />
                                    <label for="meals-per-day-5">Five</label>
                                </div>
                                <div class="option">
                                    <input
                                        id="meals-per-day-6"
                                        type="radio"
                                        name="meals-per-day"
                                        value="6-or-more"
                                    />
                                    <label for="meals-per-day-6"
                                        >Six or more</label
                                    >
                                </div>
                            </fieldset>
                            <fieldset class="fset-sub">
                                <legend class="main-label legend-sub">
                                    Meal composition
                                </legend>
                                <div class="option">
                                    <input
                                        id="meal-comp-1"
                                        type="checkbox"
                                        name="meal-content"
                                        value="fruit-and-vegetables"
                                    />
                                    <label for="meal-comp-1"
                                        >Fruit and vegetables</label
                                    >
                                </div>
                                <div class="option">
                                    <input
                                        id="meal-comp-2"
                                        type="checkbox"
                                        name="meal-content"
                                        value="meat"
                                    />
                                    <label for="meal-comp-2">Meat</label>
                                </div>
                                <div class="option">
                                    <input
                                        id="meal-comp-3"
                                        type="checkbox"
                                        name="meal-content"
                                        value="tubers"
                                    />
                                    <label for="meal-comp-3">Tubers</label>
                                </div>
                                <div class="option">
                                    <input
                                        id="meal-comp-4"
                                        type="checkbox"
                                        name="meal-content"
                                        value="dairy"
                                    />
                                    <label for="meal-comp-4"
                                        >Dairy products</label
                                    >
                                </div>
                                <div class="option">
                                    <input
                                        id="meal-comp-5"
                                        type="checkbox"
                                        name="meal-content"
                                        value="grains"
                                    />
                                    <label for="meal-comp-5">Grains</label>
                                </div>
                                <div class="option">
                                    <input
                                        id="meal-comp-6"
                                        type="checkbox"
                                        name="meal-content"
                                        value="sugar"
                                    />
                                    <label for="meal-comp-6">Sugar</label>
                                </div>
                            </fieldset>
                        </div>
                    </section>
                </div>

                <section id="add-info">
                    <h2>
                        Additional information
                    </h2>
                    <label class="main-label" for="comments">Comments</label>
                    <textarea
                        name="comments"
                        id="comments"
                        cols="30"
                        rows="10"
                        placeholder="Enter your comment here..."
                    ></textarea>
                    <div class="row">
                        <fieldset class="fset-sub">
                            <legend class="main-label legend-sub">
                                Newsletter
                            </legend>
                            <div class="option">
                                <input
                                    id="newsletter"
                                    type="checkbox"
                                    name="newsletter"
                                    value="subscribe"
                                />
                                <label for="newsletter"
                                    >Keep in touch with our newsletter</label
                                >
                            </div>
                        </fieldset>
                        <div class="col">
                            <button id="submit" class="btn">Submit</button>
                        </div>
                    </div>
                </section>
            </form>
        </main>
    </body>
</html>

CSS file:

/* Color scheme */
:root {
    --background: #efefef;
    --form-bg-standard: #fff;
    --form-bg-alt: #eee;
    --form-bg-dark: #444;
    --text-standard: #666;
    --text-title: #333;
    --focus: #7bc94e;
    --focus-alt: #4394d6;
}

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

/* Standard setup */
body {
    background-color: var(--background);
    /* background: linear-gradient(45deg, #759b61, #619b85); */
    font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
    line-height: 1.5;
    color: var(--text-standard);
}

main {
    margin: auto;
}

#survey-form {
    max-width: 900px;
    margin: auto;
    padding: 2rem 2rem;
}

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

h1 {
    font-size: 2.5rem;
    color: #fff;
    text-align: center;
}

h2 {
    font-size: 1.25rem;
    margin-bottom: 1rem;
    color: var(--focus-alt);
}

/* Utility classes */
.row {
    display: flex;
    width: 100%;
}

.col {
    display: flex;
    flex-direction: column;
    width: 100%;
}

.grid-columns {
    display: grid;
    grid-template-columns: 1fr 1fr;
}

.new-line {
    display: block;
    margin-top: 0.5rem;
}

/* Buttons */
.btn {
    border: none;
    padding: 1rem 1rem;
    width: 20rem;
    background-color: var(--focus);
    color: #fff;
    font-size: 1.1rem;
    border-radius: 5px;
}

.btn:hover {
    cursor: pointer;
}

/* Form */
section {
    background-color: var(--form-bg-standard);
    display: flex;
    flex-direction: column;
    width: 100%;
    padding: 1.5rem 1.5rem 1.5rem 1.5rem;
    margin: 0.5rem 0;
    border: none;
    box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.05);
}

.row section:first-of-type {
    margin-right: 0.5rem;
}
.row section:last-of-type {
    margin-left: 0.5rem;
}

.fset-sub {
    display: block;
    width: 100%;
    border: none;
}

input[type="text"],
input[type="email"],
input[type="number"],
select,
#comments {
    display: inline-block;
    width: 100%;
    padding: 0.5rem;
    border-color: var(--form-bg-alt);
    border-style: solid;
    margin-bottom: 1rem;
    font-size: 16px;
}

select {
    background-color: var(--form-bg-alt);
}

label {
    font-size: 1rem;
}

.main-label {
    font-size: 1.1rem;
    margin-bottom: 0.5rem;
    color: var(--text-title);
}

legend.main-label {
    display: block;
    float: left;
    width: 100%;
    margin-top: 0rem;
}

/* Header */
header {
    /* background-color: var(--focus-alt); */
    background: linear-gradient(45deg, #4394d6, #43c5d6);
    padding: 2rem 1rem 1rem 1rem;
    box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.05);
    margin-bottom: 0.5rem;
    color: #fff;
}

header div {
    padding: 2rem 5rem;
    justify-content: center;
    align-items: center;
}

#description {
    margin-right: 1rem;
    font-size: 1rem;
    font-weight: 500;
    width: 100%;
}

header img {
    height: 100px;
    width: auto;
    margin-left: 1rem;
}
/* P-info */
#p-info .col:first-of-type {
    margin-right: 1rem;
}

/* Eating habits */
#eating-habits .option {
    margin-bottom: 0.5rem;
}

/* Additional-info */
#add-info .col {
    justify-content: center;
    align-items: flex-end;
}

/* Media queries desktop first */

/* Tablet 840px */
@media only screen and (max-width: 840px) {
    form > .row {
        flex-direction: column;
    }

    form .row section {
        margin: 0.5rem 0;
    }

    #eating-habits {
        margin: 0.5rem 0;
    }

    .btn {
        width: 100%;
    }

    #survey-form {
        padding: 1rem 1rem;
    }

    header {
        padding: 1rem 0.5rem 0.5rem 0.5rem;
    }

    header div {
        padding: 1.5rem 3rem;
    }
}

/* Phone 568px */
@media only screen and (max-width: 568px) {
    .row {
        flex-direction: column;
    }

    .grid-columns {
        grid-template-columns: 1fr;
    }

    #survey-form {
        padding: 0.5rem 0.5rem;
    }

    header div {
        padding: 1rem 1.5rem 0 1.5rem;
    }

    header img,
    header #description {
        margin: 0.5rem 0 0 0;
    }

    h1 {
        font-size: 2rem;
    }

    .option:last-of-type {
        padding-bottom: 1rem;
    }

    #p-info .col:first-of-type {
        margin-right: 01rem;
    }

    header img {
        margin: 1rem;
    }
}
\$\endgroup\$
2
\$\begingroup\$

It looks ok to me. What you could improve is the order of your CSS statements. For example

This:

header {
    /* background-color: var(--focus-alt); */
    background: linear-gradient(45deg, #4394d6, #43c5d6);
    padding: 2rem 1rem 1rem 1rem;
    box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.05);
    margin-bottom: 0.5rem;
    color: #fff;
}

Would look a little bit cleaner this way(alphabetical order):

header {
    /* background-color: var(--focus-alt); */
    background: linear-gradient(45deg, #4394d6, #43c5d6);
    box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.05);
    color: #fff;
    margin-bottom: 0.5rem;
    padding: 2rem 1rem 1rem 1rem;
}

There are a few different ways to order CSS statements. For example you could write out all statements that change the appearance first (background, color, font-size) and then all statements that change the box model (width, height, padding, margin).

\$\endgroup\$
  • \$\begingroup\$ Thanks for the advice. I installed CSScomb in VS code now, an it seems to do just that \$\endgroup\$ – Øyvindsen Sep 13 at 9:26
2
\$\begingroup\$

There's really not much you can improve. My follow up question would be where and how did you decide on your breakpoints?

I suggest using a bit more standardized sizes; the ones I pasted below are directly from the Bootstrap 4 Template https://getbootstrap.com/docs/4.3/layout/overview/

You do not need all 4 sizes, but these are a bit more standard (even though there's a bajillion different sizes, these are most common)

// Small devices (landscape phones, 576px and up)
@media (min-width: 576px) { ... }

// Medium devices (tablets, 768px and up)
@media (min-width: 768px) { ... }

// Large devices (desktops, 992px and up)
@media (min-width: 992px) { ... }

// Extra large devices (large desktops, 1200px and up)
@media (min-width: 1200px) { ... }

And maybe some general clean up. For example right now you have:

Current

    form .row section {
        margin: 0.5rem 0;
    }
    #eating-habits {
        margin: 0.5rem 0;
    }

Revised

#eating-habits, form .row section{
    margin: 0.5rem 0;
}

Keep all the same style in one block. So if there are a bunch of things that have the exact same property and value, put them in a single block. I usually do ID's then class (alphabetical). And same with the properties themselves as mentioned by Dennis.

Reason

Lets say you have 50 elements, and they all need to display:block . Its much quicker to write that out once, and attach all the classes and ID's to that property, than the inverse. If you look at most CSS frameworks you'll find them written in this fashion.

Otherwise great work! :)

\$\endgroup\$
  • \$\begingroup\$ Thanks. I will try to get all the same styles in one block. The reason for my nonstandard breakpoints is just that text started wraping or overflow on those points. \$\endgroup\$ – Øyvindsen Sep 13 at 9:36

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.