# Lab02: Wordle Layout with `CSS` and `Flexbox` :::danger 📅 **Due:** Thursday, September 11th by 11:59pm **Points:** 4 ::: **Learning Flexbox Through Experimentation** :::info ## What You'll Learn Today By the end of this lab, you'll understand: - How `display: flex` transforms layouts instantly - The difference between horizontal and vertical centering - Why `gap` is better than `margin` for spacing - How to center content on a webpage ::: ## **Time Estimate Breakdown:** :::info - **Setup & Understanding:** 15-20 minutes - **Adding HTML rows:** 5 minutes - **8 CSS Experiments:** 60-90 minutes (most time here) - **Colors & Polish:** 15-20 minutes - **Screenshots & Submission:** 10 minutes **Total: 2-2.5 hours** for most students. ::: ## Part 1: Assignment Setup :::danger The GitHub Classroom link has been providing out of date code. Please use this repository instead: https://github.com/merriekay/lab02-wordle-layout ::: :::danger 1. To get started, click on the ~~[GitHub Classroom](https://classroom.github.com/a/5JSw2Oh2)~~ link and accept the assignment. 2. This step will work, but the code is behind a few commits. I'm working on this. For now, use the `index.html` and `styles.css` from this repository: https://github.com/merriekay/lab02-wordle-layout ::: ![Accept the assignment screenshot GitHub Classroom](https://hackmd.io/_uploads/BJQ10h35le.png) :::success 2. After accepting the assignment, you should see a link to an auto-generated repository: ::: !["You're ready to go!" successfully accepted assignment screenshot](https://hackmd.io/_uploads/Sy2nga35le.png) :::success 3. Click on that link, and it should take you to your :sparkles: shiny new repo :sparkles: ::: ![screenshot of lab02 auto-generated starter repo](https://hackmd.io/_uploads/H1PxZa39xe.png) :::success 4. Now, we need to `clone` this code to your local machine so that you can make edits. To do this, click on the green "`<> Code`" button, and copy the repo URL: ::: ![image](https://hackmd.io/_uploads/Hyb9Za2cxg.png) :::success 5. Open up Visual Studio code, and create a new folder called `Lab02`. ::: :::success 6. Open up a new terminal ("Terminal"--> "New Terminal"), and double check that there isn't already a `git` repository by typing: ::: ``` git status ``` Mine looks like this: ![image](https://hackmd.io/_uploads/Sk_WG63qgl.png) which means that I'm in the clear, and there's no pre-existing `git` repo. This a good sign (even though it might sound scary `fatal:`)! > However, if you get something that looks like this: > ![image](https://hackmd.io/_uploads/rJz8z63cxx.png) > Go ahead and create a folder somewhere else and try steps 5 and 6 again until you find a spot where there isn't already a git repo. :::success 7. Alright, now let's use that URL that we copied from our brand new git repo. In the terminal you opened, go ahead and enter the following: ```bash! git clone https://github.com/drake-full-stack/lab02-css-wordle-layout-yourUserName.git ``` > Note that your URL should include your actual username, not yourUserName ::: :::success 8. Now, if that was successful, let's double check that we're in the correct working directory... after cloning we usually need to `cd` into the correct working directory: ```bash! cd lab02-wordle-layout ``` ::: --- ## Part 2: Get Familiar with the Starter Code Before we start experimenting with CSS, let's see what we're working with. ### Step 1: Launch the Code :::success 1. Make sure you have the `index.html` file selected in VS Code 2. Click the **'Go Live'** button (if you have Live Server installed) or open the file in your browser 3. Prepare yourself for... well, let's just say it's not pretty yet! ::: Click on this image to unblur it and make sure that what you got looks similar to what I'm starting with. :::spoiler See screenshot below ![initial run showing what the starter code should look like--not well aligned](https://hackmd.io/_uploads/HJVhAATcle.png) :: ### Step 2: Understanding the Files :::warning We have two key files working together: - **`index.html`** - The skeleton/structure of our game (all the content) - **`style.css`** - The styling rules that make it look good (or in this case, not so good yet!) The browser reads both files and combines them to create what you see on screen. ::: ### Step 3: Compare to the Goal Your starter code probably looks quite broken right now. Here's what the real NYT Wordle grid looks like for comparison: ![real wordle interface with 'WORDS' in the first row](https://hackmd.io/_uploads/SJmfJ1C5ge.png) :::warning Take a moment to study what's different: - What specific problems can you spot with positioning, spacing, or alignment? - Write down 2-3 things you think need fixing (don't worry about HOW to fix them yet) ::: :::danger **📸 Screenshot:** Take a picture of your broken starter code and save it as `lastname_before.png` - you'll compare it to your final result later. ::: --- ## The Intentionally Broken Starting Point We're going to start with something that looks terrible on purpose. Your job is to fix it step by step and discover how each CSS property works. :::warning ### Understanding CSS Variables Notice the section at the top starting with `:root`? These are **CSS custom properties**, also called CSS variables. They're a powerful way to store values you want to reuse throughout your stylesheet. **How they work:** - **Declare variables** in `:root` using the `--` prefix: `--tile-size: 62px;` - **Use variables** anywhere with the `var()` function: `width: var(--tile-size);` **Why use them?** - **Consistency:** Change `--tile-size` once and it updates everywhere - **Maintainability:** Easy to update your design system - **Readability:** `var(--tile-size)` is clearer than just `62px` Look through the CSS above and find where variables are being used. You'll see `var(--border-color)`, `var(--background-color)`, etc. This means if you want to change the border color for the entire game, you only need to change it in one place! ::: :::warning ### Quick Review: CSS Selectors and Classes Before we start our experiments, let's review how CSS connects to HTML elements: **Element Selectors** target HTML tags directly: ```css body { background-color: #f6f7f8; } /* Styles ALL body elements */ h1 { font-size: 2.5rem; } /* Styles ALL h1 elements */ ``` **Class Selectors** target elements with specific class attributes: ```css .tile { width: 62px; } /* Styles elements with class="tile" */ .row { display: flex; } /* Styles elements with class="row" */ ``` **Multiple Classes** can be applied to one element: ```html <div class="tile correct">W</div> <!-- This div has BOTH classes --> ``` ```css .tile { width: 62px; } /* Base tile styling */ .tile.correct { background: green; } /* Additional styling for correct tiles */ ``` **Descendant Selectors** target elements inside other elements: ```css header h1 { text-align: center; } /* Only h1 elements inside header */ .game-board .row { margin-bottom: 8px; } /* Only .row elements inside .game-board */ ``` ::: **Look at your HTML and CSS:** Can you identify which styles will apply to which elements? For example, what styles will apply to `<div class="tile">W</div>`? --- ## Step 2: Add more rows in `index.html` :::success 1. Go ahead and copy the empty row so that we have 6 rows of 5 tiles each in our `HTML` document. 2. Find this section of code and complete the `TODO:` ```html! <!-- Row 2: Empty for now--> <div class="row"> <div class="tile"></div> <div class="tile"></div> <div class="tile"></div> <div class="tile"></div> <div class="tile"></div> </div> <!-- TODO: Add 4 more empty rows following the same pattern --> <!-- could be a fun Emmet abbreviation trial... --> ``` ::: :::warning Right now, these won't show up as rows... you'll see lots of grey boxes stacked vertically. We'll tackle this problem in **Experiment 1** :arrow_down: ::: --- ## 🧪 Experiment 1: Display Flex Right now your tiles are probably stacked in a weird vertical column. Let's fix the first row. :::info **🔮Prediction:** Before you add the next line of code, write down what you think `display: flex` will do to the `.row`. ::: ### Add the Code :::success Add this single line to your `.row` CSS: ```css .row { display: flex; /* Add this line */ margin-bottom: 8px; } ``` ::: Once you've added this line and checked to see what it does, double check it against mine by clicking on the image below: :::spoiler See screenshot below ![layout after adding display: flex](https://hackmd.io/_uploads/S1Bae1Rqee.png)::: :::warning ### Reflection - What happened to your tiles? - Was your prediction correct? - Describe the transformation in your own words. ::: --- ## 🧪 Experiment 2: Flex Direction Flexbox has a direction setting that controls how items are arranged. Let's experiment! :::info **🔮 Prediction:** What do you think `flex-direction: column` will do? Sketch your prediction if it helps. ::: ### Experiment Time :::success Temporarily add this to your `.row`: ```css .row { display: flex; flex-direction: column; /* Try this first */ margin-bottom: 8px; } ``` ::: ### Observation :::success What happened? Now change `column` to `row`: ```css .row { display: flex; flex-direction: row; /* Now try this */ margin-bottom: 8px; } ``` ::: :::warning ### Think About It - Which direction makes more sense for Wordle? - What do you think the default `flex-direction` is? - When might you want to use `column`? ::: --- ## 🧪 Experiment 3: Centering Content Look at your letters - they're probably stuck in the top-left corner of each tile. This is one of the most useful CSS techniques: perfectly centering content. :::info **Prediction:** You're going to add TWO properties to center the letters. Can you guess what they might be called? ::: ### Add Centering Properties - One at a Time :::success First, add just this property to your `.tile`: ```css .tile { /* ... existing styles ... */ display: flex; justify-content: center; /* Add this first */ } ``` ::: **What changed?** *Click below to see a screenshot of my code at this step:* :::spoiler See screenshot below: !![vertically centered letters](https://hackmd.io/_uploads/B1Mqb1A5ll.png) ::: :::success Now add the second property: ```css .tile { /* ... existing styles ... */ display: flex; justify-content: center; align-items: center; /* Add this second */ } ``` ::: **What changed now?** :::spoiler See screenshot below !![fully centered letters](https://hackmd.io/_uploads/SJF3Wy05xg.png)::: :::warning ### Understanding the Properties - `justify-content: center` controls _______ centering - `align-items: center` controls _______ centering - Why do you need `display: flex` for these to work? ::: --- ## 🧪 Experiment 4: Spacing with Gap vs Margin Your tiles are probably touching each other. Let's explore two ways to add spacing. ### Try the Traditional Way :::success Add this to your `.tile`: ```css .tile { /* ... existing styles ... */ margin: 5px; /* The old way */ } ``` ::: Your page shoud now look something like this: :::spoiler See screenshot ![margins](https://hackmd.io/_uploads/S1gmZzkC5ge.png) ::: > Look at the spacing around your tiles. > Notice anything weird about the edges? ### Try the Modern Way :::success **Delete the margin** and add this to your `.row` instead: ```css .row { display: flex; flex-direction: row; gap: 10px; /* The new way */ } ``` ::: *Now you should see something like the following:* :::spoiler see screenshot below ![image](https://hackmd.io/_uploads/SJIdzy05xx.png) ::: :::success **Now, let's fix the vertical spacing** ```css .row { display: flex; flex-direction: row; gap: 10px; /* BUG #3: Rows will be touching each other vertically */ /* TODO: Add margin-bottom: 5px; for spacing between rows */ margin-bottom: 5px; } ``` ::: Here's what your layout should look like now: :::spoiler see screenshot below ![gap and margin](https://hackmd.io/_uploads/Sk9WmJ0cgl.png)::: :::warning ### Compare the Results - What's different about the spacing? - Which method gives cleaner edges? - Why might `gap` be better than `margin` for flex layouts? ::: --- ## 🧪 Experiment 5: Center the Entire Game The ultimate challenge: center the whole game on the page! :::info **Prediction:** You've learned the centering techniques. How would you apply them to center the entire `.game-container` in the browser window? ::: ### Apply Your Knowledge :::success Add these properties to your `body`: ```css body { /* previous styles above here*/ /* add these new ones*/ display: flex; justify-content: center; align-items: center; min-height: 100vh; } ``` ::: Now, your gameboard should be properly centered: :::spoiler see screenshot below ![image](https://hackmd.io/_uploads/B1rs7y05ll.png)::: :::warning > **Note:** `vh` stands for "viewport height" - it's a unit that's relative to the browser window size. `100vh` means "100% of the viewport height", so the full height of the browser window. ### Understanding the Code - Why do we need `min-height: 100vh`? - What would happen without it? - Try removing `align-items: center` temporarily - what changes? ::: --- ## 🧪 Experiment 6: Stack the Rows Your game board probably needs the rows stacked vertically and centered. :::info **Prediction:** How would you make the `.game-board` stack its rows vertically and center them? ::: ### Apply Flexbox to Game Board :::success Add the following lines to `.game-board`: ```css .game-board { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-bottom: 30px; } ``` ::: :::success **Remove the `margin-bottom` from `.row`** since we're using `gap` now: ```css .row { display: flex; flex-direction: row; gap: 10px; /* Remove margin-bottom: 8px; */ } ``` ::: :::success Let's also go ahead and remove the temporary styling at the bottom of the `styles.css` file: ```css! /* Optional: temporary styling to make it easier to see while building. */ .tile:empty { background-color: #f8f9fa; border-style: dashed; } ``` ::: Yours should look something like this: :::spoiler see screenshot below ![everything but colors and header/footer spacing](https://hackmd.io/_uploads/SJyKVJAcel.png) ::: ## 🧪 Experiment 7: Polish the Header Spacing Your header is probably too close to the game board. Let's add some breathing room. :::success Add proper spacing to your header: ```css header h1 { text-align: center; font-size: 2.5rem; font-weight: bold; border-bottom: 1px solid var(--border-color); \* Add these for better spacing: *\ margin-bottom: 30px; padding-bottom: 15px; } ``` ::: *Here's a screenshot:* || ![image](https://hackmd.io/_uploads/Hk6AUy09gg.png)|| :::warning ### Understanding the Difference - `padding-bottom: 15px` adds space **inside** the border (between text and border line) - `margin-bottom: 30px` adds space **outside** the border (between header and game board) ::: ## 🧪 Experiment 8: Fix Footer Spacing The footer is probably too close to the game board. Let's give it some space. :::success Add margin to your footer: ```css footer { text-align: center; font-size: 0.9rem; color: #6e6e6e; /* Add this for proper spacing: */ margin-top: 20px; } ::: ![image](https://hackmd.io/_uploads/r1plv1Ccll.png) --- ### Filled Tiles -- Darker border Let's make tiles with letters have a darker border so they feel more "active": :::success Add this CSS rule after your color classes: ```css /* Darker border for tiles that contain letters */ .tile:not(:empty) { border-color: #878a8c; } ::: ||![wordle with tile border](https://hackmd.io/_uploads/B1ivuyC5ge.png)|| --- ## Now, Let\'s Add Some Color :::success Add some Wordle-style colors! Apply these classes to your first row's tiles: ```css /* Add to your CSS */ .tile.correct { background-color: #6aaa64; /* Green - using hexadecimal color notation */ border-color: #6aaa64; color: white; } .tile.present { background-color: #c9b458; /* Yellow - hex colors start with # */ border-color: #c9b458; color: white; } .tile.absent { background-color: #787c7e; /* Gray - 6 digits for red, green, blue values */ border-color: #787c7e; color: white; } ``` ::: :::warning **Note:** These colors use hexadecimal notation (hex codes). The `#` symbol indicates hex format, followed by 6 characters representing red, green, and blue values. For example, `#6aaa64` breaks down as: `6a` (red), `aa` (green), `64` (blue). ::: :::success Update your first row in HTML: ```html <div class="row"> <div class="tile correct">W</div> <div class="tile present">O</div> <div class="tile absent">R</div> <div class="tile absent">D</div> <div class="tile present">S</div> </div> ``` ::: And Voila!! ![image](https://hackmd.io/_uploads/r1OhOJR5ex.png) --- ## 📸 Document Your Progress :::danger Take these screenshots: 1. `lastname_before.png` - Your starting point (if you haven't already) 2. `lastname_after.png` - Your completed layout 3. `lastname_colors.png` - With Wordle colors added ::: --- ::: warning ## Reflection Questions These aren't graded, but they'll help solidify your learning. You can write your answers as comments at the bottom of your CSS file: ```css /* REFLECTION QUESTIONS: 1. What was the most surprising moment for you in this lab? 2. In your own words, explain what display: flex does to an element. 3. What's the difference between `justify-content` and `align-items`? 4. Why is gap better than margin for spacing in flexbox? 5. Before this lab, what was your biggest challenge with CSS layout? 6. What would you tell a friend who's struggling to center things in CSS? */ ``` ::: --- ## Optional Challenges :::success ### Challenge 1: Responsive Design Add this media query and see what happens on mobile: ```css @media (max-width: 480px) { .tile { width: 50px; height: 50px; font-size: 1.5rem; } } ``` ::: :::success ### Challenge 2: Hover Effects ```css .tile:hover { transform: scale(1.05); transition: transform 0.2s ease; } ``` ::: :::success ### Challenge 3: CSS Grid Alternative Try rebuilding the same layout using CSS Grid instead of Flexbox. Which do you prefer? ::: --- ## Planning the Interactive Version Now that you have a solid layout, let's think about what it would take to make this actually playable. This will help you prepare for when we add JavaScript functionality next class. :::info ### Brainstorming Session Look at your Wordle layout and think about what needs to happen to make it interactive. Consider: **User Actions:** - How does a player input their guess? - What happens when they press Enter? - How do they know if a letter is correct, present, or absent? **Game Logic:** - How does the game check if a guess is valid? - How does it compare the guess to the target word? - When does the game end (win or lose)? **Visual Feedback:** - How do tiles change color based on the guess? - How does the game show which row is currently active? - What happens when the game ends? ::: ### Write Some Pseudocode :::success **Instructions:** Write pseudocode (step-by-step logic in plain English) for how the Wordle game should work. Don't worry about actual JavaScript syntax - just think through the logic. ::: **Example format:** ``` WHEN the page loads: - Set the target word (maybe "WORDS") - Set current row to 0 - Set current tile to 0 WHEN user types a letter: - If current tile is less than 5: - Add letter to current tile - Move to next tile - Display the letter in the tile WHEN user presses Enter: - Check if row is complete (5 letters) - If complete: - Compare guess to target word - Color the tiles based on results - Move to next row - If not complete: - Show error message ... continue for other scenarios ``` :::success **Your turn:** Write pseudocode for at least these scenarios: 1. **Typing letters** - What should happen when a user types? 2. **Submitting a guess** - What should happen when they press Enter? 3. **Checking the guess** - How do you determine which letters are correct/present/absent? 4. **Ending the game** - When and how does the game end? ::: :::warning **💭 Reflection:** After writing your pseudocode, what seems like it would be the most challenging part to implement? What questions do you have about how this would work in JavaScript? ::: --- ## 📤 Submission Instructions :::danger **Submit via Blackboard > Lab02 Assignment** **Required Submissions:** 1. **Screenshots** (upload as image files): - `lastname_before.png` - Your broken starter code - `lastname_after.png` - Your completed layout - `lastname_colors.png` - Final version with Wordle colors 2. **GitHub Repository Link:** - Copy your repository URL from GitHub - **Make it clickable:** Format as a proper link in Blackboard - Example: `https://github.com/drake-full-stack/lab02-css-wordle-layout-yourUsername` **✅ Before submitting, make sure:** - [ ] All screenshots are clearly named with your last name - [ ] Your GitHub repo link works when clicked - [ ] Your final code includes all experiments completed - [ ] You've pushed your final changes to GitHub ::: :::info **💡 GitHub Reminder:** Don't forget to commit and push your final changes: ```bash git add . git commit -m "Complete Lab02: Wordle layout with flexbox" git push origin main ``` ::: ## What's Next? You've just learned the fundamental building blocks of modern web layout! These flexbox skills will serve you in every web project you build. **Coming soon!**: We'll take your pseudocode and turn it into real JavaScript to make this Wordle game fully interactive!