Shopping Cart/Blog

Data shows nothing hurts website sales more than a slow website.

Speed is outselling everything.

  1. Uber’s faster than a taxi.
  2. Get an answer to any question in 0.3 seconds because at .5 Google lost 20% of their traffic.
  3. Netflix and Spotify deliver content on demand.
  4. When you finish your Uber ride you walk out, they charge you.
  5. You can have a car pick you up in five minutes.
  6. A pizza delivered in 20 minutes.
  7. Groceries in 60 minutes.
  8. You've got apps you speak into to place orders.
  9. And you can use Touch ID to pay.
  10. And their are places that have posters you can scan QR codes and have products delivered to your house.

While Amazon and Walmart have released data showing how 1 second could cost them billions, their competition is averaging load times of 27.3 seconds on mobile and being told 5 seconds is okay.

It is like they have already given up.

Companies aren’t counting minutes anymore, they're counting milliseconds.

They went from weeks to days, from days to hours, from hours to minutes, from minutes to seconds and now they're going from seconds to milliseconds.

  1. Mobify said a 100 millisecond improvement in load times netted a 1.11% increase in sales.
  2. AutoAnything said they saw a 3% increase by cutting load times in half.
  3. Walmart said a one second improvment increased conversions by 2%
  4. BBC said they lost 10% of their total users for every additional second it took their pages to load.
  5. COOK reduced page loads by 850 milliseconds and saw a 7% increase in conversions.
  6. Furniture Village decreased load times by 20% and got a 10% increase in conversions.

I think it's time someone started talking about how much bad code is costing the small business owner.

And the talk should start with Bootstrap.

A Google study showed if a website takes 3 seconds to load, it'll lose 53% of it's traffic.

And in 2 seconds you’ve got a Google penalty.

Yet despite this the average website takes 27.3 seconds to load on mobile.

Made for the masses, frontend frameworks like Bootstrap should have died back in 2017, but lazy designers and teachers have kept them on life support. 

Costing the small business owners billions of dollars a year and allowing companies like Amazon to destroy the backbone of the world's economy.

Every frontend framework, no matter the name

  • Bootstrap
  • Foundation
  • Bulma
  • Zurb
  • Skeleton
  • Pure
  • Groundwork

All suffer from code bloat because they were all made for the masses!

Bootstrap and the like are all made for the masses.

The very meaning of being made for the masses is being mundane, ordinary, plain Jane vanilla. 

And if you're ordinary, if you're just like everyone else, the only place left to compete is price. 

You see no matter the framework, they all make bad assumptions and prevent you from adapting to the newest and best coding practices. 

Take Bootstrap ... the most popular.   

Bootstrap has an option for just about anything you can imagine. 

Bootstrap was originally created for internal use and never meant to be used in production but web designers were willing to ignore that.

And even today they are willing to ignore the damage it does to the end user. Because it makes their lives easier, happier, and gives them lots of free time.

Damn the customer and let's have another beer.

3.5 million websites later, with an internet full of code bloat the small business owners have all but given up on competing with the likes of Amazon. 

It's the cost of bad code!

Neither the dealership, store, or small business owner takes the time to research and study the facts because they trust their designer, programmer, or marketing guru.  Who like them have not done their homework and they trust their guru, who like them has not done their homework.

So they build their online business on a poorly coded platform with a poorly coded frontend framework and accept the fact that they could never compete with the likes of Amazon and never think to wonder why.

It's the web designers, developers, and teachers who have sold them out to laziness and a fast buck.

As they are either too lazy, busy, or just don't care to look at the facts.

So their clients are correct, they will never compete with the likes of Amazon!

They put how fast they could finish above performance and correctness. 

They listened to marketing gurus, designers, developers, and SEO's instead of checking, testing, and researching the information for themselves.

Because they thought it was more important to get their business online fast, than doing it right. 

Today, more than 19% of websites use Bootstrap and at least another 40% are using some other kind of frontend framework.  And that one decision cost them money everyday, that they never see themselves losing.

Bootstrap is the first clue that your front-end developer doesn't care about the end user.

It’s for people who don’t understand the internet and how things work.

People with low budgets, high ambitions, and little understanding.

Bootstrap allows someone with very little knowledge to build a good looking website — at least in the eyes of the client and most website users.

But Bootstrap is a made for the masses mess!

A framework that was never intended to be used in production or to be maintainable.

Every year you need to rebuild your website as the next version is released and this is NOT how your website should work in 2022.

The internet has become a living, breathing, thing, and to survive your website has to do the same.

With split testing, analytics, and a slew of online tools you're able to bring your website to life. 

Having it evolve and change by measuring how the end user responds to it.   

But you can't do this on a framework that forces a total rebuild every year.

Code bloat is killing the small business, like sugar is killing its owner.

Silently in the background, it turns away ¾ of your customers per day and your stats prove it.
 
And this code bloat comes from made for the masses frameworks.
 
Using a frontend framework hinders your ability to load quickly because of all the code bloat.
 
And these frameworks make bad decisions ... When designing a website for different screen sizes and devices you have breakpoints.
 
Bootstrap does this by dividing the design into columns, and then they assign column classes, in their divs.
 
And they use pixel-based values.
 

The problem with pixel-based breakpoints is that they don’t work for accessibility.

If you can’t see good and you adjust your browser’s font size …

Depending on how the breakpoints for the different devices are set up, it could break the web design.

Breakpoints should use font sizes and those sizes should be a relative unit either EM or REM.

This is important because it is common for users with visual impairments to change the default browser font size.

And with pixel-based breakpoints this breaks the design.

Bootstrap uses pixel-based breakpoints and is therefore not good for business owners who want websites that will work on any device in any setting.

And because of the way its setup it adds a lot of code bloat to the site as the site grows so does the code bloat and this slows the site down.

Bootstrap is full of coding errors and the total misuse of the !important statement.

In total, there are 146 occurrences of !important in Bootstrap 4.

In Bootstrap 5, they got it down to 19.

Cascaded style sheets are processed by the web browser in a certain order.

So let's say you're creating a website and you want to change one of the values that's in the external stylesheet, you could just write it into the header of the page on your own and it would overwrite what was in the external style sheet.

If you wanted to overwrite something that was in the header you could just write in inline.

So what's ever closest to the HTML overwrites was further away.

However the use of the !important statement breaks this order and adds weight to a specific declaration and ignores the others.

This is considered bad practice and makes it difficult to maintain or adjust the codebase later.

Amazon said a 1 second lag in page load time could cost them $1.6 Billion dollars a year.

When you're losing money by the millisecond, why would you add 500KB of unesscarry code to your site?
 
To create a simple landing page you would have to use jQuery, Bootstrap CSS, and Bootstrap JS.
 
Look at all the code you're linking out to and look at how much of that code you're actually using. It's like internet pollution. Bootstrap has so many components, utilities, and options that you will most likely never use half of them.
 
But you're carrying all that code around and all that code is slowing your site down. 

It's costing the company that's trying to compete with the likes of Amazon money ...
 

It's hurting your customer, damaging a business, why would you use it?

Something that is rarely talked about is the expense associated with bad code.

When we talk about coding we talk about the expense associated with development and maintenance but we don’t talk about the expense of bad code …
  1. Increase load times.
  2. Kills conversion.
  3. Waste resources.
  4. Kills rankings.
  5. Hurts credibility.
  6. ​Can get you sued.
  7. And your website may not work in all the different devices.​
​And something else that is not talked about is how much more money you can make with high-quality custom code.  ​

High-quality, custom tailored code will always save money and increase sales.


Because it will always be faster!

What’s a Framework?

A “Framework” is nothing more than a way of doing things.

It’s a process, a pattern created by a group of people that believe this is the best, quickest, easiest, or whatever reason has motivated them to code this process.

The advantages of using a framework is that you don’t need to build out any of the functionality. All you have to do is follow their instructions and tie it into their system.

And a framework doesn’t have to be complicated, you could call an style sheet a framework!

However, using a framework without understanding the goals, reasoning, and motivations of its creators could be costly, harmful, and detrimental to the future of your business.

Why use a Framework?

Frameworks save the developers, coders, and designers time.

Most companies hire according to which frameworks you know.

When you build a website there are a lot of things you will do over and over again, so frameworks came along to save time and prevent you from having to do the same things over and over again.

And depending on the framework you're using will also depend on the cost you'll pay.

But sadly what's not being talked about is how a 1 second increase in load times, caused by bad code could be costing you millions a year.

And made for the masses frameworks always cost the website owner money in the long run.

Types and Uses of Frameworks

Professional front-end developers do not use made for the masses frameworks.

A framework is nothing more than a pattern, so having a pattern isn’t a bad thing but when you take that pattern, tweak it, stretch it, and turn it into a one size fits all ... it can’t compete with a mean, lean, coded for the project, coded for speed website.

Made for the masses frameworks are normally made for beginners and require more code in addition to the already trying to be everything to everybody problem.

I guess it all comes down to the end goals!

But to me it just makes sense that if you're writing code that you’ll be repeating over and over again, you would write the code to meet all current coding standards but sadly coding standards never seem to come up when coding front end frameworks.

The differences between an expert and an amateur is the quality of the code and one way of accessing the quality of the code is to see if it validates.

The internet is Constantly Changing and Evolving

Because the internet is constantly changing and evolving the frameworks are also having to twist, change, and turn to keep up with it. And many times, this means having to chunk your old theme and totally redesign, year after year to try and keep up with the Internet.

By having a website outside of these made for the masses frameworks you're able to evolve with the internet instead of looking like some kind of parasite that has attached itself to it.

And frameworks come and go.

So build your own framework ...

What Makes a Good Framework

If you're a coder and someone asks you what constitutes good code then you have to say the quality of the code.

The way you establish the quality of the framework is that it meets all the standards and doesn’t have any errors. The way you find errors is by validating the code and if you can’t validate the code how can the developer be sure he didn’t forget to close a tag?

A professional writes code that meets all the standards and validates so a good framework does the same.

How can you introduce a framework that doesn’t meet all the standards?

How can a all these made for the masses framework even dream that they’ve possibly covered every option a business may encounter?

And to make it worse all those options that you’ll never use weigh down your site and that weight slows it down.

And that slow down can cost you millions a year and put you at a huge competitive disadvantage.

So a good framework is one that has been custom built for your project and its code meets all the current coding standards and validates.

Building your own framework is the only way to get rid of all the code bloat.

A good framework should use all the current benefits available in all the languages you're programming in.

And if something new comes up, if there is a new way of doing something, or if a feature needs to be extended, it should be simple, quick, and easy.

But most of all it has to be designed around speed!

A Framework Should Be Custom

Everything should be precise, you don’t need the extra code needed to change, adjust, and extend because everything has been custom written for you and your site.

Every piece of code is written with a purpose, not one line, space, or mark is accidental.

Nothing is repeated and it's packed, stacked, used, and written to use as little code as possible while being as effective as possible.

The best way to build a custom framework is to start at the beginning.

How to Make Your Own Frontend Framework

You could start with a tutorial and work through into a guide, and from the guide into a bunch of different layouts and mock ups that you're able to pick and choose elements from.

Once the layout is chosen the code is rendered.

And from this point on you're able to start writing your custom code.

You're adding to a blank template versus all of the current front-end frameworks where you start with every option available to man and to speed up the site or add something they didn’t think of, you have to rewrite or remove code.

And that's even if that particular framework allows you to modify and remove the code because some frameworks don’t.

The Death of Custom Templates!

Some frontend frameworks cause you to rewrite the code you modified every-time they update.

This is the reason most people don’t even try to customize their templates. Instead they add more code through an app or plugin that leaves a slow, bloated, low-quality, inferior experience.

These front end frameworks come with a hidden tax that’ll put you at a disadvantage and eventually out of business.

It’s happening as companies like Amazon pick and choose the most profitable products for themselves by watching your data.

Frameworks are Easy to Understand!

A good framework is built around speed and usability!

It’s organized in such a way that it is both easy to understand and easy to maintain. This means setting up and sticking with a way of laying-out and organizing things.

The code needs to be easy to understand and write.

Frameworks are Easy to Add Onto

The idea is to start with a lightweight frame and keep the code light, as different features are added.

You’ve got to be able to add in custom features as some sites may use a feature that is unique to that business and it’ll never or rarely ever be used and you don’t want any extra code slowing down the framework.

But it’s location and how it’ll work has to be thought of ahead of time because these added features are one of the biggest contributors to code bloat.

This means having a place for framework code and another place for non-framework code.

Building a Framework

If a framework can be as simple as a style sheet then anyone who can write CSS can build a framework.

The framework has to be ...

  • Fast
  • Customizable
  • Extendable
  • Understandable

Your framework is your secret weapon that's hard to see and even harder to duplicate.

Quality Control

The good thing about writing quality code, is that there are a lot of tools we can use to make sure we’ve got everything right and we need to perform checks and guidelines to make sure all our code validates and meets all performance and accessibility checks.

For quality control, test:

  • Accessibility
  • Performance
  • Responsiveness
  • Maintainability
  • Validation
  • Linting
  • Formatting

And those checks need to be automated.

The front end design doesn’t need to be complicated. As a matter of fact it should start out as simple as possible because the less code the faster it’ll load.

You’ve really only got 2 web design styles and both can be laid out using the native browser language (CSS GRID) which makes the site cleaner and faster.

Single Column Web Design Layout

Single column layouts with hero image layout in the content in a single, vertical column.

Visitors just scroll down to see more content.

Single column layouts are the most popular kind of websites. And mobile has helped push this kind of design because in mobile everything needs to fit to a single column to fit mobile screens perfectly.

The hero image is based on the idea that using images in design is the fastest way to sell a product. Featured images create an emotional connection with visitors — a big, bold photograph or illustration of an object makes a strong statement and creates a stunning first impression.

The code for a single website design doesn’t need to get complicated, it can be simple.

Fixed sidebars

Navigation is a critical part of any website — the main menu is the first thing most users look for when they want to navigate a website.

Along with the top menu you have the horizontal navigation.

It’s possible to keep menu options in sight by placing it in a fixed sidebar.

The sidebar is a vertical column on the left or right part of the page.

One way to design a website is to have the sidebar stay stationary and always remain visible while the rest of the page changes as the user scrolls the page.

This way the navigation remains accessible.

Instead of saying we learned someone elses framework, why not say we built our own framework?


HTML Setup

HTML (stands for Hypertext Markup Language) and it's a computer language that makes up most web pages and online applications. A hypertext is a text that is used to reference other pieces of text, while a markup language is a series of markings that tells web servers the style and structure of a document.

