Mobile ready demo - tonytienvuong/Project-1-Bay-Kicks GitHub Wiki
The brief asks for the site to work on both large and small screens, with the navigation changing from a row to a stack, and for an explanation of how Bootstrap makes that happen.
The home page. The navigation links sit in a row on the right.

The shop page. Three product cards per row.

A product page. The photo is on the left and the details are on the right.

The home page. The navigation links are gone, replaced by a hamburger button.

The shop page. One card per row, with the details stacked under the photo.

The hamburger clicked open. The links stack vertically above the content.

- The navigation goes from a row of links on the right to a hamburger button. Clicking it opens the links in a vertical stack.
- The product grid goes from three cards per row, to two, and then to one.
- The product page goes from a photo on the left with the details on the right, to the photo on top with the details underneath.
My agent measured the live site at nine widths, from 1440 pixels down to 320.
- 1440 pixels — three cards per row, no hamburger
- 1200 pixels — three cards per row, no hamburger
- 992 pixels — three cards per row, no hamburger
- 991 pixels — two cards per row, hamburger appears
- 768 pixels — two cards per row, hamburger
- 576 pixels — two cards per row, hamburger
- 575 pixels — one card per row, hamburger
- 390 pixels — one card per row, hamburger
- 320 pixels — one card per row, hamburger
At every one of those widths the page has no horizontal scrolling, which means nothing spills off the side of the screen on a phone.
The switch from a row to a hamburger happens at 992 pixels. That is Bootstrap's lg
breakpoint, and it is not a number I picked. It comes from the class described below.
It comes down to one class on the navigation bar:
<nav className="navbar navbar-expand-lg bk-navbar sticky-top">navbar-expand-lg is the instruction. It means keep the links in a row as long as the
screen is at least lg wide, and collapse them below that.
The hamburger button is Bootstrap's navbar-toggler:
<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#bkMainNav"
>
<span className="navbar-toggler-icon"></span>
</button>The two data-bs- attributes are what make it work with no JavaScript of my own.
data-bs-toggle="collapse" says this button opens and closes something, and
data-bs-target="#bkMainNav" says which element, by its id.
That element is the list of links:
<div className="collapse navbar-collapse" id="bkMainNav">
<ul className="navbar-nav ms-auto">collapse navbar-collapse is the part that hides and shows. Inside it, navbar-nav lays
the links out, and it becomes a vertical stack once the bar has collapsed.
The JavaScript behind all of this comes from bootstrap.bundle.min.js, imported once in
src/main.jsx. It is a real dependency in package.json, not a link to a website.
ProductList.jsx puts Bootstrap's column classes on each card.
<div className="col-12 col-sm-6 col-lg-4" key={product.id}>Read left to right, that one line says three things:
-
col-12takes all 12 columns, so one card per row. This is the default, for phones. -
col-sm-6takes half the row, so two cards per row, from thesmbreakpoint. -
col-lg-4takes a third of the row, so three cards per row, fromlg.
That is the whole three, two, one behaviour described above.
The product page does the same thing with two columns.
<div className="col-12 col-lg-6"> {/* the photo */}
<div className="col-12 col-lg-6"> {/* the details */}Each takes the full width when they are stacked, and they sit side by side from lg
upwards.
Other Bootstrap classes in use:
-
containercentres the content and adds space at the sides. -
g-4sets the gap between cards in a row. -
ms-autopushes the navigation links to the right on wide screens. -
sticky-topkeeps the bar at the top while scrolling. -
text-centercentres text,mb-3andmt-3add space, andw-100makes a button full width. -
form-label,form-controlandform-selectstyle the form fields.
Two small additions in src/App.css, because Bootstrap's defaults needed adjusting on
small screens:
@media (max-width: 991.98px) {
.bk-navbar .navbar-nav { padding: 0.75rem 0; }
.bk-hero { padding: 2.5rem 0 2rem; }
.bk-hero h1 { font-size: 1.875rem; }
}
@media (max-width: 575.98px) {
.bk-hero h1 { font-size: 1.625rem; }
}The first gives the stacked links some breathing room and shrinks the heading on the home page. The second shrinks that heading a little more on a phone.
The breakpoint numbers match Bootstrap's own, which is why the custom rules change at exactly the same moment as the grid.
The cart's quantity row and the page number buttons wrap onto a second line rather than overflowing, and that is why the page never scrolls sideways on a narrow screen.
I expected the navigation to be difficult, and it was not. It was one extra class on the
nav element and two attributes on the button, and Bootstrap handled the rest.