Combining Flexbox and Grid
In this assignment, you will build a photography portfolio that strategically combines CSS Grid and Flexbox to create a professional, responsive layout. Grid handles the overall page structure and content distribution, while Flexbox manages component-level arrangements and the sticky footer pattern. This project demonstrates when to use each layout system and how they work together.
You will implement named grid areas for semantic page structure, use auto-fit and auto-fill for responsive galleries, create a sticky footer with Flexbox, and combine both systems within the same page. The result is a production-quality portfolio that adapts gracefully to different screen sizes without excessive media queries.
The Strategic Choice
Every layout system excels at specific tasks. Grid provides powerful two-dimensional control, making it ideal for page-level structure, card grids, and content areas that need both row and column control. Flexbox offers superior one-dimensional flow control, perfect for navigation bars, footer arrangements, and the sticky footer pattern that requires flexible vertical spacing.
Modern layouts rarely use just one system. Professional developers combine Grid and Flexbox, choosing each where it provides the clearest, most maintainable solution. A Grid container can have Flexbox children, and Flexbox containers can contain Grid elements. This assignment teaches you to recognize these opportunities and implement hybrid layouts confidently.
Setup Instructions
1. Download and Extract Starter Files
Download the starter files and extract them. The download contains complete HTML structure, finished base styles, component styles, and a layout CSS file with detailed TODO comments guiding your implementation.
The starter files include:
flex-grid-starter/
├── css/
│ ├── base/
│ │ ├── reset.css
│ │ ├── variables.css
│ │ └── typography.css
│ ├── components/
│ │ ├── buttons.css
│ │ └── cards.css
│ ├── layout/
│ │ └── portfolio.css
│ └── main.css
├── index.html
└── README.md
2. Add to Your Portfolio
Copy the starter files into your portfolio repository following this structure:
portfolio/
└── unit-3/
└── flexbox-grid-practice/
├── css/
│ ├── base/
│ ├── components/
│ ├── layout/
│ │ └── portfolio.css
│ └── main.css
├── index.html
└── README.md
3. Review the Files
Open index.html in your browser to see the unstyled structure. Examine css/layout/portfolio.css to understand the TODO comments. Read through README.md for implementation tips and common pitfalls. The base styles and components are complete; you will work exclusively in the layout file.
Implementation Requirements
1. Sticky Footer Pattern with Flexbox
Implement the classic sticky footer pattern that keeps the footer at the bottom of the viewport even when page content is short. This requires making the body a flex container with column direction, setting minimum height to the full viewport, and making the main content area grow to fill available space.
The pattern uses three key properties: display: flex and flex-direction: column on the body establish vertical stacking, min-height: 100vh ensures the body spans the full viewport height, and flex: 1 on the main content area makes it grow to push the footer down. The footer should not grow or shrink.
Test the sticky footer by temporarily removing content sections from the HTML. Even with minimal content, the footer should remain at the bottom of the viewport, not floating in the middle of the page.
2. Header Layout with Grid Template Areas
Use grid-template-areas to create a semantic header layout with named regions for the logo and navigation. On desktop, these areas sit side by side. The grid template should define two columns, with the logo area taking the first column and the navigation area taking the second.
Assign grid areas to elements using the grid-area property. The logo element receives grid-area: logo, and the navigation element receives grid-area: nav. This creates self-documenting CSS where the layout structure is immediately clear from the template definition.
3. Navigation Bar with Flexbox
The navigation list inside the header should use Flexbox to arrange links horizontally with appropriate spacing. Apply display: flex to the unordered list, use the gap property to space items evenly, and ensure vertical alignment with align-items.
Flexbox handles this one-dimensional layout more cleanly than Grid would. The links need to flow horizontally and wrap if necessary, which is exactly what Flexbox was designed for.
4. Hero Section with Grid Centering
The hero section needs content centered both vertically and horizontally within a defined minimum height. Use CSS Grid with place-items: center to achieve both axes of alignment simultaneously. This single property replaces separate alignment declarations and works perfectly for centered hero content.
5. Stats Grid with Auto-Fit
Implement a responsive stats grid using repeat(auto-fit, minmax(...)) that creates three columns on desktop, two on tablet, and one on mobile without any media queries. The key is choosing appropriate minimum and maximum values in minmax().
Use minmax(min(250px, 100%), 1fr) as your column definition. The min(250px, 100%) prevents columns from exceeding container width on small screens, which would cause horizontal overflow. The 1fr maximum allows columns to expand when space permits. The auto-fit keyword collapses empty tracks, so if you have three stat cards, they expand to fill the available width rather than leaving empty space.
A common mistake is using minmax(250px, 1fr) without the min() wrapper. On a 320px mobile device, this creates columns that are 250px wide, forcing horizontal scroll. Always wrap your minimum value in min() when using auto-fit or auto-fill.
6. Photo Gallery: Auto-Fill vs Auto-Fit Decision
The photo gallery is where you experiment with the critical difference between auto-fill and auto-fit. Both create as many columns as will fit in the container, but they handle leftover space differently. This section requires you to implement one approach, test it with different numbers of photos, and document why you chose it.
With auto-fill, empty tracks remain in the layout even when no photos occupy them. If your container can hold five columns but you only have three photos, auto-fill creates five columns and leaves two empty. The three photos maintain their minimum width (around 300px) with empty space to the right.
With auto-fit, those empty tracks collapse to zero width. The three photos expand beyond their minimum to fill the entire container width. Each photo grows proportionally according to the 1fr maximum you specified in minmax().
For a photography portfolio, consider which behavior creates better visual balance. Do you want photos to maintain consistent width regardless of how many exist, or should they expand to fill available space? There is no single correct answer; your choice depends on the visual effect you want to achieve. Document your decision in the assignment form.
7. About Section: Grid for Layout, Flexbox for Content
The about section demonstrates hybrid layouts. Use Grid to position the image and text content side by side on desktop (or stacked on mobile). Within the text content area, use Flexbox with flex-direction: column to arrange the heading, paragraphs, and call-to-action button with appropriate vertical spacing.
Grid excels at the two-dimensional layout of image and text because you need to control both horizontal positioning and ensure elements align properly. Flexbox handles the simpler task of stacking content vertically within the text area. Combining both creates clean, maintainable CSS where each tool does what it does best.
8. Footer Layout with Flexbox
The footer contains copyright information on the left and social links on the right. Use Flexbox with justify-content: space-between to push these elements to opposite edges. The social links themselves should also use Flexbox to arrange multiple links horizontally with the gap property providing spacing.
This demonstrates nested Flexbox containers: the footer container uses Flexbox to distribute major sections, and the social links container uses Flexbox to arrange individual links. Each Flexbox context is independent, making the code easy to understand and modify.
Responsive Considerations
The auto-fit and auto-fill grids handle most responsive behavior automatically, adapting column counts based on available space. However, you will need media queries for specific layout changes that cannot be handled by automatic grid behavior.
The header layout requires a breakpoint to stack the logo and navigation vertically on mobile devices. Change the grid-template-areas from a two-column layout to a single-column layout, and adjust the grid-template-columns accordingly. This typically occurs around 768px viewport width.
The about section needs similar treatment. On desktop, the image and text sit side by side. On mobile, they stack vertically. You can handle this by changing from a two-column grid to a single-column grid at the appropriate breakpoint, or by using grid-auto-flow with responsive column definitions.
Testing Your Implementation
Thorough testing ensures your layout works across different scenarios and viewport sizes. Start by testing the sticky footer: temporarily remove content sections to create a short page. The footer should remain at the bottom of the viewport, not floating in the middle. Add content back to verify the footer moves down naturally when content exceeds viewport height.
Test the photo gallery by adding and removing photo cards from the HTML. With auto-fill, notice how empty space remains when you have fewer photos. With auto-fit, observe how remaining photos expand to fill that space. Try the gallery with 3 photos, 5 photos, 8 photos, and 12 photos to see how each approach responds.
Resize your browser window to test responsive behavior. At desktop widths (1400px and above), verify that the stats grid shows three columns, the photo gallery shows multiple columns, and the about section displays image and text side by side. At tablet widths (768px to 1024px), check that grids reduce to appropriate column counts. At mobile widths (375px to 768px), confirm that all grids stack to single columns and the header navigation stacks vertically.
Modern browser developer tools include Grid inspection features. In Chrome or Firefox DevTools, select a grid container to see an overlay showing grid lines, track sizes, and gap spacing. This visualization helps you verify that your grid definitions produce the expected layout structure.
Common Challenges and Solutions
Several common issues appear frequently when combining Grid and Flexbox. Understanding these ahead of time saves debugging frustration and helps you write better CSS from the start.
The sticky footer pattern fails if you forget to set min-height: 100vh on the body. Without this, the body only grows to contain its content, and the flex layout cannot push the footer down. Similarly, if the main content area does not have flex: 1 or flex-grow: 1, it will not expand to fill available vertical space.
Grid template areas require exact string matching between the template definition and element assignments. A typo like grid-area: navi when the template defines nav causes that element to not participate in the named grid at all. It falls back to auto-placement, appearing in unexpected locations.
When using auto-fit or auto-fill with minmax(), forgetting the min() wrapper around your minimum value causes horizontal overflow on mobile devices. If your minimum column width is 300px and a mobile screen is 320px wide, the grid creates columns that exceed the container, forcing horizontal scroll.
Flexbox gap property and margins can conflict. If you use gap on the flex container, do not add margins to flex items for spacing. The gap property provides cleaner, more maintainable spacing. Adding margins creates double spacing and makes calculations unpredictable.
Assignment Submission
Complete the form below to document your implementation decisions and portfolio link. When finished, download the PDF and submit it to Canvas along with your portfolio repository link.
Provide the link to your completed portfolio page:
Explain which keyword you chose for the photo gallery (auto-fill or auto-fit) and why. What visual behavior did you want to achieve? How does your choice affect the layout when you have 3 photos versus 8 photos?
Describe one specific place where you chose Grid over Flexbox (or vice versa) and explain why. What made that layout system the better choice for that particular component?
What was the most challenging part of this assignment? How did you solve it? This could be technical (sticky footer, responsive behavior) or conceptual (deciding between layout systems).
Looking Ahead
This assignment establishes the foundation for more advanced Grid techniques you will explore in upcoming work. You have combined two powerful layout systems and learned to recognize which tool serves each situation best. The auto-fit and auto-fill patterns you implemented here create responsive layouts without brittle media query stacks, and the named grid areas provide semantic, self-documenting structure.
Future assignments will introduce subgrid for aligning nested grids with parent tracks, and complex grid-area patterns for sophisticated magazine and dashboard layouts. The strategic thinking you developed here about when to use Grid versus Flexbox continues to apply as layouts become more complex.