Hello! In the last lesson, we made our movie search app more professional by adding loading and error states. Now, the application is functionally complete for its core purpose, but it lacks the visual appeal of a modern web application.
This brings us to the final styling-focused lesson of this module. Our learning outcome is to style the application to create a polished, responsive user interface. We'll transform our app from a barebones functional prototype into something that looks and feels like a professional streaming service.
To achieve this, we will:
- Establish a consistent design system with global styles and colors.
- Style our components using modern CSS, including Flexbox, for a polished look. We'll draw inspiration from the Netflix UI.
- Implement advanced hover effects to enhance interactivity.
- Make our movie grid responsive, ensuring it adapts gracefully to different screen sizes, from mobile phones to desktops.
Let's get started on making our app shine!
A Quick Word on SCSS
For this lesson, we'll be using SCSS (Sassy CSS). SCSS is a "CSS preprocessor"—it's basically CSS with superpowers. It looks and feels just like CSS but adds useful features like variables, which are perfect for keeping our styling consistent.
To use it in your Vite-based React project, you just need to install it. Open your terminal in the project root and run:
npm install sass
That's it! Now you can rename your .css files to .scss (e.g., App.css to App.scss) and update the import statements in your JavaScript files. Your existing CSS will work perfectly, and you can start using new features.
Step 1: Establishing a Global Style and Theme
A polished UI starts with consistency. We'll define a global font and a main background color that all our components will share. We can store these in CSS variables for easy reuse.
The following video is a fantastic, in-depth tutorial on building a Netflix-style UI. We won't follow it end-to-end, but we will use its excellent styling techniques to guide our work.
React Netflix Movie App Design Tutorial | React UI Full Course for Beginners
Watch the beginning of the 'React Netflix Movie App Design Tutorial' by Lama Dev. This section covers setting up the project with SCSS and defining global styles, including a primary color variable.
Watch from 01:28 to 09:08. Pay close attention to how a main color is defined as a CSS variable in the app.scss file. You can apply this same technique to your project.
Based on the video, let's create our core styles.
- Rename your main CSS file (e.g.,
index.cssorApp.css) toApp.scss. Update the import in yourmain.jsxorApp.jsxfile. - In your
App.scss, define a main background color. The dark theme used in the video is perfect for a movie app.
/* src/App.scss */
/* Define a CSS variable for the main color in the root scope */
:root {
--main-color: #0b0b0b;
}
body {
background-color: var(--main-color);
color: white; /* Set default text color to white for the dark theme */
margin: 0;
font-family: 'Roboto', sans-serif; /* You can add a font from Google Fonts like in the video */
}
/* A utility class for our main container */
.container {
margin: 0 auto;
padding: 0 50px;
}
Now, make sure your main App component's root div uses this theme.
Step 2: Creating a Polished and Responsive Header
A good header is crucial for navigation and branding. We want ours to be clean and have a professional touch, like changing its background from transparent to solid as the user scrolls.
The same video demonstrates this beautifully. The concepts shown can be applied directly to your Header and SearchBox components.
React Netflix Movie App Design Tutorial | React UI Full Course for Beginners
This segment of the Netflix tutorial focuses on building a responsive navigation bar using Flexbox and implementing a scroll-triggered background change.
Watch from 10:38 to 29:41. Focus on these key techniques: Using display: flex and justify-content: space-between to position the logo and other items. Using useState and a window.onscroll event listener to track the scroll position. Conditionally applying a CSS class to change the navbar's background color.
Here's how you can adapt that logic to your Header.jsx:
// src/components/Header.jsx
import React, { useState, useEffect } from 'react';
import './Header.scss'; // Make sure to create and import the SCSS file
const Header = ({ title }) => {
const [isScrolled, setIsScrolled] = useState(false);
useEffect(() => {
const handleScroll = () => {
// window.scrollY is equivalent to window.pageYOffset
setIsScrolled(window.scrollY > 0);
};
window.addEventListener('scroll', handleScroll);
// Cleanup function to remove the event listener
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []); // Empty dependency array ensures this runs only once
return (
// Conditionally apply the 'scrolled' class
<div className={isScrolled ? 'header scrolled' : 'header'}>
<div className="header-content">
<h1>{title}</h1>
{/* Your SearchBox component would go here or nearby */}
</div>
</div>
);
};
export default Header;
And the corresponding SCSS:
/* src/components/Header.scss */
.header {
color: white;
font-size: 14px;
position: fixed; /* Keep it at the top */
top: 0;
width: 100%;
z-index: 999;
background: linear-gradient(to top, transparent 0%, rgb(0, 0, 0, 0.3) 50%);
transition: background-color 0.5s ease;
&.scrolled {
background-color: var(--main-color);
}
.header-content {
padding: 20px 50px;
display: flex;
align-items: center;
justify-content: space-between;
}
}
This gives you a sleek, professional header that responds to user interaction.
Step 3: Designing a Responsive Movie Grid
Your MovieList component currently renders a list of movies. On a large screen, they should appear in a grid. On a small screen, they should stack neatly. While media queries work, modern CSS gives us a more powerful and elegant solution: CSS Grid with auto-fit and minmax().
This technique tells the browser: "Create as many columns as you can that are at least X pixels wide, and let them grow to fill any remaining space." This single line of CSS replaces multiple media queries.

The following video explains this concept perfectly.
Create Responsive CSS Grid Layouts with GRID WRAPPING
Watch 'Create Responsive CSS Grid Layouts with GRID WRAPPING' to understand how to build a flexible, wrapping grid with just one line of CSS.
Watch the entire video. It's short and packed with value. Pay special attention to the combination of repeat(auto-fit, minmax(300px, 1fr)). This is the key to our responsive grid.
Now, let's apply this to your MovieList component. Assuming your MovieList.jsx renders a container div around your MovieCard components, you can apply the grid styles to that container.
In your MovieList.scss file:
/* src/components/MovieList.scss */
.movie-list {
display: grid;
// This is the magic line!
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-gap: 1.5rem; /* Adds space between the movie cards */
padding: 2rem 0;
}

Your MovieList component's JSX would look something like this:
// src/components/MovieList.jsx
import React from 'react';
import MovieCard from './MovieCard';
import './MovieList.scss';
const MovieList = ({ movies }) => {
return (
<div className="movie-list">
{movies.map((movie) => (
<MovieCard key={movie.imdbID} movie={movie} />
))}
</div>
);
};
export default MovieList;
Test your understanding!
Imagine you want your movie cards to be a bit smaller on mobile. You decide each card should have a minimum width of 200px instead of 250px, but they should still be able to grow. What change would you make to the grid-template-columns property?
Show answer
You would change the minimum value in the minmax() function.
The updated line would be:grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
This tells the grid to create as many columns as possible, ensuring each is at least 200px wide.
Step 4: Advanced Polish with Hover Effects
To truly elevate the UI, we can add an advanced hover effect to our MovieCard components. Instead of a simple color change, we'll make the card scale up, and reveal more information and even a video preview, just like on Netflix.
This is an advanced technique that uses CSS transforms and absolute positioning. The Lama Dev video provides an amazing demonstration of how to achieve this.
React Netflix Movie App Design Tutorial | React UI Full Course for Beginners
This final video segment demonstrates how to create a sophisticated hover effect where a list item expands to show more details and a video player.
Watch from 01:07:02 to 01:26:57. The logic here is complex, so focus on the main ideas: Use the onMouseEnter and onMouseLeave events in React to toggle an isHovered state. When hovered, apply a new class or inline styles to the MovieCard. Use CSS transform: scale() to make the card bigger. Use position: absolute on the hovered card to make it appear above the other items in the grid, preventing it from pushing them around. Conditionally render the extra details (description, buttons) and the video player only when isHovered is true.
This is the most complex part of the lesson, but it delivers a huge payoff in terms of UI polish. Don't worry about getting it perfect on the first try. The key is to understand the interplay between React state (isHovered) and CSS properties (transform, position, z-index). Start by simply scaling the card on hover, and then gradually add more elements like the video player.
Conclusion
Congratulations! You've just learned how to take a functional React application and give it a polished, responsive, and professional user interface. This is a critical skill for any front-end developer, as it's often the quality of the UI that leaves the biggest impression on users.
Key Takeaways:
- Consistency is Key: Use CSS variables (
--main-color) to maintain a consistent theme throughout your application. - Flexbox for Alignment:
display: flexis your go-to tool for aligning items within a component, like in a header. - Grid for Responsive Layouts:
display: gridwithrepeat(auto-fit, minmax(…))is a powerful, modern way to create responsive, wrapping grids with minimal code. - Polish with Transitions and Transforms: Use CSS
transitionandtransformproperties, combined with React state, to create engaging hover effects and animations. - Positioning is Power:
position: absoluteis essential for creating overlay effects, like an expanded movie card that doesn't disrupt the rest of the grid.
In our next lesson, we'll add the final piece of functionality to our mid-course project: persisting application state across browser sessions by saving and loading data from localStorage. This will allow users to save a list of their favorite movies.