HTML is not considered a programming language as it can’t create dynamic functionality. Instead, with HTML, web users can create and structure sections, paragraphs, and links using elements, tags, and attributes.

Here are some of the most common uses for HTML:

    Web development. Developers use HTML code to design how a browser displays web page elements, such as text, hyperlinks, and media files.
    Internet navigation. Users can easily navigate and insert links between related pages and websites as HTML is heavily used to embed hyperlinks.
    Web documentation. HTML makes it possible to organize and format documents, similarly to Microsoft Word.

It’s also worth noting that HTML is now considered an official web standard. The World Wide Web Consortium (W3C) maintains and develops HTML specifications, along with providing regular updates.

The average website includes several different HTML pages. For instance, a home page, an about page, and a contact page would all have separate HTML files.

HTML documents are files that end with a .html or .htm extension. A web browser reads the HTML file and renders its content so that internet users can view it.

And because HTML is markup, not a programming language.

The only way to hack it is to hack the server.  Because it's not possible to hack HTML because it doesn't run any code.

HTML5 is about making everything simple.

HTML5 has made it easy to implement web standards that in the past have been difficult to implement.

It's the most powerful language the Web has ever seen: HTML5!

When you open an XHTML document the first thing you see, the first line of the document: is <DOCTYPE>

The browser uses the <doctype> to know how to render the web page. Browsers change their behavior based on the <DOCTYPE>.

HTML5 has made creating a web page easy.  The tags are less complex, the features are less complex, and most importantly, the rules are less complex.

The HTML5 specification states that the <doctype> is case-insensitive; however, previous versions of HTML require an all-caps version of the <DOCTYPE>.

By using <DOCTYPE> in all caps we allow all browsers to support us!

First thing I want to do is create a folder for my project and since I'm in Linux I'll just right click and I'll create a folder and call it HTML.

I'll go into that folder and rt click again and this time I'll create a document and I'll call it index

I'll open Sublime and start off by typing html

<html> 

hitting enter and letting sublime feel out the rest.

<!DOCTYPE html>   
      <html>
           <head>
                <meta charset="utf-8">   
                <title></title>   
           </head>
           <body>                  
           </body>
      </html>

Now … every line of code adds to the time it takes a page to load.

And every major corporation who cares about money, has seen how page speeds affect conversions.

For example …
  • Amazon said Every 100ms Cost them 1% in Sales.
  • Google said two milliseconds cost them 20% of their searches.

So right from the start we want to start by eliminating, slimming down, and speeding up our website.

Some of the base HTML code and some of what is written afterwards is done for the purpose of making it easier to understand.

For example I do not need to tell the browser that it’s “html”, it knows that.

So I’ll remove the

<html>

open and close tags.

<!DOCTYPE html>   
           <head>
                <meta charset="utf-8">   
                <title></title>   
           </head>
           <body>                  
           </body>

I can also remove the head and body tags.

<!DOCTYPE html>   
                <meta charset="utf-8">   
                <title></title>   

Let's start with the body and let's start by adding a div

<div>

element for a container for content. But it doesn’t have any effect on the layout until it's styled, so I can prepare my HTML for the styling by adding some class to my content and I can do this by adding the class element.

Then I'll add a selector and call it grid-container.

<div class="grid-container">

But the idea is to make the code as thin as possible and as a result it’ll be super fast.

But it also has to be optimized for the search engines and be compliant.

Because by law you have to make a business accessible to people with a handicap. And even though a website isn’t a physical business they are winning lawsuits.

And anyway ... it's better to make your website accessible to as many people as possible.

So we will make ours AA compliant.

And it has to be optimized for the search engines.

<!DOCTYPE html>
<meta charset="utf-8">
<title></title>

Let's start with the body and let's start by adding a <div> element for a container for content. But it doesn’t have any effect on the layout until it's styled, so we need to add some class to our content and we can do that with the class element.

Then we will add a selector and call it grid-container.

<div class="grid-container">

And inside the grid-container I’ll add a topbar, for our phone number or a message. And then I’ll add a selector for styling and I’ll call it grid-box and I’ll use this one on all the elements we create for styling our content inside this area.

And I’ll add a topbar on this one for styling things specifically for this area.

<div class="grid-box topbar">
<p>Info bar</p>
</div>

And then I’ll add an area under the message for our logo.

<header class="grid-box">
<p>Logo</p>
</header>

And then I’ll add a mega menu. The problem with mega menus is that the more options you give someone the less likely it is that they will make a purchase.

However, at the same time you should be able to get to any page on your website within two clicks.

So there will be some pages we will use a mega menu and other pages and sections of the site where we will not.

And I’ll put the mega menu inside the nav element.

<nav>
<p>Nav</p>
</nav>

I’ll add in a Hero image because images communicate 60,000 times faster than text.

And you’ve got .03 milliseconds to make a first impression.

So you've got to have an image-focused design.

Bold graphics that grab the user and pull them into the story.

A hero image is your elevator pitch.

It tells the website visitor what your purpose for being is.

You're looking for an image that creates an emotional connection that reinforces the call to action and increases a desire to click it.

It starts with an image of someone you want someone to help and have them looking at your call to action.

You design different images for different devices to help with load times.

The images have to be flawless and pull you in!

And you don’t want to use carousels or sliders because they slow down the site and kill conversions.

They …

1.) Cause Banner Blindness

2.) Divides user’s Attention

3.) Kill Conversions

5.) Are Not Built for Accessibility

6.) Get Low Click-through Rates

7.) Aren’t Mobile Optimized

8.) Have Too Many Options, And Overwhelm Visitors

9.) Take Control Away from You

Rather than beating users over the head with all of your offers at once, let them come across the offers naturally throughout your site.

1. More Choices = Bad User Experience

The more options you give, the more you distract users from yours and their desired goal.

WhirlPool tested it and went minimalist, eliminating all the secondary calls to actions and photographs.

2. It Increases Buyer’s remorse

The more choices you have, the worse you feel after you buy. Why? Because now all you can think about is how much better the other options may have been.

3. Depletion of ability to think

We are only allowed so many decisions a day, if our ability to make a decision is already depleted or if we understand that we have a limited number of decisions, we’ll just leave rather than depleting our ability to make important decisions later.

To compete today you need to be creating specific messages for multiple personas. Using previous interest you customize a user experience and show different hero images and call to actions for different personas.

But the idea is one Hero image, one call to action, one goal, per a page.

This is where we attempt to take control and point them in a direction.

So this is where one large image at the top of the page, full-width, without white space goes.

It occupies the best real estate.

And it Demands Attention!

… and I’ll call this selector hero.

<div class="grid-box hero">

Hero image

</div>

Now the main element is where the main part of your content goes and it will run beside the left menu.

<main class="grid-box">
<p>Content</p>
</main>

And then comes our left menu with the aside element. And here I’ll just reuse the same selector I used for main and just call it grid-box as well.

I can use the aside element for styling this one so I don’t need to add anything but grid-box.

<aside class="grid-box">
<p>aside<p>
</aside>

Then I’ll add one more for a call to action and I’ll call it teaser and I’ll just call this one.

<div class="grid-box teaser">
<p>
Call to action
</p>
</div>

Then I'll add a footer element with the same selector.

<footer class="grid-box">
<p>footer</p>
</footer>
</div>

The HTML controls the content and layout and the CSS modifies the design and display of the HTML using elements.

Now the fastest kind of CSS is inline and to run inline we just type <style and hit enter.

What we did above was set a “class” that we can now target with CSS code.

We will create a style tag and put all our css code inside the style.

<style>

Let's start by defining our grid areas.

The first will be topbar and I’ll hook it to the location on the html with the grid-area of topbar.

.topbar {
grid-area: topbar;
}

Next will be header and I’ll hook it to the location on the html with the grid-area of header.

header {
grid-area: header;}

And then the nav and I’ll hook it to the location on the html with the grid-area of nav.

nav {
grid-area: nav;
}

And then the hero and I’ll hook it to the location on the html with the grid-area of hero.

.hero {
grid-area: hero;
}

Next will be the teaser and I’ll hook it to the location on the html with the grid-area of teaser.

.team {
grid-area: teaser;
}

Then main connected to the grid-area of main.

main {
grid-area: main;
}

Aside main connected to the grid-area of aside.

aside {
grid-area: aside;
}

And teaser hooked to the location on grid-area of teaser.

.teaser {
grid-area: teaser;
}

And footer hooked to the location on grid-area of footer.

footer {
grid-area: footer;
}

Then I’ll style the grid container.

.grid-container {

I’ll give it a grid display.

display: grid;

I’ll define the placement of the grid areas and the order that they go in.

grid-template-areas:
    "topbar"
    "header"
    "nav"
    "hero"
    "team"
    "main"
    "aside"
    "teaser"
    "footer";

I’ll give it a gap and some padding.

grid-gap: .5rem;
padding: .25rem;
}

If our landing pages aren't optimized for mobile it won’t be easy to use.

To have a responsive design, we have to make sure it looks good on cell phones, tablets, laptops, and desktop screens.

A media query lets you render content that adapts to different factors like screen size or resolution.

I’ll give two media queries for the grid container. This will allow it to adapt to different devices.

The default will put everything in one column for mobile and the second will put everything in 2 coulms for laptops.

@media only screen and (min-width: 550px) {
.grid-container {
grid-template-columns: repeat(2,1fr);
grid-template-areas:
"topbar topbar"
"header header"
"nav nav"
"hero hero"
"team team"
"main main"
"aside ."
"teaser teaser"
"footer footer";
}
}

And the last one will put everying in 3 coulmns and it will put the aside next to the main for the sidebar. And this one is for desktops.

@media only screen and (min-width: 800px) {
.grid-container {
grid-template-columns: repeat(3,1fr);
grid-template-areas:
"topbar topbar topbar"
"header header header"
"nav nav nav"
"hero hero hero"
"team team team"
"aside main main"
"teaser teaser teaser"
"footer footer footer";
}
}

Now let's style the grid box with a border, font size and some padding.

.grid-box {
padding: .5rem;
}

And I’ll do the same for main, aside and footer and I’ll define background and text color along with the area in the HTML I want to target.  But I don't want to repeat the code so I'll all the selectors together and only use one ...

.topbar, header, nav, .hero, aside, main, .teaser, footer, .team {
background-color: #24272B;
color: whitesmoke;
}

And the code so far ….

<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Rapid Prototyping</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Example for rapid prototyping with CSS Grid Layout with focus on 'grid areas'.">
<style>
.topbar {
grid-area: topbar;
}
header {
grid-area: header;
}
nav {
grid-area: nav;
}
.hero {
grid-area: hero;
}<
.team {
grid-area: team;
}
main {
grid-area: main;
}
aside {
grid-area: aside;
}
.teaser {
grid-area: teaser;
}
footer {
grid-area: footer;
}
/* Styles for the grid container */
.grid-container {
display: grid;
/* Styles for the placement of the grid areas */
grid-template-areas:
"topbar"
"header"
"nav"
"hero"
"team"
"main"
"aside"
"teaser"
"footer";
grid-gap: .5rem;
padding: .25rem;
}
@media only screen and (min-width: 550px) {
.grid-container {
grid-template-columns: repeat(2,1fr);
grid-template-areas:
"topbar topbar"
"header header"
"nav nav"
"hero hero"
"team team"
"main main"
"aside ."
"teaser teaser"
"footer footer";
}
}
@media only screen and (min-width: 800px) {
.grid-container {
grid-template-columns: repeat(3,1fr);
grid-template-areas:
"topbar topbar topbar"
"header header header"
"nav nav nav"
"hero hero hero"
"team team team"
"aside main main"
"teaser teaser teaser"
"footer footer footer";
}
}
/* Styles for the grid items */
.grid-box {
padding: .5rem;
}
/* Styles for the HTML elements */
.topbar, header, nav, .hero, aside, main, .teaser, footer, .team {
background-color: #24272B;
color: whitesmoke;
}
</style>
</head>
<body>
<div class="grid-container">
<div class="grid-box topbar">
<p>Info bar</p>
</div>
<header class="grid-box header">
<p>Logo</p>
</header>
<nav>
<p>Nav</p>
</nav>
<div class="grid-box hero">
Hero image
</div>
<main class="grid-box">
<p>Main</p>
</main>
<aside class="grid-box">
<p>nav</p>
</aside>
<div class="teaser">
<p>
Call to action
</p>
</div>
<footer class="grid-box">
<p>Footer</p>
</footer>
</div>
</body>
</html>

Now we’ve got our code for our website with a sidebar.

I want to set up our typography.

You’ve got .3 seconds to grab their attention so we need our fonts, colors, and images, to tell a story and set a Rhythm before anything ever gets read.

You’ve got 100,000 different fonts and 16.8 million colors to choose from, the combinations are limitless.

1. Select a font

Fonts are important because they help to set the website's mood.

The curves in our fonts will have an emotional impact on the viewer while saying something about our personality.

Curves are friendly. Straight lines are stiff and standoffish. Thick is bold. Too thick is a bully, while thin is sexy and stylish.

But we want to put speed and readability before anything else.

If we host a custom local font, or font hosted by a third party, it will slow down our website.

So, we want to use web safe fonts because they speed up the website and 70% of consumers say page speed influences their purchasing decisions.

Web safe fonts already have the font on the devices that are reading the page.

Verses having to have extra HTTP requests to an outside server to get the font.

Also keep in mind that everything we do has to be set up to be responsive.

This means having to test the font in all the different devices to see how they look. And out of all of them Verdana is considered to be one of the best.

So I’m going to go with Verdana because I’ve seen nothing that shows having a fancy third party font improves conversions. But I’ve seen a lot about how speed does and since Verdana will speed up my site and look good on any device I’m going to go with it.

body, {
font-family: Verdana, Arial, Helvetica, sans-serif;
}

2. Font size

There is a problem with how Chrome handles font sizes on refreshes. They Get Bigger!

So the work around is to set the font-size in the HTML to 62.5%.

And then set the font size on the body to 1.4 em. Which should give me something that is at least 14 pixels as a base.

So I’ll do the 62.5 in the html but in the body I’m going to go with 1.6em ...

html {
font-size: 62.5%; }
body {
font-size: 1.6em;
font-family: Verdana, Arial, Helvetica, sans-serif;
}

3. Line Height

Line Height Affects Horizontal Motion

Readers scan content both horizontally and vertically, lines of text should feel like horizontal lines.

A line height that is too tight could undermine horizontal eye movement and encourage scanning down the left edge. It could also force people to reread lines of text. On the other hand, a line height that is too loose could make lines of text visually “float away” from each other. The lines will no longer feel like a cohesive unit, and vertical scanning becomes more difficult.

For this reason I will set the line height to 1.7em.

html {
font-size: 62.5%; }
body {
font-size: 1.6em;
line-height: 1.7em;
font-family: Verdana, Arial, Helvetica, sans-serif;
}

Colors

Now colors are important because they affect our emotions.

Colors Influence Taste

The color of your food can increase your appetite and affect the food. Orange increases your appetite. Blue makes you lose your appetite.

Black is related to power, strength and authority. Think of the black robs of a judge or the black belt in karate.

However, sports teams whose uniforms are black receive more penalties, and the players are associated with negative qualities such as aggression.

Color influences temperature

Whether you are feeling warm or cold can depend on the color tone of your environment. In a room painted in warm color temperature will feel higher than the same temperature in a cool-colored room.

Blue represents winter, ice, water, freshness, rain, wind, and your lips turn blue when you’re cold. Warm colors like red or yellow produce images like fire, sun, and summer in your mind.

Colors influence decisions

The color of a product can be the reason someone chooses it over another. Colors create emotions.

Warm colors create emotions of trust. As a consequence, it leads to loyalty and increases in purchases.

Your brand’s color also impacts your employees. One study found that red in the logo causes employees to work harder.

Red is associated with danger and failure (mistakes in exams are usually marked in red).

A study showed that when a team plays another team wearing red, they lose more often than they win because they associate the red uniforms with danger and failure.

Warm colors such as red and orange activate the survival mode, increasing speed but decreasing patience and creativity.

Cool colors like blue seem to have opposing calming effects. They are relaxing and enhance creativity. Installing blue-colored lights in train stations or streets reduces the crime rate.

Colors influence the perception of time

A red room puts you in survival mode. And this causes your perception of time to shift, where seconds feel like minutes.

But on the plus side you're paying more attention.

Red increases the heart rate and the amount of adrenaline circulating in our bloodstream.

And cool colors relax us. They calm the body, reduce respiration and lower the blood pressure. It's the reason surgeons wear green or blue.

A study, studying color on the placebo effect, showed that people given warm-colored pills, where more likely to believe they were working than people given cool-colored pills.

With that being said we will setup our colors as follows for now.

The first two digits of a hexadecimal color are the red value, the next two are the green, and the last two represent the blue. Think of “RGB” to remember the order.

Smaller values yield darker colors, so #000000 is black while #FFFFFF is white.

A shorter version uses three digits. It’s equivalent to the six-digit format, where each digit is duplicated to give the six-digit version. The value #46A is the same as #4466AA.

The eight-digit version adds a transparency value. In the three and six-digit notations, all colors are fully opaque.

The eight-digit notation has two digits at the end indicating the degree of transparency. A value of 00 indicates a completely transparent color, and ff is completely opaque.

For example, #0000FF88 would be a semi-transparent blue color.

Similarly, you can add one digit of transparency to a three-digit color code. The four-digit value #46A8 defines a semi-transparent color and is equivalent to #4466AA88.

And you should never use a pure black or a pure white.

So for our background color I’m going to set it to #222 and for our red I’m going to set it to #d00

Now we’re going to add a pure html and css navbar.

Let's add a navbar but let's do it with pure html and css so we’re not adding anything to what the browser already has to interpret.

And then I’ll set the width to 100% so it takes up the full width of the page and doesn’t leave any white space on the edges.

body {
background-color: #d00;
color: #222;
font-family: Verdana, Geneva, sans-serif;
font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */
line-height: 1.6;
width: 100%;
}

I’m going to set up the top bar with my phone number, email and login.

<div class="grid-container">
<div class="grid-box sub-grid-topbar topbar">

I’m going to set up a sub grid inside the topbar. I’ll call it sub underscore because I want to be able to easily see which are parents and which are children.

A parent can go by itself anywhere on the page but a child needs to go inside a parent.

<div class="grid-box sub-grid-topbar topbar">
<div class="grid-box topbar sub_grid_topbar">
<div class="topbar_box_1">
<h3>Phone #</h3>
</div>

So I’ll call it sub_grid_box and I’ll create a second selector that will be unique to this area and call it topbar_box_1.

<div class="topbar_box_2">
Email
</div>
<div class="topbar_box_3">
</div>
<div class="topbar_box_4">
Login
</div>
</div>

I’ll start by defining the area I want the CSS to affect.

.topbar_box_1 {
grid-area: topbar_box_1;
}
.topbar_box_2 {
grid-area: topbar_box_2;
.topbar_box_3 {
grid-area: topbar_box_3;
}
.topbar_box_4 {
grid-area: topbar_box_4;
}

Then I’ll tell it I want it to show two in a row side by side and put the second two under the first.

.sub_grid_topbar {
display: grid;
grid-template-columns: repeat(2,1fr);
grid-template-areas:
"topbar_box_1 topbar_box_2"
"topbar_box_3 topbar_box_4";
}

And then I’ll use a Media Query to say unless its a device with a screen size larger than 800px.

In that case show them side by side. 4 in a row.

@media only screen and (min-width: 800px) {
  .sub_grid_topbar {
  grid-template-columns: repeat(4,1fr);
  grid-template-areas:
    "topbar_box_1 topbar_box_2 topbar_box_3 topbar_box_4";
  }
}

And now I'm going to move back to the HTML.

And I'm going to add anoter selector to the class with the topbar and I'm going to call this one sub dash grid dash topbar.

  <div class="grid-box topbar sub-grid-topbar">
  </div>

And then we will create another div inside of the first one.

I'll call this one topbar_box_1 all underscores.

The reason this one is an under score is because it only works as a child. When I look at my code I want to easily be able to tell what is and what isn't a child, and I can do this by adding a dash to the parents and an underscore to the children.

  <div class="topbar_box_1">
  </div>

The first box will be the phone number with an svg of a phone.

But before I add my phone number and icon I want to copy my inside box three more time.

And I will number these 1 - 4.

   <div class="topbar_box_1">
   </div>
   <div class="topbar_box_2">
   </div>
   <div class="topbar_box_3">
   </div>
   <div class="topbar_box_4">
   </div>

And in the first box I will add my phone number with my icon.

   <div class="topbar_box_1">
                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-phone-vibrate-fill" viewBox="0 0 16 16">
                  <path d="M4 4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4zm5 7a1 1 0 1 0-2 0 1 1 0 0 0 2 0zM1.807 4.734a.5.5 0 1 0-.884-.468A7.967 7.967 0 0 0 0 8c0 1.347.334 2.618.923 3.734a.5.5 0 1 0 .884-.468A6.967 6.967 0 0 1 1 8c0-1.18.292-2.292.807-3.266zm13.27-.468a.5.5 0 0 0-.884.468C14.708 5.708 15 6.819 15 8c0 1.18-.292 2.292-.807 3.266a.5.5 0 0 0 .884.468A7.967 7.967 0 0 0 16 8a7.967 7.967 0 0 0-.923-3.734zM3.34 6.182a.5.5 0 1 0-.93-.364A5.986 5.986 0 0 0 2 8c0 .769.145 1.505.41 2.182a.5.5 0 1 0 .93-.364A4.986 4.986 0 0 1 3 8c0-.642.12-1.255.34-1.818zm10.25-.364a.5.5 0 0 0-.93.364c.22.563.34 1.176.34 1.818 0 .642-.12 1.255-.34 1.818a.5.5 0 0 0 .93.364C13.856 9.505 14 8.769 14 8c0-.769-.145-1.505-.41-2.182z"/>
                  </svg> 770-897-6107
                </div>
   <div class="topbar_box_2">
   </div>
   <div class="topbar_box_3">
   </div>
   <div class="topbar_box_4">
   </div>

And in the second box I will add my email icon with my email address.

   <div class="topbar_box_1">
                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-phone-vibrate-fill" viewBox="0 0 16 16">
                  <path d="M4 4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4zm5 7a1 1 0 1 0-2 0 1 1 0 0 0 2 0zM1.807 4.734a.5.5 0 1 0-.884-.468A7.967 7.967 0 0 0 0 8c0 1.347.334 2.618.923 3.734a.5.5 0 1 0 .884-.468A6.967 6.967 0 0 1 1 8c0-1.18.292-2.292.807-3.266zm13.27-.468a.5.5 0 0 0-.884.468C14.708 5.708 15 6.819 15 8c0 1.18-.292 2.292-.807 3.266a.5.5 0 0 0 .884.468A7.967 7.967 0 0 0 16 8a7.967 7.967 0 0 0-.923-3.734zM3.34 6.182a.5.5 0 1 0-.93-.364A5.986 5.986 0 0 0 2 8c0 .769.145 1.505.41 2.182a.5.5 0 1 0 .93-.364A4.986 4.986 0 0 1 3 8c0-.642.12-1.255.34-1.818zm10.25-.364a.5.5 0 0 0-.93.364c.22.563.34 1.176.34 1.818 0 .642-.12 1.255-.34 1.818a.5.5 0 0 0 .93.364C13.856 9.505 14 8.769 14 8c0-.769-.145-1.505-.41-2.182z"/>
                  </svg> 770-897-6107
                </div>
   <div class="topbar_box_2">               
                    <svg xmlns="http://www.w3.org/2000/svg" width="16.822035" height="16.822035" viewBox="0 0 16.822035 16.822035"><g id="email" transform="matrix(0.35045904,0,0,0.35045904,-0.70091808,-0.70091808)"><g id="email-2" data-name="email"><rect x="2" y="20" width="48" height="26" id="rect4" style="fill:#1aa6b8" />
   <div class="topbar_box_3">
   </div>
   <div class="topbar_box_4">
   </div>

For now I'll leave the third box empty and in the fourth box I'll add a login icon.

   <div class="topbar_box_1">
                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-phone-vibrate-fill" viewBox="0 0 16 16">
                    <path d="M4 4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4zm5 7a1 1 0 1 0-2 0 1 1 0 0 0 2 0zM1.807 4.734a.5.5 0 1 0-.884-.468A7.967 7.967 0 0 0 0 8c0 1.347.334 2.618.923 3.734a.5.5 0 1 0 .884-.468A6.967 6.967 0 0 1 1 8c0-1.18.292-2.292.807-3.266zm13.27-.468a.5.5 0 0 0-.884.468C14.708 5.708 15 6.819 15 8c0 1.18-.292 2.292-.807 3.266a.5.5 0 0 0 .884.468A7.967 7.967 0 0 0 16 8a7.967 7.967 0 0 0-.923-3.734zM3.34 6.182a.5.5 0 1 0-.93-.364A5.986 5.986 0 0 0 2 8c0 .769.145 1.505.41 2.182a.5.5 0 1 0 .93-.364A4.986 4.986 0 0 1 3 8c0-.642.12-1.255.34-1.818zm10.25-.364a.5.5 0 0 0-.93.364c.22.563.34 1.176.34 1.818 0 .642-.12 1.255-.34 1.818a.5.5 0 0 0 .93.364C13.856 9.505 14 8.769 14 8c0-.769-.145-1.505-.41-2.182z"/>
                  </svg> 770-897-6107
                </div>
   <div class="topbar_box_2">               
                    <svg xmlns="http://www.w3.org/2000/svg" width="16.822035" height="16.822035" viewBox="0 0 16.822035 16.822035"><g id="email" transform="matrix(0.35045904,0,0,0.35045904,-0.70091808,-0.70091808)"><g id="email-2" data-name="email"><rect x="2" y="20" width="48" height="26" id="rect4" style="fill:#1aa6b8" /><polygon points="50,20.06 2,20.06 26,2 " id="polygon6" style="fill:#24b9cc" /><polygon points="39.12,6.09 5.71,6.09 5.71,38.02 46.29,38.02 46.29,13.83" id="polygon8" style="fill:#eae8e8" /><polygon points="39.12,6.09 39.12,13.83 46.29,13.83" id="polygon10" style="fill:#d7d4d4"/><polygon points="50,20 50,50 26,34" id="olygon12" style="fill:#80deea"/><polygon points="26,34 2,50 2,20" id="polygon14" style="fill:#80deea"/><polygon points="50,50 2,50 26,34" id="polygon16" style="fill:#5cd4e3" /><path d="m 26,12 a 8,8 0 1 0 5.19,14.08 l -1,-1.22 A 6.4,6.4 0 1 1 32.4,20 v 1.2 a 1.2,1.2 0 0 1 -2.4,0 V 16 h -1.6 v 0.82 A 4,4 0 0 0 26,16 4,4 0 1 0 28.88,22.76 2.79,2.79 0 0 0 34,21.6 v 0 -1.6 a 8,8 0 0 0 -8,-8 z m 0,10.4 A 2.4,2.4 0 1 1 28.4,20 2.4,2.4 0 0 1 26,22.4 Z" id="path18"    inkscape:connector-curvature="0" style="fill:#ff6e40" /></g></g></svg> greggeniis@gmail.com
                </div>
   <div class="topbar_box_3">
   </div>
   <div class="topbar_box_4">
                  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-node-minus" viewBox="0 0 16 16">
                    <path fill-rule="evenodd" d="M11 4a4 4 0 1 0 0 8 4 4 0 0 0 0-8zM6.025 7.5a5 5 0 1 1 0 1H4A1.5 1.5 0 0 1 2.5 10h-1A1.5 1.5 0 0 1 0 8.5v-1A1.5 1.5 0 0 1 1.5 6h1A1.5 1.5 0 0 1 4 7.5h2.025zM1.5 7a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zM8 8a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5A.5.5 0 0 1 8 8z"/></svg> Login
                </div>

And now I'm going to move back to the CSS.

Lets start by defining the area.

I'll say that the dot topbar underscore box underscore 1 is in the grid aread of topbar underscore box underscore 1.

  /* Defining the subgrid areas */
.topbar_box_1 {
  grid-area: topbar_box_1;
}

And then I'll repeat that three more times and name them two, three, and four.

  /* Defining the subgrid areas */
.topbar_box_1 {
  grid-area: topbar_box_1;
}
.topbar_box_2 {
  grid-area: topbar_box_2;
}
.topbar_box_3 {
  grid-area: topbar_box_3;
}
.topbar_box_4 {
  grid-area: topbar_box_4;
}

And then we are going to say dot sub underscore grid underscore topbar.

sub_grid_topbar {
}

It has a display of grid.

sub_grid_topbar {
  display: grid;
}

A grid is a set of intersecting horizontal and vertical lines defining columns and rows. Elements can be placed onto the grid within these column and row lines.

You can create a grid with fixed track sizes – using pixels for example. This sets the grid to the specified pixel which fits to the layout you desire. You can also create a grid using flexible sizes with percentages or with the new fr unit designed for this purpose.

Item placement

You can place items into a precise location on the grid using line numbers, names or by targeting an area of the grid. Grid also contains an algorithm to control the placement of items not given an explicit position on the grid.

Creation of additional tracks to hold content

You can define an explicit grid with grid layout. The Grid Layout specification is flexible enough to add additional rows and columns when needed. Features such as adding “as many columns that will fit into a container” are included.

Alignment control

Grid contains alignment features so we can control how the items align once placed into a grid area, and how the entire grid is aligned.

Control of overlapping content.

More than one item can be placed into a grid cell or area and they can partially overlap each other. This layering may then be controlled with the z-index property.

Grid is a powerful specification that, when combined with other parts of CSS such as flexbox, can help you create layouts that were previously impossible to build in CSS. It all starts by creating a grid in your grid container.

The Grid container

We create a grid container by declaring display: grid or display: inline-grid on an element.

Next I'm going to add how many columns I want per row.

We can set it to a fraction of the free space in the grid (using the fr unit)

Here I'm telling it to display 1 column per row.

sub_grid_topbar {
  display: grid;
  grid-template-columns: repeat(1,1fr);
}

And next I'll set up the template area order that I want them displayed in.

I'll first say grid dash template areas.

And then I'll put inside of quotes the name topbar underscore box underscore 1.

And then I'll copy and paste it three times and label them two, three, and four.

sub_grid_topbar {
  display: grid;
  grid-template-columns: repeat(1,1fr);
  grid-template-areas:
    "topbar_box_1"
    "topbar_box_2"
    "topbar_box_3"
    "topbar_box_4";
}

And for now I'll just add one media query and I'll tell it if the screen has a min-width of 800px put four in a row instead of in aline.

So I can copy the dot sub underscore grid underscore topbar and past it down below and then at the top of what I just pasted write, @media only screen and then the min width 800px

And then change the 1 to a four and put the items in a row without the quotes around each one.

sub_grid_topbar {
  display: grid;
  grid-template-columns: repeat(1,1fr);
  grid-template-areas:
    "topbar_box_1"
    "topbar_box_2"
    "topbar_box_3"
    "topbar_box_4";
}
@media only screen and (min-width: 800px) {
  .sub_grid_topbar {
    grid-template-columns: repeat(4,1fr);
    grid-template-areas:
      "topbar_box_1 topbar_box_2 topbar_box_3 topbar_box_4";
  }
}

And across the top of that I will add grid areas for each box with the boxes name.

.topbar_box_1 {
  grid-area: topbar_box_1;
}
.topbar_box_2 {
  grid-area: topbar_box_2;
}
.topbar_box_3 {
  grid-area: topbar_box_3;
}
.topbar_box_4 {
  grid-area: topbar_box_4;
}

And a refresh shows the boxes are now aligned acorss the top of the page.

Now lets go back to our HTML and add something in the featured area.

The first thing I'm going to add is a section and I'm going to add a couple selections to this element.

Section, teaser, top-teaser, mobileCenter

The reason this one has so many selectors is because we want to zig, zag it. One on the right, one on the left, and then back to the right again in desktop, but all in a single line on mobile.

    <div class="featured">
                    <section class="section teaser top-teaser mobileCenter">               
                    </section>
    </div>

I'm going to add in an image and for the moment I'm going to render the image from the CSS.

This makes for a better looking image but it doesn't render as fast so I will move this to the HTML once I've build my database in python.

    <div class="featured">
                    <section class="section teaser top-teaser mobileCenter">
                           <div class="sectionImg"></div>
                      </section>
    </div>

Then I'm going to add another div under that one for my content.

For the selector I'm going to call it sectionCopy

And to use basic animations I can add data-aos="animation_name" to my HTML element. There are several types of animation you can choose from. For example, you can add fade animations like “fade”, “fade-up” and “fade-down-left”.

An under that I will add another element but this time I want to be able to show different tags like, "New", "On Sale", and so on.

So for the class on this one I'll just call it "new" and I'll place the text inside a span and call it "Just In!".

    <div class="featured">
                    <section class="section teaser top-teaser mobileCenter">
                           <div class="sectionImg"></div>
                           <div class="sectionCopy" data-aos="fade-up">
                             <div class="new">
                               <span>Just In!</span>
                             </div>
                           </div>
                      </section>
               </div>

Next I will add my title, description, and button

I'm going to create a selector of block for the button so from time to time, when I want the button to run the full width of the page I can add in my block selector.

    <div class="featured">
                    <section class="section teaser top-teaser mobileCenter">
                           <div class="sectionImg"></div>
                           <div class="sectionCopy" data-aos="fade-up">
                             <div class="new">
                               <span>Just In!</span>
                             </div>
                             <h3>TITILE</h3>
                             <p>Description </p>
                             <a href="#" class="button block">Shop</a>
                           </div>
                      </section>
               </div>

And then I will copy it and past in in two more times.

And where I have top-teaser, I will change that to middle-teaser, and bottom-teaser to allow me to align them as well as change the images out in the CSS for now.

    <div class="featured">
                    <section class="section teaser top-teaser mobileCenter">
                           <div class="sectionImg"></div>
                           <div class="sectionCopy" data-aos="fade-up">
                             <div class="new">
                               <span>Just In!</span>
                             </div>
                             <h3>TITILE</h3>
                             <p>Description. </p>
                             <a href="#" class="button block">Shop</a>
                           </div>
                      </section>
                      <section class="section teaser middle-teaser mobileCenter">
                             <div class="sectionImg"></div>
                             <div class="sectionCopy" data-aos="fade-up">
                               <h3>TITILE</h3>
                               <p>Description. </p>
                               <a href="#" class="button block">Shop</a>
                             </div>
                      </section>
                      <section class="section teaser bottom-teaser mobileCenter">
                             <div class="sectionImg"></div>
                             <div class="sectionCopy" data-aos="fade-up">
                               <h3>TITILE</h3>
                               <p>Description.</p>
                               <a href="#" class="button block">Shop</a>
                             </div>
                      </section>
               </div>

And now I'll go back into my CSS and style this a little.

I'm going to start by giving being very speific about my target, which is the h3 tag inside the section element.  And what I'm wanting to do here is set a color for the text.  Trying to keep all the hex color codes to 3 digitis because were counting milliseconds. 

  .section h3, {
  color: #d00;
}

I only want to set colors once.  Because if I have to change the template colors I want to be able to change the colors for the entire site in one spot.  So for this background color with this text, I'll add in other selectors but will not repeat any of my colors or font sizes.

.button {
  background-color: #d00;
  color: whitesmoke;
}

Next is the hover for my button and I'll change both the background and text color.  I'm thinking green, like a green light, it moves to move forward.

.button:hover { background: #FAEBD7; color: #444; }

Then I'll set the background color for my special, in this case the "Just In" special.

.new {
  background-color: darkslategray;
}
I'll set my text color for new in a second location so this will be my secondary font color.
.new {
  color: burlywood;
}

And now I'll setup the rest of my button, although I will be moving some of this stuff around later to try and use less code.

“display: inline” Property: This property is used to display an element as an inline element (like <span>). The height and width properties are not effected on display:inline; property. It allows only left and right side of margins, not top and bottom. In simple words it has no line break before and after of its neighbor elements and it allows HTML next to it.

Compared to display: inline, the major difference is that display: inline-block allows to set a width and height on the element.

Also, with display: inline-block, the top and bottom margins/paddings are respected, but with display: inline they are not.

Compared to display: block, the major difference is that display: inline-block does not add a line-break after the element, so the element can sit next to other elements.

Then I'll set the font size to 1rem for now but I'll need to come back and look at this.

I want it to stand out so I'll back all the letters uppercase.

Letter spacing defines the spacing between the characters of a block of text.

The default setting is ...
letter-spacing: normal;

I'm using em because it keeps it relative to the font-size.

Text decoration none is telling it I don't want any underlines, linethrows, or anything else.

I want the text centered align.  Aligning text along the center axis can make a page look organized and symmetrical — it can also draw the visitor’s eye to particular elements on the page. For example, titles, block quotes, and call-to-actions are often centered to disrupt the flow of the document and grab the reader’s attention. That’s why I'm centering the text on the button. 

The padding is what creates the button.  

A button should communicate an action to a user. It should appear interactive. On desktop devices, for instance, a button should look ‘clickable.’ Unlike desktop users, mobile users don’t have the opportunity to hover over an element to check for interactivity.

Without this affordance, it’s important to make sure buttons appear interactive without requiring the user to do anything.

Designing with the mobile phone user in mind should be a priority as over 48 percent of page views worldwide are through mobile devices. Your buttons should be touch-friendly for mobile users and clickable for desktop users.

Size

The size of a button also helps make it identifiable as one. Studies by the MIT Touch Lab suggests that 10mm x 10mm is the best minimum size for buttons due to the average size of fingertips.

Designing buttons must not only be pleasing to the eye, but they also need to make tactile sense for the user. Buttons should have a touch target of at least 38px by 38px.  

Cursor pointer - When a cursor hovers over a link, the cursor changes from a pointer to a hand. So, whenever someone hovers over the button, it provides a visual clue that it's clickable.

The following are possible values for the cursor property −

  1. auto
    Shape of the cursor depends on the context area it is over.
  2. 2 Crosshair
    A crosshair or plus sign
  3. 3 default
    An arrow
  4. 4 pointer
    A pointing hand
  5. 5 move
    The I bar
  6. 6 e-resize
    The cursor indicates that an edge of a box is to be moved right (east)
  7. 7 ne-resize
    The cursor indicates that an edge of a box is to be moved up and right (north/east)
  8. 8 nw-resize
    The cursor indicates that an edge of a box is to be moved up and left (north/west)
  9. 9 n-resize
    The cursor indicates that an edge of a box is to be moved up (north)
  10. 10 se-resize
    The cursor indicates that an edge of a box is to be moved down and right (south/east)
  11. 11 sw-resize
    The cursor indicates that an edge of a box is to be moved down and left (south/west)
  12. 12 s-resize
    The cursor indicates that an edge of a box is to be moved down (south)
  13. 13 w-resize
    The cursor indicates that an edge of a box is to be moved left (west)
  14. 14 text
    The I bar
  15. 15 wait
    An hour glass
  16. 16 help
    A question mark or balloon, ideal for use over help buttons
  17. 17 <url>
    The source of a cursor image file

    NOTE − You should try to use only these values to add helpful information for users, and in places, they would expect to see that cursor. For example, using the crosshair when someone hovers over a link can confuse visitors.

Box shadow - The box-shadow CSS property adds shadow effects around an element's frame. You can set multiple effects separated by commas. A box shadow is described by X and Y offsets relative to the element, blur and spread radius, and color.

Width: fit-content; The width CSS property sets an element's width. By default, it sets the width of the content area, but if box-sizing is set to border-box, it sets the width of the border area.
The min-width and max-width properties override width.

Length
Defines the width as an absolute value.
Percentage
Defines the width as a percentage of the containing block's width.
Auto
The browser will calculate and select a width for the specified element.
Max-content
The intrinsic preferred width.
Min-content
The intrinsic minimum width.
Fit-content(<length-percentage>)
Uses the fit-content formula with the available space replaced by the specified argument, i.e. min(max-content, max(min-content, <length-percentage>)).
.button {
  display: inline-block;
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  text-decoration: none;
  text-align: center;
  padding: 0.75em 2em;
  cursor: pointer;
  box-shadow: 0px 4px 30px rgba(0, 0, 0, 0.2);
  width: fit-content;
}

The purpose of the block is to make the button where it is used go full width. 

Display: block means that the element is displayed as a block, as paragraphs and headers have always been. A block has some whitespace above and below it and tolerates no HTML elements next to it, except when ordered otherwise (by adding a float declaration to another element, for instance).

Width: 100%; will make the element as wide as the parent container.

Border: The border property sets the line style for all four sides of an element's border.

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

Next I'm going to set up the new selector but I will most likely combine this one with the button selector later.

I'll add some padding but make it a little smaller than the button for now. 

Border-radius CSS property rounds the corners of an element's outer border edge. You can set a single radius to make circular corners, or two radius's to make elliptical corners.

I'll then transform the text to uppercase, add letter-spacing, font size, and tell the width to fit to content. 

.new {
  padding: 0.5em 1em;
  border-radius: 2px;
  text-transform: uppercase;
  letter-spacing: 0.075em;
  font-size: 0.85em;
  width: fit-content;
}

I'm going to add some padding to the entire section selector.

.section {
  padding: 4em 0;
}

And now I'll add the font size, line height, and font weight to the section h3 header tag.

.section h3 {
  font-size: 2em;
  line-height: 1.5em;
  font-weight: 500;
}

I'll also add a margin that will only effect the button that is inside the section element.

.section .button {
  margin: 1em 0;
}

And now I'll go back into my CSS and style this a little.

.section.teaser {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

And now I'm going to copy and paste the first one and the only thing I'm going to change is the change thell go back into my CSS and style this a little.

.section.teaser.top-teaser .sectionImg {
  background: url("converting_traffic/1.webp") no-repeat;
  background-size: cover;
  background-position: center center;
  width: 100%;
  height: 450px;
  grid-column: 1/7;
}

And now I'll go back into my CSS and style this a little.

.section.teaser.top-teaser .sectionCopy {
  grid-column: 8/12;
}

And now I'm going to copy and paste the first one and the only thing I'm going to change is the change thell go back into my CSS and style this a little.

.section.teaser.bottom-teaser .sectionImg {
  background: url("converting_traffic/2.webp") no-repeat;
  background-size: cover;
  background-position: center 10%;
  width: 100%;
  height: 450px;
  grid-column: 1/7;
}

And now I'll go back into my CSS and style this a little.

.section.teaser.bottom-teaser .sectionCopy {
  grid-column: 8/12;
}

And now I'm going to copy and paste the first one and the only thing I'm going to change is the top-teaser to middle teaser and the grid row.

.section.teaser.middle-teaser .sectionImg {
  background: url("converting_traffic/4.webp") no-repeat;
  background-size: cover;
  width: 100%;
  height: 450px;
  grid-column: 7/13;
  grid-row: 1/2;
}

And now I'll go back into my CSS and style this a little.

.section.teaser.middle-teaser .sectionCopy {
  grid-column: 2/6;
}

And now I'll go back into my CSS and style this a little.

@media (max-width: 700px) {
  :root {
    padding: 10%
  }

And now I'll go back into my CSS and style this a little.

  .section {
    padding: 2em 0;
  }

And now I'll go back into my CSS and style this a little.

  .block {
    display: block;
    width: 70%;
    border: none;
  }

And now I'll go back into my CSS and style this a little.

  .new {
    margin: auto;
  }

And now I'll go back into my CSS and style this a little.

  .section.teaser.mobileCenter {
    grid-template-rows: 1fr 1fr;
    text-align: center;
  }

And now I'll go back into my CSS and style this a little.

  .section.teaser.mobileCenter .sectionImg {
    grid-column: 1/13;
    grid-row: 1/2;
    height: 100%;
  }

And now I'll go back into my CSS and style this a little.

  .section.teaser.mobileCenter .sectionCopy {
    grid-column: 2/12;
    grid-row: 2/3;
    margin-top: 2em;
    padding: 0;
  }
 
}

And this is what the page looks like now.

Lets go back into the HTML and set up the header.

The first thing I'm going to do is add some selectors ...grid-box, header, and sub_grid_header.

Then I'll add an element with a selector of header-box-1.

Inside that selector I'm going to add an image, alt tag, I'll lazy load it, and then I'll set the width and height.

  <header class="grid-box header sub_grid_header">
                  <div class="header-box-1">
                      <a href="/" aria-label="go to home page">
                      <img src="img/logo.webp" alt="" loading="lazy" style="height: 35px; width: 186px;">
                    </a>
                    </div>
              </div>
            </header>

I'm going to create an element with a selector of header box 2 and then I'll copy that over for elements 3 & 4.

Then in 3 I'm going to add anoter element with the selector of search__bar__header.

After that I will add in my form with the action of searcg_results with a method of get.

Then I'll have a button for the search box.

  <header class="grid-box header sub_grid_header">
                  <div class="header-box-1">
                      <a href="/" aria-label="go to home page">
                      <img src="img/logo.webp" alt="" loading="lazy" style="height: 35px; width: 186px;">
                    </a>
                    </div>
                    <div class="header-box-2">
                  </div>
                    <div class="header-box-3">
                      <div class="search__bar__header">
                      <form action="/search/results/" method="get">
                          <div class="search-box">
                          <input type="search" name="q" class="search-input" id="search" placeholder="search">
                          <button type="submit" class="submit search-button">
                          Search
                          </button>
                        </div>
                      </form>
                    </div>
                    </div>
                    <div class="header-box-4">
              </div>
            </header>

Now in the last one I'm going to add in a couple SVG's.

  <header class="grid-box header sub_grid_header">
                  <div class="header-box-1">
                      <a href="/" aria-label="go to home page">
                      <img src="img/logo.webp" alt="" loading="lazy" style="height: 35px; width: 186px;">
                    </a>
                    </div>
                    <div class="header-box-2">
                  </div>
                    <div class="header-box-3">
                      <div class="search__bar__header">
                      <form action="/search/results/" method="get">
                          <div class="search-box">
                          <input type="search" name="q" class="search-input" id="search" placeholder="search">
                          <button type="submit" class="submit search-button">
                          Search
                          </button>
                        </div>
                      </form>
                    </div>
                    </div>
                    <div class="header-box-4">
                      
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-folder-symlink-fill" viewBox="0 0 16 16">
                          <path d="M13.81 3H9.828a2 2 0 0 1-1.414-.586l-.828-.828A2 2 0 0 0 6.172 1H2.5a2 2 0 0 0-2 2l.04.87a1.99 1.99 0 0 0-.342 1.311l.637 7A2 2 0 0 0 2.826 14h10.348a2 2 0 0 0 1.991-1.819l.637-7A2 2 0 0 0 13.81 3zM2.19 3c-.24 0-.47.042-.684.12L1.5 2.98a1 1 0 0 1 1-.98h3.672a1 1 0 0 1 .707.293L7.586 3H2.19zm9.608 5.271l-3.182 1.97c-.27.166-.616-.036-.616-.372V9.1s-2.571-.3-4 2.4c.571-4.8 3.143-4.8 4-4.8v-.769c0-.336.346-.538.616-.371l3.182 1.969c.27.166.27.576 0 .742z"/>
                        </svg>
                              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-compass" viewBox="0 0 16 16">
                                <path d="M8 16.016a7.5 7.5 0 0 0 1.962-14.74A1 1 0 0 0 9 0H7a1 1 0 0 0-.962 1.276A7.5 7.5 0 0 0 8 16.016zm6.5-7.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0z"/>
                                <path d="M6.94 7.44l4.95-2.83-2.83 4.95-4.949 2.83 2.828-4.95z"/>
                              </svg>
                              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-droplet-half" viewBox="0 0 16 16">
                              <path fill-rule="evenodd" d="M7.21.8C7.69.295 8 0 8 0c.109.363.234.708.371 1.038.812 1.946 2.073 3.35 3.197 4.6C12.878 7.096 14 8.345 14 10a6 6 0 0 1-12 0C2 6.668 5.58 2.517 7.21.8zm.413 1.021A31.25 31.25 0 0 0 5.794 3.99c-.726.95-1.436 2.008-1.96 3.07C3.304 8.133 3 9.138 3 10c0 0 2.5 1.5 5 .5s5-.5 5-.5c0-1.201-.796-2.157-2.181-3.7l-.03-.032C9.75 5.11 8.5 3.72 7.623 1.82z"/>
                              <path fill-rule="evenodd" d="M4.553 7.776c.82-1.641 1.717-2.753 2.093-3.13l.708.708c-.29.29-1.128 1.311-1.907 2.87l-.894-.448z"/>
                             </svg>
            
              </div>
            </header>
  <header class="grid-box header sub_grid_header">
                  <div class="header-box-1">
                      <a href="/" aria-label="go to home page">
                      <img src="img/logo.webp" alt="" loading="lazy" style="height: 35px; width: 186px;">
                    </a>
                    </div>
                    <div class="header-box-2">
                  </div>
                    <div class="header-box-3">
                      <div class="search__bar__header">
                      <form action="/search/results/" method="get">
                          <div class="search-box">
                          <input type="search" name="q" class="search-input" id="search" placeholder="search">
                          <button type="submit" class="submit search-button">
                          Search
                          </button>
                        </div>
                      </form>
                    </div>
                    </div>
                    <div class="header-box-4">
                      
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-folder-symlink-fill" viewBox="0 0 16 16">
                          <path d="M13.81 3H9.828a2 2 0 0 1-1.414-.586l-.828-.828A2 2 0 0 0 6.172 1H2.5a2 2 0 0 0-2 2l.04.87a1.99 1.99 0 0 0-.342 1.311l.637 7A2 2 0 0 0 2.826 14h10.348a2 2 0 0 0 1.991-1.819l.637-7A2 2 0 0 0 13.81 3zM2.19 3c-.24 0-.47.042-.684.12L1.5 2.98a1 1 0 0 1 1-.98h3.672a1 1 0 0 1 .707.293L7.586 3H2.19zm9.608 5.271l-3.182 1.97c-.27.166-.616-.036-.616-.372V9.1s-2.571-.3-4 2.4c.571-4.8 3.143-4.8 4-4.8v-.769c0-.336.346-.538.616-.371l3.182 1.969c.27.166.27.576 0 .742z"/>
                        </svg>
                              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-compass" viewBox="0 0 16 16">
                                <path d="M8 16.016a7.5 7.5 0 0 0 1.962-14.74A1 1 0 0 0 9 0H7a1 1 0 0 0-.962 1.276A7.5 7.5 0 0 0 8 16.016zm6.5-7.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0z"/>
                                <path d="M6.94 7.44l4.95-2.83-2.83 4.95-4.949 2.83 2.828-4.95z"/>
                              </svg>
                              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-droplet-half" viewBox="0 0 16 16">
                              <path fill-rule="evenodd" d="M7.21.8C7.69.295 8 0 8 0c.109.363.234.708.371 1.038.812 1.946 2.073 3.35 3.197 4.6C12.878 7.096 14 8.345 14 10a6 6 0 0 1-12 0C2 6.668 5.58 2.517 7.21.8zm.413 1.021A31.25 31.25 0 0 0 5.794 3.99c-.726.95-1.436 2.008-1.96 3.07C3.304 8.133 3 9.138 3 10c0 0 2.5 1.5 5 .5s5-.5 5-.5c0-1.201-.796-2.157-2.181-3.7l-.03-.032C9.75 5.11 8.5 3.72 7.623 1.82z"/>
                              <path fill-rule="evenodd" d="M4.553 7.776c.82-1.641 1.717-2.753 2.093-3.13l.708.708c-.29.29-1.128 1.311-1.907 2.87l-.894-.448z"/>
                             </svg>
            
              </div>
            </header>
  <header class="grid-box header sub_grid_header">
                  <div class="header-box-1">
                      <a href="/" aria-label="go to home page">
                      <img src="img/logo.webp" alt="" loading="lazy" style="height: 35px; width: 186px;">
                    </a>
                    </div>
                    <div class="header-box-2">
                  </div>
                    <div class="header-box-3">
                      <div class="search__bar__header">
                      <form action="/search/results/" method="get">
                          <div class="search-box">
                          <input type="search" name="q" class="search-input" id="search" placeholder="search">
                          <button type="submit" class="submit search-button">
                          Search
                          </button>
                        </div>
                      </form>
                    </div>
                    </div>
                    <div class="header-box-4">
                      
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-folder-symlink-fill" viewBox="0 0 16 16">
                          <path d="M13.81 3H9.828a2 2 0 0 1-1.414-.586l-.828-.828A2 2 0 0 0 6.172 1H2.5a2 2 0 0 0-2 2l.04.87a1.99 1.99 0 0 0-.342 1.311l.637 7A2 2 0 0 0 2.826 14h10.348a2 2 0 0 0 1.991-1.819l.637-7A2 2 0 0 0 13.81 3zM2.19 3c-.24 0-.47.042-.684.12L1.5 2.98a1 1 0 0 1 1-.98h3.672a1 1 0 0 1 .707.293L7.586 3H2.19zm9.608 5.271l-3.182 1.97c-.27.166-.616-.036-.616-.372V9.1s-2.571-.3-4 2.4c.571-4.8 3.143-4.8 4-4.8v-.769c0-.336.346-.538.616-.371l3.182 1.969c.27.166.27.576 0 .742z"/>
                        </svg>
                              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-compass" viewBox="0 0 16 16">
                                <path d="M8 16.016a7.5 7.5 0 0 0 1.962-14.74A1 1 0 0 0 9 0H7a1 1 0 0 0-.962 1.276A7.5 7.5 0 0 0 8 16.016zm6.5-7.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0z"/>
                                <path d="M6.94 7.44l4.95-2.83-2.83 4.95-4.949 2.83 2.828-4.95z"/>
                              </svg>
                              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-droplet-half" viewBox="0 0 16 16">
                              <path fill-rule="evenodd" d="M7.21.8C7.69.295 8 0 8 0c.109.363.234.708.371 1.038.812 1.946 2.073 3.35 3.197 4.6C12.878 7.096 14 8.345 14 10a6 6 0 0 1-12 0C2 6.668 5.58 2.517 7.21.8zm.413 1.021A31.25 31.25 0 0 0 5.794 3.99c-.726.95-1.436 2.008-1.96 3.07C3.304 8.133 3 9.138 3 10c0 0 2.5 1.5 5 .5s5-.5 5-.5c0-1.201-.796-2.157-2.181-3.7l-.03-.032C9.75 5.11 8.5 3.72 7.623 1.82z"/>
                              <path fill-rule="evenodd" d="M4.553 7.776c.82-1.641 1.717-2.753 2.093-3.13l.708.708c-.29.29-1.128 1.311-1.907 2.87l-.894-.448z"/>
                             </svg>
            
              </div>
            </header>
  <header class="grid-box header sub_grid_header">
                  <div class="header-box-1">
                      <a href="/" aria-label="go to home page">
                      <img src="img/logo.webp" alt="" loading="lazy" style="height: 35px; width: 186px;">
                    </a>
                    </div>
                    <div class="header-box-2">
                  </div>
                    <div class="header-box-3">
                      <div class="search__bar__header">
                      <form action="/search/results/" method="get">
                          <div class="search-box">
                          <input type="search" name="q" class="search-input" id="search" placeholder="search">
                          <button type="submit" class="submit search-button">
                          Search
                          </button>
                        </div>
                      </form>
                    </div>
                    </div>
                    <div class="header-box-4">
                      
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-folder-symlink-fill" viewBox="0 0 16 16">
                          <path d="M13.81 3H9.828a2 2 0 0 1-1.414-.586l-.828-.828A2 2 0 0 0 6.172 1H2.5a2 2 0 0 0-2 2l.04.87a1.99 1.99 0 0 0-.342 1.311l.637 7A2 2 0 0 0 2.826 14h10.348a2 2 0 0 0 1.991-1.819l.637-7A2 2 0 0 0 13.81 3zM2.19 3c-.24 0-.47.042-.684.12L1.5 2.98a1 1 0 0 1 1-.98h3.672a1 1 0 0 1 .707.293L7.586 3H2.19zm9.608 5.271l-3.182 1.97c-.27.166-.616-.036-.616-.372V9.1s-2.571-.3-4 2.4c.571-4.8 3.143-4.8 4-4.8v-.769c0-.336.346-.538.616-.371l3.182 1.969c.27.166.27.576 0 .742z"/>
                        </svg>
                              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-compass" viewBox="0 0 16 16">
                                <path d="M8 16.016a7.5 7.5 0 0 0 1.962-14.74A1 1 0 0 0 9 0H7a1 1 0 0 0-.962 1.276A7.5 7.5 0 0 0 8 16.016zm6.5-7.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0z"/>
                                <path d="M6.94 7.44l4.95-2.83-2.83 4.95-4.949 2.83 2.828-4.95z"/>
                              </svg>
                              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-droplet-half" viewBox="0 0 16 16">
                              <path fill-rule="evenodd" d="M7.21.8C7.69.295 8 0 8 0c.109.363.234.708.371 1.038.812 1.946 2.073 3.35 3.197 4.6C12.878 7.096 14 8.345 14 10a6 6 0 0 1-12 0C2 6.668 5.58 2.517 7.21.8zm.413 1.021A31.25 31.25 0 0 0 5.794 3.99c-.726.95-1.436 2.008-1.96 3.07C3.304 8.133 3 9.138 3 10c0 0 2.5 1.5 5 .5s5-.5 5-.5c0-1.201-.796-2.157-2.181-3.7l-.03-.032C9.75 5.11 8.5 3.72 7.623 1.82z"/>
                              <path fill-rule="evenodd" d="M4.553 7.776c.82-1.641 1.717-2.753 2.093-3.13l.708.708c-.29.29-1.128 1.311-1.907 2.87l-.894-.448z"/>
                             </svg>
            
              </div>
            </header>

Now I'm going to go into the CSS and add

  .search__bar__header input[type="search"] {
  padding: 10px;
  outline: none;
  border: none;
  box-shadow: 0px 0px 2px #107fa8;
}

@media (max-width: 576px) {
  .search__bar__header input[type="button"] {
    padding: 9px;
    font-size: 0.7em;
  }
}

input {
  display: initial;
}


.search-button {
    padding: 10px;
    outline: none;
    border: none;
    cursor: pointer;
    background-color: red;
    color: whitesmoke;
    font-size: 1.2rem;
}

Now we want to set up our mega menu.

<nav class="navbar">

    <!-- Menu Toggle for Small Screens -->
    
      <input id="menu-toggle" type="checkbox" />
      <label class='menu-button-container' for="menu-toggle">
          <div class='menu-button'></div>
      </label>
    
    <!--/ Menu Toggle for Small Screens -->
    
    <!-- Main Menu -->
    
      <ul class="menu">
        <li>

          <a href="">Products ↓</a>

          <!-- Submenu Toggle for Small Screens -->
            <input class='submenu-toggle' id="submenu-toggle-id" type="checkbox" />
            <label class='submenu-button-container' for="submenu-toggle-id">
                <div class='submenu-button'></div>
            </label>
          <!--/ Submenu Toggle for Small Screens -->

          <!-- Submenu -->
          <div class="submenu">

            <div class="column">

              <ul>
                <li><a href="">Sub Menu 1</a></li>
                <li>Sub Menu 2</li>
              </ul>

            </div>

            <div class="column">

              <ul>
                <li><a href="">Sub Menu 1</a></li>
                <li><a href="">Sub Menu 1</a></li>
                
              </ul>

            </div>
            <div class="column">

              <ul>
                <li><a href="">Sub Menu 1</a></li>
                <li><a href="">Sub Menu 1</a></li>
                
                
              </ul>

            </div>
            <div class="column">

              <ul>
                <li><a href="">Sub Menu 1</a></li>
                <li><a href="">Sub Menu 1</a></li>
                
                
              </ul>

            </div>

          </div>
          <!--/ Submenu -->

        </li>
        <li>

          <a href="">Products ↓</a>

          <!-- Submenu Toggle for Small Screens -->
            
<body>
<div class="grid-container">
<nav>

Inside the nav we’re going to add a <ul> tag, which is an unordered (bulleted) list. And I’ll give it some class with a topnav selector.

<ul class="topnav">

I’ll add the

<li>

tag and now I have an unordered list.

For the moment I’ll style inline.

Elements with a 'display' property of 'list-item' are formatted visually with a marker and I’m telling it not to display that marker.

Then I’m telling it to display inline. Which means that the element is displayed inside the current block on the same line.

<li style="list-style: none; display: inline">

Labels are critical for blind users, user with low vision, users with mobility disabilities and users with memory loss. Missing labels will make a form inaccessible for many users. Since there is nothing indicating the purpose of the link, the aria-label attribute is used to provide the label with this information.

<a aria-label="go to home page" href="/">

Then I'm telling it to use an unordered list.

<ul>

The list will go between the li tags. 

<li>

The first item in the list is the logo. 

<div class="logo"></div>

</li>

<li class="right"></li>

<li style="list-style: none">Home</li>

</ul>

</a>

</li>

<li class="right"> <a href="#">About</a> </li>

<li class="right"> <a href="#">Contact</a> </li>

</ul>

</nav>

<main class="grid-box">

<h3 style="color:#444;">Content</h3>

</main>

<aside class="grid-box"> aside </aside>

<footer class="grid-box"> footer </footer>

</div>

</body>

</html>

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title></title>

<style>

/* Defining the grid areas */

nav {

background-color: #00242f57;

grid-area: nav;

}

main {

background-color: #E5E5E5;

color: #1A1A1A;

grid-area: main;

}

aside {

background-color: #BFBFBF;

color: #4D4D4D;

grid-area: aside;

}

footer {

background-color: #4D4D4D;

color: #BFBFBF;

grid-area: footer;

}

/* Styles for the grid container */

.grid-container {

/* Styles for the placement of the grid areas */

display: grid;

grid-gap: .5rem;

grid-template-areas: "nav" "main" "aside" "footer";

padding: .25rem;

}

/* 2 media queries for the grid container */

@media only screen and (min-width: 550px) {

.grid-container {

grid-gap: .75rem;

grid-template-areas: "nav nav" "main main" "aside ." "footer footer";

grid-template-columns: repeat(2, 1fr);

padding: .5rem;

}

}

@media only screen and (min-width: 800px) {

.grid-container {

grid-gap: 1rem;

grid-template-areas: "nav nav nav" "aside main main" "footer footer footer";

grid-template-columns: repeat(3, 1fr);

padding: .75rem;

}

}

/* Styles for the grid items */

.grid-box {

border-radius: .125rem;

font-size: 1.25rem;

padding: .5rem;

}

/* 2 media queries for the grid items */

@media only screen and (min-width: 550px) {

.grid-box {

font-size: 1.5rem;

padding: .75rem;

}

}

@media only screen and (min-width: 800px) {

.grid-box {

font-size: 1.25rem;

padding: 1rem;

}

}

/*Navbar*/

.logo {

background: url(/img/logo.webp) no-repeat top left;

height: 45px;

margin: 10px;

width: 200px;

}

.logo:hover {

filter: brightness(110%);

}

ul.topnav {

background-color: #333;

list-style-type: none;

margin: 0;

overflow: hidden;

padding: 0;

}

ul.topnav li {

float: left;

}

ul.topnav li a {

color: white;

display: block;

padding: 14px 16px;

text-align: center;

text-decoration: none;

}

ul.topnav li a:hover:not(.active) {

background-color: #111;

}

ul.topnav li a.active {

background-color: #4CAF50;

}

ul.topnav li.right {

float: right;

}

@media screen and (max-width: 600px) {

ul.topnav li.right,

ul.topnav li {

float: none;

}

}

</style>

</head>

<body>

<div class="grid-container">

<nav>

<ul class="topnav">

<li style="list-style: none; display: inline">

<a aria-label="go to home page" href="/">

<ul>

<li>

<div class="logo"></div>

</li>

<li class="right"></li>

<li style="list-style: none">Home</li>

</ul>

</a>

</li>

<li class="right"> <a href="#">About</a> </li>

<li class="right"> <a href="#">Contact</a> </li>

</ul>

</nav>

<main class="grid-box">

<h3 style="color:#444;">Content</h3>

</main>

<aside class="grid-box"> aside </aside>

<footer class="grid-box"> footer </footer>

</div>

</body>

</html>

Now lets dress up the left menu a little.

And inside the grid-container I’ll add a topbar, for our phone number or a message. And then I’ll add a selector for styling and I’ll call it grid-box and I’ll use this one on all the elements we create for styling our content inside this area.

And I’ll add a topbar on this one for styling things specifically for this area.

<!DOCTYPE html>   
      <html>
           <head>
                <meta charset="utf-8">   
                <title></title>   
           </head>
           <body>
               <header>
               </header>
           </body>
      </html>

I'm going to put all three top menus inside the header tag.

So inside the body tags I'll add the header tag.

<!DOCTYPE html>   
      <html>
           <head>
                <meta charset="utf-8">   
                <title></title>   
           </head>
           <body>
               <header>
                  <div class="header-content-top">
                  </div>
               </header>
           </body>
      </html>

I'm going to put the top menu inside a div tag with a css styling class name of header-content-top.

<!DOCTYPE html>   
      <html>
           <head>
                <meta charset="utf-8">   
                <title></title>   
           </head>
           <body>
               <header>
                  <div class="header-content-top">
                     <div class="content">
                     </div>
                  </div>
               </header>
           </body>
      </html>

Then I'm going to put a div class with content inside that one

<!DOCTYPE html>   
<html>
  <head>
    <meta charset="utf-8">   
    <title></title>   
  </head>
  <body>
    <header>
      <div class="header-content-top">
        <div class="content">
          <span>
            <img src="icon/phone.webp" alt="phone" width="15" height="15"/> 770-897-6107
          </span> 
          <span>
            <img src="icon/email.webp" alt="email" width="15" height="15"/> greggeniis@gmail.com
          </span>
          <span>
            <a href="/"<img src="icon/delivery.webp" alt="phone" width="15" height="15"/> Track</a>
          </span>
          <span>
            <a href="
            /pages/about/"
            ><img src="icon/flag.webp" alt="flag" width="15" height="15"/>
          </span>
        </div>
      </div>
    </header>
  </body>
</html>

Top Menu

First thing I want to do is create a folder for my project and since I'm in Linux I'll just type ...

$ cd Desktop

To move into my Desktop and then I'll type ...

$ mkdir Smutsia

Then I'll go into that folder by typing ...

$ cd SmutSia

And I'll create some HTML files by typing ...

$ touch {index,about,privacy_policy,profile,detail,login,signup,logout,password_reset,password_change,order_summary,checkout,payment,receipt}.html
    

I might have missed some pages so we may need to add more latter but as you can see there are a lot of pages involved in creating a shopping cart.

I'll open Sublime and start off by typing ...

<html> 

hitting enter and letting sublime feel out the rest.

<!DOCTYPE html>   
      <html>
           <head>
                <meta charset="utf-8">   
                <title></title>   
           </head>
           <body>                  
           </body>
      </html>

This website has three top menus.

I’ll start by writing the content for the very top of the page and using feeler text because the logo, menus, text, and such will be feed into the template from the admin so none of the content will matter once we convert it into template code.

<!DOCTYPE html>   
      <html>
           <head>
                <meta charset="utf-8">   
                <title></title>   
           </head>
           <body>
               <header>
               </header>
           </body>
      </html>

I'm going to put all three top menus inside the header tag.

So inside the body tags I'll add the header tag.

<!DOCTYPE html>   
      <html>
           <head>
                <meta charset="utf-8">   
                <title></title>   
           </head>
           <body>
               <header>
                  <div class="header-content-top">
                  </div>
               </header>
           </body>
      </html>

I'm going to put the top menu inside a div tag with a css styling class name of header-content-top.

<!DOCTYPE html>   
      <html>
           <head>
                <meta charset="utf-8">   
                <title></title>   
           </head>
           <body>
               <header>
                  <div class="header-content-top">
                     <div class="content">
                     </div>
                  </div>
               </header>
           </body>
      </html>

Then I'm going to put a div class with content inside that one

<!DOCTYPE html>   
<html>
  <head>
    <meta charset="utf-8">   
    <title></title>   
  </head>
  <body>
    <header>
      <div class="header-content-top">
        <div class="content">
          <span>
            <img src="icon/phone.webp" alt="phone" width="15" height="15"/> 770-897-6107
          </span> 
          <span>
            <img src="icon/email.webp" alt="email" width="15" height="15"/> greggeniis@gmail.com
          </span>
          <span>
            <a href="/"<img src="icon/delivery.webp" alt="phone" width="15" height="15"/> Track</a>
          </span>
          <span>
            <a href="
            /pages/about/"
            ><img src="icon/flag.webp" alt="flag" width="15" height="15"/>
          </span>
        </div>
      </div>
    </header>
  </body>
</html>

Header CSS

Then I’ll add in some css to add a little style to the code.

<style>
*
</style>

The star is a CSS reset for browsers saying reset "all elements" (a universal reset), making things look the same in all browsers.

<style>
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}
</style>

Border-box tells the browser to account for any border and or padding. So the content shrink to absorb that extra width.

And then I'm setting all elements to have zero margins, and zero padding so that the website looks the same in any browser.

<style>
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
body  {
  font-family: Georgia, serif;
}
</style>

Times vs Georgia vs Verdana fonts on computer screens, test have shown Georgia is easier to read, sharper, and more legible than Times.

So I'm going to set the font to Georgia

<style>
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
body  {
  font-family: Georgia, serif;
}
label,
a {
  text-decoration: none;
  color: whitesmoke;
}
</style>

Now I'm telling the label and any links that I don't want any text decoration like underline, solid, double, dashed or the like.

And I'm setting the font color to smokewhite.

You should never use pur black or pure white as they will cause eye strain.

White has 100% color brightness, and black has 0% color brightness

<style>
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
body  {
  font-family: Georgia, serif;
}
label,
a {
  text-decoration: none;
  color:whitesmoke;
}
ul {
  list-style: none;
  padding: 0;
}
</style>

Now I'm telling it that I want a bulleted list but without any bullets or padding.

<style>
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
body  {
  font-family: Georgia, serif;
}
label,
a {
  text-decoration: none;
  color: whitesmoke;
}
ul {
  list-style: none ;
  padding: 0 ;
}
header {
  position: sticky;
  top: 0;
  width: 100%;
  z-index: 10;
}
</style>

We are going to add a head.

<style>
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
body  {
  font-family: Georgia, serif;
}
label,
a {
  text-decoration: none;
  color:whitesmoke;
}
ul {
  list-style: none;
  padding: 0;
}
</style>

Now I'm telling it that I want a bulleted list but without any bullets or padding.

<style>
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
body  {
  font-family: Georgia, serif;
}
label,
a {
  text-decoration: none;
  color: whitesmoke;
}
ul {
  list-style: none;
  padding: 0;
}
header {
  position: sticky;
  top: 0;
  width: 100%;
  z-index: 10;
}
.header-content-top {
  background: #5c5c5c;
  height: 30px;
  width: 100%;
}
</style>

Now I'm telling it that I want a bulleted list but without any bullets or padding.

<style>
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
body  {
  font-family: Georgia, serif;
}
label,
a {
  text-decoration: none;
  color: whitesmoke;
}
ul {
  list-style: none;
  padding: 0;
}
header {
  position: sticky;
  top: 0;
  width: 100%;
  z-index: 10;
}
.header-content-top {
  background: #5c5c5c;
  height: 30px;
  width: 100%;
}
.header-content-top .content {
  align-items: center;
  display: flex;
  height: 30px;
  justify-content: flex-end;
  margin: 0 auto;
  max-width: 1300px;
  width: 100%;
}
</style>

Now I'm telling it that I want a bulleted list but without any bullets or padding.

<style>
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
body  {
  font-family: Georgia, serif;
}
label,
a {
  text-decoration: none;
  color: whitesmoke;
}
ul {
  list-style: none;
  padding: 0;
}
header {
  position: sticky;
  top: 0;
  width: 100%;
  z-index: 10;
}
.header-content-top {
  background: #5c5c5c;
  height: 30px;
  width: 100%;
}
.header-content-top .content {
  align-items: center
  display: flex;
  height: 30px;
  justify-content: flex-end;
  margin: 0 auto;
  max-width: 1300px;
  width: 100%;
}
.header-content-top .content span {
  color: #fff;
  font-size: 12px;
  margin: 0 15px;
}

</style>

Now I'm telling it that I want a bulleted list but without any bullets or padding.


Middle Menu

                     <div class="container">
       <!-- logo -->
       <strong class="logo"></strong>
       <!-- open nav mobile -->

          <!--search -->
          <label class="open-search" for="open-search">
            <i class="fas fa-search"></i>
                  <input class="input-open-search" id="open-search" type="checkbox" name="menu" />
          <div class="search">
            <button class="button-search"><img src="icon/search.webp" alt="email" width="15" height="15"/></button>
            <input type="text" placeholder="What are you looking for?" class="input-search"/>
          </div>
          </label>
          <!-- // search -->
          <nav class="nav-content">
            <!-- nav -->
            <ul class="nav-content-list">
              <li class="nav-content-item account-login">
                <label class="open-menu-login-account" for="open-menu-login-account">
                  <input class="input-menu" id="open-menu-login-account" type="checkbox" name="menu" />
                  <span class="login-text"><a href="account_signup"><img src="icon/person.webp" alt="phone" width="15" height="15"/>Hello, login <strong>Create Account</strong></a></span>

                  <!-- submenu -->
                  <ul class="login-list">
                    <li class="login-list-item"><a href="#">My account</a></li>
                    <li class="login-list-item"><a href="#">Create account</a></li>
                    <li class="login-list-item"><a href="#">logout</a></li>
                    </label>
                  </ul>
              </li>
              <li class="nav-content-item"><img src="icon/heart.webp" alt="heart" width="15" height="15"/></a></li>
              <li class="nav-content-item">cart>
              </a></li>
              &lt;!-- call to action -->
            &lt;/ul>
          </nav>
        <div>



      

Mega Menu


        .container {
  align-items: center;
  display: flex;
  height: 70px;
  justify-content: space-between;
  margin: 0 auto;
  max-width: 100%;
  padding: 0 15px;
  position: relative;
  width: 100%;
  background-color: #5c5c5c;
}
.container .logo {
  float: left;
  padding:0 0 6px 0;
  background: url(img/logo.webp) no-repeat top left;
  margin: 10px;
  width: 185px;
  height: 45px;
}
.container .open-search {
  border-radius: 3px;
  flex: auto;
  margin: 0 15px;
  overflow: hidden;
  position: relative;
}
@media (max-width: 991px) {
  .container .open-search {
    margin: 0;
    position: static;
    text-align: right;
  }
}
.container .open-search .fa-search {
  display: none;
}
@media (max-width: 991px) {
  .container .open-search .fa-search {
    display: block;
  }
}
.container .open-search .input-open-search {
  display: none;
}
.container .open-search .input-open-search:checked ~ .search {
  display: block;
}
@media (max-width: 991px) {
  .container .search {
    display: none;
    position: absolute;
    left: 0;
    top: 70px;
    width: 100%;
    z-index: 999;
  }
}
.container .search .input-search {
  border-radius: 3px;
  border: 1px solid #e1e1e1;
  height: 40px;
  padding: 0 70px 0 15px;
  width: 100%;
  background: white no-repeat;
  transition: 100ms all linear 0s;
  background-image: linear-gradient(to bottom, rgba(77, 97, 252, 0.63) 0%, #4d61fc 90%), linear-gradient(to bottom, #e1e1e1, #e1e1e1);
  background-size: 0 2px, 100% 1px;
  background-position: 50% 100%, 50% 100%;
  transition: background-size 0.3s cubic-bezier(0.64, 0.09, 0.08, 1);
}
.container .search .input-search:focus {
  background-size: 100% 2px, 100% 1px;
  outline: none;
}
.container .search .button-search {
  background: gold;
  border: 0;
  color: #fff;
  cursor: pointer;
  padding: 13px 20px;
  position: absolute;
  right: 0px;
  top: 0px;
}
.container .search .button-search .fa-search {
  display: block;
}
.container .nav-content .nav-content-list {
  align-items: center;
  display: flex;
  justify-content: space-between;
  padding: 0 15px;
}
.container .nav-content .nav-content-list .nav-content-item {
  align-items: center;
  display: flex;
  height: 40px;
  margin: 0 5px;
  position: relative;
  transition: 100ms all linear 0s;
}
@media (max-width: 991px) {
  .container .nav-content .nav-content-list .nav-content-item {
    padding: 0 5px;
  }
}
.container .nav-content .nav-content-list .nav-content-item .item-arrow {
  margin-left: 5px;
  position: relative;
  top: -3px;
}
@media (max-width: 768px) {
  .container .nav-content .nav-content-list .nav-content-item .item-arrow {
    display: none;
  }
}
.container .nav-content .nav-content-list .nav-content-item .open-menu-login-account {
  align-items: center;
  cursor: pointer;
  display: flex;
  position: relative;
}
.container .nav-content .nav-content-list .nav-content-item .input-menu {
  display: none;
}
.container .nav-content .nav-content-list .nav-content-item .input-menu:checked ~ .login-list {
  display: block;
}
.container .nav-content .nav-content-list .nav-content-item .login-list {
  background: #fff;
  border-bottom: 3px solid gold;
  border-radius: 3px;
  box-shadow: 2px 9px 49px -17px rgba(0, 0, 0, 0.3);
  display: none;
  overflow: hidden;
  position: absolute;
  right: 0;
  top: 28px;
  transition: 100ms all linear 0s;
  width: 200px;
  z-index: 10;
}
.container .nav-content .nav-content-list .nav-content-item .login-list .login-list-item {
  padding: 15px 20px;
}
.container .nav-content .nav-content-list .nav-content-item .login-list .login-list-item:hover {
  background: gold;
}
.container .nav-content .nav-content-list .nav-content-item .login-list .login-list-item:hover a {
  color: #fff;
}
.container .nav-content .nav-content-list .nav-content-item:nth-child(2):hover .fas {
  color: #e74c3c;
}
.container .nav-content .nav-content-list .nav-content-item:hover .fas {
  color: gold;
}
.container .nav-content .nav-content-list .account-login .login-text {
  align-items: end;
  display: flex;
  flex-direction: column;
  font-size: 12px;
  margin-left: 5px;
}
@media (max-width: 991px) {
  .container .nav-content .nav-content-list .account-login .login-text {
    display: none;
  }
}
.container .nav-content .nav-content-list .account-login .login-text strong {
  display: block;
}
.container .nav-content .nav-content-list .nav-content-link {
  border-radius: 3px;
  font-size: 19px;
  padding: 10px 15px;
  transition: 100ms all linear 0s;
}
@media (max-width: 991px) {
  .container .nav-content .nav-content-list .nav-content-link {
    padding: 0;
  }
}

Mega Menu

The next thing we want to do is set up our urls.py folder.

<!-- logo --> <nav class="featured-category"> <ul class="nav-row"> <li class='nav-row-list droppable'> <a class="white" href='/catalog/list/'>HTML <img src="icon/icon.webp" alt="phone" width="10" height="10"/></a> <div class='mega-menu'> <div class="container cf"> <ul class="ul-reset"> <h3>HTML 5</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> <ul class="ul-reset"> <h3>Lawnmower Spares</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> <ul class="ul-reset"> <h3>Strimmer Spares</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> <ul class="ul-reset"> <h3>New Machines</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul>< </div><!-- .container --> </div><!-- .mega-menu--> </li><!-- .droppable --> <li class='nav-row-list droppable'> <a class="white" href='/catalog/list/'>CSS <img src="icon/icon.webp" alt="phone" width="10" height="10"/></a> <div class='mega-menu'> <div class="container cf"> <ul class="ul-reset"> <h3>CSS Grid</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> <ul class="ul-reset"> <h3>Lawnmower Spares</h3> <li><a href='/catalog/list/'>Category Two Sublink</a><span class="#99cc00"></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> <ul class="ul-reset"> <h3>Strimmer Spares</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> <ul class="ul-reset"> <h3>New Machines</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> </div><!-- .container --> </div><!-- .mega-menu--> </li><!-- .droppable --> <li class='nav-row-list droppable'> <a class="white" href='/catalog/list/'>Shopify <img src="icon/icon.webp" alt="phone" width="10" height="10"/></a> <div class='mega-menu'> <div class="container cf"> <ul class="ul-reset"> <h3>Converting</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> <ul class="ul-reset"> <h3>Lawnmower Spares</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> <ul class="ul-reset"> <h3>Strimmer Spares</h3> <li><a href='/catalog/list/'>Category Two Sublink</a> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> <ul class="ul-reset"> <h3>New Machines</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> </div><!-- .container --> </div><!-- .mega-menu--> <</li><!-- .droppable --> <li class='nav-row-list droppable'> <a class="white" href='/catalog/list/'>Django <img src="icon/icon.webp" alt="phone" width="10" height="10"/></a> <div class='mega-menu'> <div class="container cf"> <ul class="ul-reset"> <h3>Pressure Washer Spares</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a><</li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> <ul class="ul-reset"> <h3>Lawnmower Spares</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> <ul class="ul-reset"> <h3>Strimmer Spares</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> <ul class="ul-reset"> <h3>New Machines</h3> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> <li><a href='/catalog/list/'>Category Two Sublink</a></li> </ul><!-- .ul-reset --> </div><!-- .container --> </div><!-- .mega-menu--> </li> <!-- .droppable --> </ul> </nav> </div> </label> </li> </ul> </nav> </div> <section id="hero1" class="hero"> <div class="inner"> <div class="copy"> <h1>Websites Are Supposed to - <br> <span class="gold">Generate Leads & Drive Sales!</span></h1> <p class="text-white">So... Why Do So Many Websites Fail to Do Either?</p> <a href="post/web-design-industry-whole-mess/" class="button center">Read More</a> </div> </section> <section class="section intro-grey"> <div class="row"> <div class="column"> <a href="post/web-design-industry-whole-mess/" class="center"> <img src="cart/1.png" loading="lazy" alt="phone" width="30" height="30"/> <p class="center">HTML5</p> </a> </div> <div class="column"> <a href="post/web-design-industry-whole-mess/" class="center"> <img src="cart/2.png" loading="lazy" alt="phone" width="30" height="30"/> <p class="center">CSSGrid</p> </a> </div> <div class="column"> <a href="post/web-design-industry-whole-mess/" class="center"> <img src="cart/3.png" loading="lazy" alt="phone" width="30" height="30"/> <p class="center">Python</p> </a> </div> <div class="column"> <a href="post/web-design-industry-whole-mess/" class="center"> phone

Django</p> </a> </div> <div class="column"> <a href="post/web-design-industry-whole-mess/" class="center"> <img src="cart/5.png" loading="lazy" alt="phone" width="30" height="30"/>

Shopify

</div> <div class="column"> <a href="post/web-design-industry-whole-mess/" class="center"> <img src="cart/6.png" loading="lazy" alt="phone" width="30" height="30"/> <p class="center">Platforms</p> </a> </div> <div class="column"> <a href="post/web-design-industry-whole-mess/" class="center"> <img src="cart/7.png" loading="lazy" alt="phone" width="30" height="30"/> <p class="center">PageSpeed</p> </div> <div class="column"> <a href="post/web-design-industry-whole-mess/" class="center"> <img src="cart/8.png" loading="lazy" alt="phone" width="30" height="30"/> <p class="center">Laptops</p> </a> </div> <div class="column"> <a href="post/web-design-industry-whole-mess/" class="center"> <img src="cart/10.png" loading="lazy" alt="phone" width="30" height="30"/> <p class="center">Shopify</p> </a> </div> </div> </section> <section class="valueProps"> <div class="grid-3-1"> <div class="grid-3-item background1"> <div class="grid-3-img quality" data-aos="zoom-in"> </div> <h3 class="white">AutoAnything said they saw a 12-13% increase in sales after cutting page load time in half. </h3> <hr style="width:50%; margin: auto;" /> <br> </div> <div class="grid-3-item background2"> <div class="grid-3-img quality" data-aos="zoom-in"> </div> <h3 class="white">Walmart said when they improved page load time by one second increased conversions by 2%.</h3> <br> <hr style="width:50%; margin: auto;" /> <br> </div> <div class="grid-3-item background3"> <div class="grid-3-img quality" data-aos="zoom-in"> </div> <h3 class="white">Amazon showed they would lose $1.6 BILLION a year for every one second slow down.</h3> <br> <hr style="width:50%; margin: auto;" /> <br> </div> </div> </section> <div class="title-wrapper"> <h3>Deals of The Day</h3> <hr> </div> </html>

So we will remove all comments and import some code from our settings.

from django.conf import settings

Since we have images I’m going to import the static folder we created.

from django.conf.urls.static import static

I’ll leave the admin that is already here

from django.contrib import admin

And I’ll and include with our path so we can send people to our apps.

from django.urls import path, include

I’ll leave the urlpatterns alone for now.

urlpatterns = [
                                      path('admin/', admin.site.urls),
                                      ]
        

We don't need to run staticfiles when we're running a development server and DEBUG is set to True. Static and media files can be then served directly so we are adding a couple lines to our main urls.py: to do that so under our url patterns we will add …

if settings.DEBUG: urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

And since we moved our settings.py into a settings folder and changed the name to dev, and pro we need to let Django know about this change and the way we go about doing that is by going onto the manage.py and adding .dev to the end of the cartturbo.settings.

When we go into production we will need to change that to pro.

def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cartturbo.settings.dev')

Custom User Model

When you want people to interact with your website, rather it be to leave comments, make a purchase, or join a group, you need a way for them to register.

Now Django comes with a built-in model for handling this but its very limited in what you can do, so we are going to build our own. My biggest problem with Django's user model, is that it logins with the user name instead of the email.

I think the login being the email is better because often times you can't have the username you want, so you end up with different usernames, which you can easily forget. And another advantage is if I forget my password I click "reset password" and since my login is my password, I do not need to enter anything else.

We are going to create our first app, an app is nothing more than a chunk of code we are going to be plugging into our website. However, I want to keep all my apps together in an easy to find place, I don’t want to get confused with which folders are apps and which are something else, so I’m going to put all my apps in the folder I created earlier called apps.

Go to your terminal and cd into your apps folder.

$ cd apps

Create a new app and call it profiles.

$ django-admin startapp profiles

Adding Profiles to Settings

Now I’m going to go back to my base to add in the app but I want to break up my apps a bit so I can better understand what apps are what.

So I’ll break them into three categories. Django Default apps, Third Party Apps, and My Apps.

I’ll open up base.py and break the INSTALLED_APPS into three sections DEFAULT_APPS, THIRD_PARTY_APPS and LOCAL_APPS.

        DEFAULT_APPS = [
            'django.contrib.admin',
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'django.contrib.sessions',
            'django.contrib.messages',
            'django.contrib.staticfiles',
        ]

        THIRD_PARTY_APPS = [
            
        ]


        LOCAL_APPS = [
            'apps.profiles',
        ]
      

And at the bottom I’ll tell it that the INSTALLED_APPS is equal to the DEFAULT_APPS plus the LOCAL_APPS plus the THIRD_PARTY_APPS.

        INSTALLED_APPS = DEFAULT_APPS + LOCAL_APPS + THIRD_PARTY_APPS
      

Setting Up Profiles Models

Django by default has a very simple user model. Which only includes a few fields, user name, first name, last name, email, and password. So we are going to get rid of the original Django user model and build our on.

There are a couple things we are going to add, instead of having the default user name for the login we are going to use email as the main login but still require a unique user name.

The unique user name will then be used for making comments, ratings, and reviews.

Now I’ll go to models and start importing a couple things.

I’m going to use timezone so I can keep up with and even order by when someone has registered.

        from django.utils import timezone
      

And second we are using get text lazy, for translating our text into different languages.

        from django.utils.translation import gettext_lazy as _
      

According to this document we have to tell Django which text we want translated and into what languages.

https://docs.djangoproject.com/en/3.1/topics/i18n/translation/

We are going to use the underscore to identify gettext_lazy, that way I do not have to type out the name but can just use the underscore instead.

Now we are going to use the default permission mixin by typing ...

        from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin,
      

Now lets add the class using the two models we just imported.

        class User(AbstractBaseUser, PermissionsMixin):
      

We are going to login with email

        email       = models.EmailField(_('email address'), unique=True)
      

You’ve also got have a user name for comments and such.

        username   = models.CharField(max_length=150, unique=True)
      

Then we’ve got the date they joined.

        start_date  = models.DateTimeField(default=timezone.now)
      

And an optional form for a little about text.

        about       = models.TextField(_(
                'about'), max_length=500, blank=True)
      

An option to make them part of the staff.

        is_staff    = models.BooleanField(default=False)
      

And then we can repeat it for is activate.

        is_active   = models.BooleanField(default=False)
      

We need to connect with our base model, that we are going to create next.

        objects = CustomManager()
      

We need to identify the user name field. The default user name field is username and we want to change that to email. You need to use the username field to do that.

        USERNAME_FIELD = 'email'
      

Next is the required fields. These are the things that will be asked for when a user tries to create a new superuser.

In the required field I want to add user because they need a user name for making comments.

         REQUIRED_FIELDS = ['username', ] 
      

And then we will tell it to return the user name.

         def __str__(self):
        return self.username 
      

BaseUserManager

We need to import the BaseUserManager and extend it.

We are going to do this by adding the BaseUserManager after the PermissionsMixin model.

from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager

Also add it into our class ...

class CustomManager(BaseUserManager):

We are going to need two functions create_superuser

def create_superuser():

and create_user

def create_user():

First this is what the super user is going to have to complete to register. And we can also add other fields.

def create_superuser(self, email, username, password, **other_fields):

An Example of other fields would be ...

def create_superuser(self, email, username, password, **other_fields):
        other_fields.setdefault('is_staff', True)
        other_fields.setdefault('is_superuser', True)
        other_fields.setdefault('is_active', True)

The normal user is going to be set to False, because they will first need to get an email and click on that and then that activates the user.

However we want to create some checks.

if other_fields.get('is_staff') is not True:

We want to make sure that the staff has been set.

raise ValueError(

Or you will get a value error. And then we right another for our SuperUser.

'Superuser must be assigned to is_staff=True.')
        if other_fields.get('is_superuser') is not True:
            raise ValueError(
                'Superuser must be assigned to is_superuser=True.')

And then we will just return everything we are passing in at the top.

return self.create_user(email, username, password, **other_fields)

Create User

Now with the create user ….

First we add in the fields they need to complete.

def create_user(self, email, username, password):

That is what the user is going to have to complete to register. And we can also add other fields

def create_user(self, email, username, password, **other_fields):

then we will tell it what to do after it creates the new user.

We are going to return the user.

return user

Then we are going to set up the email.

def create_user(self, email, username, password, **other_fields):
          email = self.normalize_email(email)
          return user
          def create_user(self, email, username, password, **other_fields):
        

Next we will add in the users details.

          def create_user(self, email, username, password, **other_fields):
          email = self.normalize_email(email)
          user = self.model(email=email, username=username,
                          **other_fields)
          return user
        

Next we will set the password

          def create_user(self, email, username, password, **other_fields):
          email = self.normalize_email(email)
          user = self.model(email=email, username=username,
                           **other_fields)
          user.set_password(password)
            return user
        

The we are going to save all that.

        def create_user(self, email, username, password, **other_fields):

        email = self.normalize_email(email)
        user = self.model(email=email, username=username,
                          first_name=first_name, **other_fields)
        user.set_password(password)
        user.save()
        return user

Now we want to validate the email so …

def create_user(self, email, username, first_name, password, **other_fields):

You can see we are using the gettext_lazy

if not email:
            raise ValueError(_('You must provide an email address'))

And then it says you must provide an email address, you can make it say anything you want.

email = self.normalize_email(email)
        user = self.model(email=email, username=username,
                          first_name=first_name, **other_fields)
        user.set_password(password)
        user.save()
        return user

Now we need to go into base.py and tell Django that we are using a new user model. First is the app and second is the model.


AUTH_USER_MODEL

Now we need to go into base.py and tell Django that we are using a new user model. First is the app and second is the model.

AUTH_USER_MODEL = 'profiles.User'

Profiles the name of our app and User the name of our model.

Now I’m going to prepare our database for the new user model, by going back to my terminal and typing in python3 manage.py makemigrations profiles.

$ python3 manage.py makemigrations profiles

Now I’ll create the database by typing in python3 manage.py migrate profiles.

$ python3 manage.py migrate profiles

And I’ll migrate everything by typing in python3 manage.py migrate.

$ python3 manage.py migrate 

And then I’ll create a super user by typing in python3 manage.py create super user.

$ python3 manage.py createsuperuser

 

$ python3 manage.py makemigrations profiles

And then you just follow the prompts and add in a user name

CartTurbo

And a password and the password should be a quote, remove all the spaces and change out any letters you can with characters like s becomes $ t can become 7 and so on.

1\/\/1ll|_|77er|)4rk$4y1ing$Fr(

After that we can run the server and take a look at what we have so far.

$ python3.8 manage.py runserver

If we go into the admin we can not see our new users so we want to add those now.

Now we are going to go into admin.py and add …

          from django.contrib import admin
          from .models import User
          from django.contrib.auth.admin import UserAdmin
          admin.site.register(User)
        

User in Admin

Now if you refresh you can see the User in the admin. Now if we click on user we can see that we have one user. And there is very little information given. If we click on the user we can see everything but its a bit confusing, so lets see if we can clean this up a little.

We are going to start by adding in a new class.

          from django.contrib import admin
          from .models import User
          from django.contrib.auth.admin import UserAdmin
          class UserAdminConfig(UserAdmin):
            pass
        

And then we need to tie the two together with UserAdminConfig

admin.site.register(User, UserAdminConfig)

Now we are going to start defining how we want to order the different users and listing what we want to display.

          from django.contrib import admin
          from .models import User
          from django.contrib.auth.admin import UserAdmin
          from django.forms import TextInput, Textarea
          class UserAdminConfig(UserAdmin):
              ordering = ('-start_date',)
              list_display = ('email', 'username',
                              'is_active', 'is_staff')
          admin.site.register(User, UserAdminConfig)
        

Now if we go back to our page and refresh you can see we’ve defined what we want to see.

We can change from displaying from ascending order ordering = ('start_date',) to descending ordering by adding a negative sign ordering = ('-start_date',) in front of start.

We also want to add in some kind of search

          from django.contrib import admin
          from .models import User
          from django.contrib.auth.admin import UserAdmin
          from django.forms import TextInput, Textarea
          class UserAdminConfig(UserAdmin):
              model = User
              search_fields = ('email', 'username',)
        

We can now search based on those fields. And we can add some more filters to filter by over in the right hand column by adding.

              list_filter = ('email', 'username', 'is_active', 'is_staff')
              ordering = ('-start_date',)
              list_display = ('email', 'username',
                              'is_active', 'is_staff')
        

And we also want to add in the field sets. Here we have three sections

fieldsets = (

The top section

(None, {'fields': ('email', 'username',)}),

Then we have permissions

('Permissions', {'fields': ('is_staff', 'is_active')}),

And then personal

           ('Personal', {'fields': ('about',)}),
    )
        

Now if we go back and refresh you will see that we have three different areas. And we can even affect the styling with form field overrides.

          formfield_overrides = {
          User.about: {'widget': Textarea(attrs={'rows': 10, 'cols': 40})},
      }
        

And then we are going to define the fields when we add a new user

              add_fieldsets = (
              (None, {
                  'classes': ('wide',),
                  'fields': ('email', 'username', 'password1', 'password2', 'is_active', 'is_staff')}
               ),
          )
        

Those are the fields that we are going to define and that we want activate when we create a new user.

If you refresh you can see that everything is in the place and order that we have defined.


User in Admin

Now if you refresh you can see the User in the admin. Now if we click on user we can see that we have one user. And there is very little information given. If we click on the user we can see everything but its a bit confusing, so lets see if we can clean this up a little.

We are going to start by adding in a new class.

          from django.contrib import admin
          from .models import User
          from django.contrib.auth.admin import UserAdmin
          class UserAdminConfig(UserAdmin):
            pass
        

And then we need to tie the two together with UserAdminConfig

admin.site.register(User, UserAdminConfig)

Now we are going to start defining how we want to order the different users and listing what we want to display.

          from django.contrib import admin
          from .models import User
          from django.contrib.auth.admin import UserAdmin
          from django.forms import TextInput, Textarea
          class UserAdminConfig(UserAdmin):
              ordering = ('-start_date',)
              list_display = ('email', 'username',
                              'is_active', 'is_staff')
          admin.site.register(User, UserAdminConfig)
        

Now if we go back to our page and refresh you can see we’ve defined what we want to see.

We can change from displaying from ascending order ordering = ('start_date',) to descending ordering by adding a negative sign ordering = ('-start_date',) in front of start.

We also want to add in some kind of search

          from django.contrib import admin
          from .models import User
          from django.contrib.auth.admin import UserAdmin
          from django.forms import TextInput, Textarea
          class UserAdminConfig(UserAdmin):
              model = User
              search_fields = ('email', 'username',)
        

We can now search based on those fields. And we can add some more filters to filter by over in the right hand column by adding.

              list_filter = ('email', 'username', 'is_active', 'is_staff')
              ordering = ('-start_date',)
              list_display = ('email', 'username',
                              'is_active', 'is_staff')
        

And we also want to add in the field sets. Here we have three sections

fieldsets = (

The top section

(None, {'fields': ('email', 'username',)}),

Then we have permissions

('Permissions', {'fields': ('is_staff', 'is_active')}),

And then personal

           ('Personal', {'fields': ('about',)}),
    )
        

Now if we go back and refresh you will see that we have three different areas. And we can even affect the styling with form field overrides.

          formfield_overrides = {
          User.about: {'widget': Textarea(attrs={'rows': 10, 'cols': 40})},
      }
        

And then we are going to define the fields when we add a new user

              add_fieldsets = (
              (None, {
                  'classes': ('wide',),
                  'fields': ('email', 'username', 'password1', 'password2', 'is_active', 'is_staff')}
               ),
          )
        

Those are the fields that we are going to define and that we want activate when we create a new user.

If you refresh you can see that everything is in the place and order that we have defined.


Adding User To Admin

Now if you refresh you can see the User in the admin. Now if we click on user we can see that we have one user. And there is very little information given. If we click on the user we can see everything but its a bit confusing, so lets see if we can clean this up a little.

We are going to start by adding in a new class.

          from django.contrib import admin
          from .models import User
          from django.contrib.auth.admin import UserAdmin
          class UserAdminConfig(UserAdmin):
            pass
        

And then we need to tie the two together with UserAdminConfig

admin.site.register(User, UserAdminConfig)

Now we are going to start defining how we want to order the different users and listing what we want to display.

          from django.contrib import admin
          from .models import User
          from django.contrib.auth.admin import UserAdmin
          from django.forms import TextInput, Textarea
          class UserAdminConfig(UserAdmin):
              ordering = ('-start_date',)
              list_display = ('email', 'username',
                              'is_active', 'is_staff')
          admin.site.register(User, UserAdminConfig)
        

Now if we go back to our page and refresh you can see we’ve defined what we want to see.

We can change from displaying from ascending order ordering = ('start_date',) to descending ordering by adding a negative sign ordering = ('-start_date',) in front of start.

We also want to add in some kind of search

          from django.contrib import admin
          from .models import User
          from django.contrib.auth.admin import UserAdmin
          from django.forms import TextInput, Textarea
          class UserAdminConfig(UserAdmin):
              model = User
              search_fields = ('email', 'username',)
        

We can now search based on those fields. And we can add some more filters to filter by over in the right hand column by adding.

              list_filter = ('email', 'username', 'is_active', 'is_staff')
              ordering = ('-start_date',)
              list_display = ('email', 'username',
                              'is_active', 'is_staff')
        

And we also want to add in the field sets. Here we have three sections

fieldsets = (

The top section

(None, {'fields': ('email', 'username',)}),

Then we have permissions

('Permissions', {'fields': ('is_staff', 'is_active')}),

And then personal

           ('Personal', {'fields': ('about',)}),
    )
        

Now if we go back and refresh you will see that we have three different areas. And we can even affect the styling with form field overrides.

          formfield_overrides = {
          User.about: {'widget': Textarea(attrs={'rows': 10, 'cols': 40})},
      }
        

And then we are going to define the fields when we add a new user

              add_fieldsets = (
              (None, {
                  'classes': ('wide',),
                  'fields': ('email', 'username', 'password1', 'password2', 'is_active', 'is_staff')}
               ),
          )
        

Those are the fields that we are going to define and that we want activate when we create a new user.

If you refresh you can see that everything is in the place and order that we have defined.


Summary

You've reached the end of the article — we hope you enjoyed your tour of the very basics of HTML! At this point you should understand what the language looks like, how it works at a basic level, and be able to write a few elements and attributes. This is a perfect place to be right now, as in subsequent articles in the module we will go into some of the things you have already looked at in a lot more detail, and introduce some new features of the language. Stay tuned!


Source

All documentation on this page was sourced from Getting started with HTML by Mozilla Contributors, which is licensed under CC BY-SA 2.5.

We are looking for one client per area to dominate the rankings and social media!

Learn More