我建了一个假Netflix来恶搞朋友从零搭建仿流媒体平台的完整技术指南最近在和朋友聊天时发现很多人都对Netflix这样的流媒体平台充满好奇。作为一个开发者我决定用技术手段恶搞一下朋友——搭建一个外观酷似Netflix的假平台让他们误以为我开发了什么大项目。这个项目不仅有趣还能完整展示前端开发、API集成和用户体验设计的实战技巧。本文将带你从零开始使用现代Web技术栈构建一个功能完整的仿Netflix平台。无论你是前端新手想要学习实战项目还是有经验的开发者想了解流媒体平台的技术实现都能从中获得实用价值。我们将覆盖HTML/CSS布局、JavaScript交互、电影数据API集成、响应式设计等核心知识点。1. 项目概述与技术选型1.1 项目目标与功能规划这个仿Netflix项目的主要目标是创建一个视觉上高度相似、交互体验流畅的流媒体平台界面。虽然是个恶搞项目但我们在技术实现上要保持专业水准。核心功能包括电影海报轮播展示类似Netflix的主页横幅分类电影列表横向滚动布局电影详情模态框点击海报查看详细信息搜索功能实时过滤电影内容响应式设计适配手机、平板、桌面设备模拟登录界面增加真实感1.2 技术栈选择理由考虑到项目的展示性质和开发效率我们选择以下技术栈前端三件套HTML5 CSS3 JavaScript轻量级无需复杂构建工具部署简单直接浏览器打开即可运行学习曲线平缓适合各层次开发者CSS框架自定义CSS为主完全控制样式细节实现高度还原避免框架的默认样式干扰更好地理解CSS布局原理数据源The Movie Database (TMDB) API免费且丰富的电影数据库提供高质量的电影海报和元数据良好的文档和开发者支持图标库Font Awesome丰富的矢量图标易于使用和自定义良好的浏览器兼容性2. 环境准备与项目结构2.1 开发环境配置在开始编码前确保你的开发环境准备就绪代码编辑器推荐Visual Studio Code免费、功能强大WebStorm专业级JavaScript IDESublime Text轻量快速浏览器开发者工具Chrome DevTools推荐Firefox Developer EditionSafari Web Inspector必要的浏览器插件JSON Formatter美化API响应查看ColorZilla颜色拾取工具Responsive Design Checker响应式测试2.2 获取TMDB API密钥TMDB API是我们项目的数据来源需要免费注册获取API密钥访问 The Movie Database官网注册账号并验证邮箱进入设置 → API页面申请开发者API密钥记录你的API密钥如abcd1234efgh5678ijkl9012重要安全提示在实际项目中API密钥应该存储在环境变量中避免直接写在客户端代码里。本文为演示目的简化处理但生产环境务必遵循安全最佳实践。2.3 项目目录结构规划创建清晰的项目结构有助于代码维护fake-netflix/ ├── index.html # 主页面文件 ├── styles/ │ ├── main.css # 主要样式文件 │ ├── responsive.css # 响应式样式 │ └── variables.css # CSS变量定义 ├── scripts/ │ ├── app.js # 主要逻辑 │ ├── api.js # API调用模块 │ └── ui.js # 界面交互模块 ├── assets/ │ ├── images/ # 本地图片资源 │ └── icons/ # 图标文件 └── README.md # 项目说明文档3. 基础HTML结构搭建3.1 创建主页面框架首先构建基本的HTML结构这是整个项目的基础!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleNetflix - 随时随地观看电影和电视节目/title meta namedescription contentNetflix克隆版 - 流媒体平台演示项目 !-- 样式表 -- link relstylesheet hrefstyles/variables.css link relstylesheet hrefstyles/main.css link relstylesheet hrefstyles/responsive.css !-- Font Awesome图标 -- link relstylesheet hrefhttps://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css !-- 谷歌字体 -- link hrefhttps://fonts.googleapis.com/css2?familyHelveticaNeue:wght300;400;500;700displayswap relstylesheet /head body !-- 导航栏 -- nav classnavbar idnavbar div classnav-container div classnav-logo img srcassets/images/netflix-logo.png altNetflix classlogo /div div classnav-menu a href# classnav-link首页/a a href# classnav-link电视节目/a a href# classnav-link电影/a a href# classnav-link最新内容/a a href# classnav-link我的片单/a /div div classnav-actions div classsearch-container i classfas fa-search search-icon/i input typetext classsearch-input placeholder搜索影片... /div div classuser-menu img srcassets/images/user-avatar.png alt用户 classuser-avatar /div /div /div /nav !-- 主要内容区域 -- main classmain-content !-- 横幅海报区域 -- section classhero-banner idheroBanner div classbanner-content h1 classbanner-title怪奇物语/h1 p classbanner-description当一个小男孩失踪后一个小镇揭开了一连串谜团涉及秘密实验、恐怖的超自然力量还有一个非常奇怪的小女孩。/p div classbanner-actions button classbtn btn-primary i classfas fa-play/i 立即观看 /button button classbtn btn-secondary i classfas fa-info-circle/i 更多信息 /button /div /div div classbanner-fade/div /section !-- 电影列表区域 -- section classmovie-rows idmovieRows !-- 动态生成电影行 -- /section /main !-- 电影详情模态框 -- div classmodal idmovieModal div classmodal-content span classclose-modaltimes;/span div classmodal-body idmodalBody !-- 动态加载电影详情 -- /div /div /div !-- JavaScript文件 -- script srcscripts/api.js/script script srcscripts/ui.js/script script srcscripts/app.js/script /body /html3.2 语义化标签的重要性在HTML结构中使用正确的语义化标签不仅有助于SEO还能提高代码的可读性和可维护性header、nav、main、section等标签明确划分内容区域为重要元素添加有意义的ID和class名称使用alt属性为图片提供替代文本确保表单元素有对应的label标签4. CSS样式设计与Netflix风格还原4.1 定义CSS变量和基础样式创建variables.css文件定义整个项目的设计系统:root { /* 颜色系统 - Netflix风格 */ --netflix-red: #e50914; --netflix-black: #141414; --netflix-dark-gray: #2d2d2d; --netflix-gray: #808080; --netflix-light-gray: #e5e5e5; --netflix-white: #ffffff; /* 渐变效果 */ --hero-gradient: linear-gradient( to top, rgba(20, 20, 20, 0.9) 0%, rgba(20, 20, 20, 0.7) 30%, rgba(20, 20, 20, 0.5) 50%, transparent 100% ); /* 阴影效果 */ --card-shadow: 0 2px 10px rgba(0, 0, 0, 0.5); --text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8); /* 字体系统 */ --font-primary: Helvetica Neue, Arial, sans-serif; --font-size-xs: 0.75rem; /* 12px */ --font-size-sm: 0.875rem; /* 14px */ --font-size-base: 1rem; /* 16px */ --font-size-lg: 1.125rem; /* 18px */ --font-size-xl: 1.25rem; /* 20px */ --font-size-2xl: 1.5rem; /* 24px */ --font-size-3xl: 2rem; /* 32px */ --font-size-4xl: 3rem; /* 48px */ /* 间距系统 */ --spacing-xs: 0.25rem; /* 4px */ --spacing-sm: 0.5rem; /* 8px */ --spacing-md: 1rem; /* 16px */ --spacing-lg: 1.5rem; /* 24px */ --spacing-xl: 2rem; /* 32px */ --spacing-2xl: 3rem; /* 48px */ /* 动画时长 */ --transition-fast: 0.2s; --transition-normal: 0.3s; --transition-slow: 0.5s; /* 响应式断点 */ --breakpoint-mobile: 768px; --breakpoint-tablet: 1024px; --breakpoint-desktop: 1200px; } /* 基础重置样式 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: var(--font-primary); background-color: var(--netflix-black); color: var(--netflix-white); line-height: 1.6; overflow-x: hidden; } /* 滚动条样式定制 */ ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: var(--netflix-dark-gray); } ::-webkit-scrollbar-thumb { background: var(--netflix-red); border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: #f40612; }4.2 导航栏样式实现导航栏是Netflix风格的重要视觉元素需要精细还原/* 导航栏样式 */ .navbar { position: fixed; top: 0; width: 100%; height: 68px; background: linear-gradient( to bottom, rgba(0, 0, 0, 0.7) 0%, transparent 100% ); display: flex; align-items: center; padding: 0 var(--spacing-lg); z-index: 1000; transition: background-color var(--transition-normal); } .navbar.scrolled { background-color: var(--netflix-black); } .nav-container { display: flex; align-items: center; justify-content: space-between; width: 100%; max-width: 1400px; margin: 0 auto; } .nav-logo .logo { height: 36px; width: auto; } .nav-menu { display: flex; gap: var(--spacing-lg); margin-left: var(--spacing-xl); } .nav-link { color: var(--netflix-white); text-decoration: none; font-size: var(--font-size-sm); font-weight: 500; transition: color var(--transition-fast); } .nav-link:hover { color: var(--netflix-light-gray); } .nav-actions { display: flex; align-items: center; gap: var(--spacing-lg); } .search-container { position: relative; display: flex; align-items: center; } .search-icon { position: absolute; left: 10px; color: var(--netflix-white); cursor: pointer; } .search-input { background: transparent; border: 1px solid transparent; color: var(--netflix-white); padding: 6px 10px 6px 30px; border-radius: 4px; width: 0; opacity: 0; transition: all var(--transition-normal); } .search-input.active { width: 200px; opacity: 1; border-color: var(--netflix-white); background: rgba(0, 0, 0, 0.7); } .user-avatar { width: 32px; height: 32px; border-radius: 4px; object-fit: cover; }4.3 横幅区域和电影列表样式横幅区域是Netflix的视觉焦点需要精心设计/* 主横幅区域 */ .hero-banner { position: relative; height: 70vh; min-height: 500px; background: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)), url(https://image.tmdb.org/t/p/original/example-banner.jpg); background-size: cover; background-position: center; display: flex; align-items: flex-end; padding: var(--spacing-2xl); margin-top: 68px; /* 导航栏高度 */ } .banner-content { max-width: 600px; z-index: 2; } .banner-title { font-size: var(--font-size-4xl); font-weight: 700; margin-bottom: var(--spacing-md); text-shadow: var(--text-shadow); } .banner-description { font-size: var(--font-size-lg); margin-bottom: var(--spacing-lg); line-height: 1.4; text-shadow: var(--text-shadow); } .banner-actions { display: flex; gap: var(--spacing-md); } .btn { padding: 8px 24px; border: none; border-radius: 4px; font-size: var(--font-size-base); font-weight: 600; cursor: pointer; transition: all var(--transition-fast); display: flex; align-items: center; gap: 8px; } .btn-primary { background-color: var(--netflix-white); color: var(--netflix-black); } .btn-primary:hover { background-color: rgba(255, 255, 255, 0.8); } .btn-secondary { background-color: rgba(109, 109, 110, 0.7); color: var(--netflix-white); } .btn-secondary:hover { background-color: rgba(109, 109, 110, 0.5); } .banner-fade { position: absolute; bottom: 0; left: 0; right: 0; height: 100px; background: var(--hero-gradient); z-index: 1; } /* 电影行样式 */ .movie-rows { padding: var(--spacing-xl) 0; } .movie-row { margin-bottom: var(--spacing-2xl); padding: 0 var(--spacing-lg); } .row-title { font-size: var(--font-size-xl); font-weight: 600; margin-bottom: var(--spacing-md); color: var(--netflix-white); } .movie-container { display: flex; gap: 8px; overflow-x: auto; padding: 10px 0; scrollbar-width: none; /* Firefox */ } .movie-container::-webkit-scrollbar { display: none; /* Chrome, Safari, Edge */ } .movie-card { flex: 0 0 auto; width: 220px; border-radius: 4px; overflow: hidden; transition: transform var(--transition-normal); cursor: pointer; position: relative; } .movie-card:hover { transform: scale(1.05); z-index: 10; } .movie-poster { width: 100%; height: 330px; object-fit: cover; display: block; } .movie-info { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(transparent, rgba(0, 0, 0, 0.8)); padding: var(--spacing-md); opacity: 0; transition: opacity var(--transition-normal); } .movie-card:hover .movie-info { opacity: 1; } .movie-title { font-size: var(--font-size-sm); font-weight: 600; margin-bottom: 4px; } .movie-year { font-size: var(--font-size-xs); color: var(--netflix-light-gray); }5. JavaScript交互功能实现5.1 API数据获取模块创建api.js文件处理与TMDB API的通信// API配置 const API_CONFIG { baseUrl: https://api.themoviedb.org/3, apiKey: 你的TMDB_API密钥, // 替换为实际API密钥 imageBaseUrl: https://image.tmdb.org/t/p/ }; // 图片尺寸配置 const IMAGE_SIZES { poster: { small: w185, medium: w342, large: w500, original: original }, backdrop: { small: w300, medium: w780, large: w1280, original: original } }; class MovieAPI { constructor() { this.apiKey API_CONFIG.apiKey; this.baseUrl API_CONFIG.baseUrl; } // 通用API请求方法 async makeRequest(endpoint, params {}) { try { const url new URL(${this.baseUrl}${endpoint}); url.searchParams.append(api_key, this.apiKey); url.searchParams.append(language, zh-CN); // 添加额外参数 Object.keys(params).forEach(key { url.searchParams.append(key, params[key]); }); const response await fetch(url); if (!response.ok) { throw new Error(API请求失败: ${response.status}); } return await response.json(); } catch (error) { console.error(API请求错误:, error); throw error; } } // 获取热门电影 async getPopularMovies(page 1) { return this.makeRequest(/movie/popular, { page }); } // 获取正在上映的电影 async getNowPlayingMovies(page 1) { return this.makeRequest(/movie/now_playing, { page }); } // 获取即将上映的电影 async getUpcomingMovies(page 1) { return this.makeRequest(/movie/upcoming, { page }); } // 获取最高评分电影 async getTopRatedMovies(page 1) { return this.makeRequest(/movie/top_rated, { page }); } // 搜索电影 async searchMovies(query, page 1) { return this.makeRequest(/search/movie, { query, page }); } // 获取电影详情 async getMovieDetails(movieId) { return this.makeRequest(/movie/${movieId}); } // 获取电影分类 async getGenres() { return this.makeRequest(/genre/movie/list); } // 根据分类获取电影 async getMoviesByGenre(genreId, page 1) { return this.makeRequest(/discover/movie, { with_genres: genreId, page }); } // 构建图片URL getImageUrl(path, size medium, type poster) { if (!path) return /assets/images/placeholder.jpg; const sizeKey IMAGE_SIZES[type][size] || IMAGE_SIZES[type].medium; return ${API_CONFIG.imageBaseUrl}${sizeKey}${path}; } } // 创建全局API实例 const movieAPI new MovieAPI();5.2 用户界面交互模块创建ui.js文件处理页面交互逻辑class NetflixUI { constructor() { this.movieAPI movieAPI; this.currentMovies []; this.searchTimeout null; this.initializeEventListeners(); this.loadInitialData(); } // 初始化事件监听器 initializeEventListeners() { // 导航栏滚动效果 window.addEventListener(scroll, this.handleScroll.bind(this)); // 搜索功能 const searchIcon document.querySelector(.search-icon); const searchInput document.querySelector(.search-input); searchIcon.addEventListener(click, () { searchInput.classList.toggle(active); if (searchInput.classList.contains(active)) { searchInput.focus(); } }); searchInput.addEventListener(input, this.handleSearch.bind(this)); // 模态框关闭 const modal document.getElementById(movieModal); const closeBtn document.querySelector(.close-modal); closeBtn.addEventListener(click, () { modal.style.display none; }); window.addEventListener(click, (event) { if (event.target modal) { modal.style.display none; } }); } // 处理页面滚动 handleScroll() { const navbar document.getElementById(navbar); if (window.scrollY 100) { navbar.classList.add(scrolled); } else { navbar.classList.remove(scrolled); } } // 处理搜索输入 handleSearch(event) { const query event.target.value.trim(); // 防抖处理 clearTimeout(this.searchTimeout); if (query.length 2) { if (query.length 0) { this.loadInitialData(); } return; } this.searchTimeout setTimeout(() { this.performSearch(query); }, 500); } // 执行搜索 async performSearch(query) { try { const searchResults await this.movieAPI.searchMovies(query); this.displaySearchResults(searchResults.results); } catch (error) { console.error(搜索失败:, error); this.showError(搜索失败请稍后重试); } } // 加载初始数据 async loadInitialData() { try { // 并行获取多种类型的电影数据 const [popular, nowPlaying, topRated, genres] await Promise.all([ this.movieAPI.getPopularMovies(), this.movieAPI.getNowPlayingMovies(), this.movieAPI.getTopRatedMovies(), this.movieAPI.getGenres() ]); this.displayMovieRows([ { title: 热门电影, movies: popular.results }, { title: 正在热映, movies: nowPlaying.results }, { title: 高分推荐, movies: topRated.results } ]); // 根据分类加载更多电影行 this.loadMoviesByGenres(genres.genres.slice(0, 3)); } catch (error) { console.error(数据加载失败:, error); this.showError(数据加载失败请检查网络连接); } } // 根据分类加载电影 async loadMoviesByGenres(genres) { try { const genrePromises genres.map(genre this.movieAPI.getMoviesByGenre(genre.id) ); const genreResults await Promise.all(genrePromises); const additionalRows genres.map((genre, index) ({ title: genre.name, movies: genreResults[index].results })); this.displayMovieRows(additionalRows); } catch (error) { console.error(分类电影加载失败:, error); } } // 显示电影行 displayMovieRows(rowsData) { const movieRowsContainer document.getElementById(movieRows); movieRowsContainer.innerHTML ; rowsData.forEach(rowData { if (rowData.movies rowData.movies.length 0) { const rowElement this.createMovieRow(rowData.title, rowData.movies); movieRowsContainer.appendChild(rowElement); } }); } // 创建单个电影行 createMovieRow(title, movies) { const rowDiv document.createElement(div); rowDiv.className movie-row; const titleElement document.createElement(h2); titleElement.className row-title; titleElement.textContent title; rowDiv.appendChild(titleElement); const containerDiv document.createElement(div); containerDiv.className movie-container; movies.slice(0, 10).forEach(movie { const movieCard this.createMovieCard(movie); containerDiv.appendChild(movieCard); }); rowDiv.appendChild(containerDiv); return rowDiv; } // 创建电影卡片 createMovieCard(movie) { const cardDiv document.createElement(div); cardDiv.className movie-card; cardDiv.addEventListener(click, () this.showMovieDetails(movie.id)); const posterImg document.createElement(img); posterImg.className movie-poster; posterImg.src this.movieAPI.getImageUrl(movie.poster_path, medium); posterImg.alt movie.title; posterImg.loading lazy; // 图片加载失败处理 posterImg.onerror () { posterImg.src /assets/images/poster-placeholder.jpg; }; const infoDiv document.createElement(div); infoDiv.className movie-info; const titleElement document.createElement(div); titleElement.className movie-title; titleElement.textContent movie.title; const yearElement document.createElement(div); yearElement.className movie-year; if (movie.release_date) { yearElement.textContent new Date(movie.release_date).getFullYear(); } infoDiv.appendChild(titleElement); infoDiv.appendChild(yearElement); cardDiv.appendChild(posterImg); cardDiv.appendChild(infoDiv); return cardDiv; } // 显示电影详情 async showMovieDetails(movieId) { try { const movieDetails await this.movieAPI.getMovieDetails(movieId); this.displayMovieModal(movieDetails); } catch (error) { console.error(获取电影详情失败:, error); this.showError(无法加载电影详情); } } // 显示电影详情模态框 displayMovieModal(movie) { const modal document.getElementById(movieModal); const modalBody document.getElementById(modalBody); modalBody.innerHTML div classmodal-poster img src${this.movieAPI.getImageUrl(movie.backdrop_path, large, backdrop)} alt${movie.title} classmodal-backdrop /div div classmodal-info h2 classmodal-title${movie.title}/h2 div classmodal-meta span classmodal-year${new Date(movie.release_date).getFullYear()}/span span classmodal-runtime${movie.runtime} 分钟/span span classmodal-rating⭐ ${movie.vote_average.toFixed(1)}/span /div p classmodal-overview${movie.overview || 暂无简介}/p div classmodal-actions button classbtn btn-primary i classfas fa-play/i 立即观看 /button button classbtn btn-secondary i classfas fa-plus/i 加入片单 /button /div /div ; modal.style.display block; } // 显示搜索结果 displaySearchResults(movies) { this.displayMovieRows([{ title: 搜索结果, movies }]); } // 显示错误信息 showError(message) { // 简单的错误提示实现 const errorDiv document.createElement(div); errorDiv.style.cssText position: fixed; top: 100px; right: 20px; background: #e50914; color: white; padding: 15px; border-radius: 4px; z-index: 1001; max-width: 300px; ; errorDiv.textContent message; document.body.appendChild(errorDiv); setTimeout(() { document.body.removeChild(errorDiv); }, 3000); } }5.3 主应用初始化创建app.js文件初始化整个应用// 应用主入口 document.addEventListener(DOMContentLoaded, function() { // 检查API密钥是否设置 if (movieAPI.apiKey 你的TMDB_API密钥) { alert(请先在api.js文件中设置你的TMDB API密钥); return; } // 初始化UI const netflixUI new NetflixUI(); // 设置横幅电影可选功能 setFeaturedMovie(); console.log(Netflix克隆版初始化完成); }); // 设置特色电影横幅 async function setFeaturedMovie() { try { const popularMovies await movieAPI.getPopularMovies(); if (popularMovies.results.length 0) { const featuredMovie popularMovies.results[0]; const banner document.getElementById(heroBanner); // 设置背景图片 banner.style.backgroundImage linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)), url(${movieAPI.getImageUrl(featuredMovie.backdrop_path, original, backdrop)}) ; // 更新横幅内容 const titleElement banner.querySelector(.banner-title); const descElement banner.querySelector(.banner-description); titleElement.textContent featuredMovie.title; descElement.textContent featuredMovie.overview || 暂无简介; // 更新按钮事件 const playBtn banner.querySelector(.btn-primary); const infoBtn banner.querySelector(.btn-secondary); playBtn.onclick () netflixUI.showMovieDetails(featuredMovie.id); infoBtn.onclick () netflixUI.showMovieDetails(featuredMovie.id); } } catch (error) { console.error(设置特色电影失败:, error); } }6. 响应式设计与移动端优化6.1 移动端适配策略创建responsive.css文件确保在各种设备上都有良好体验/* 平板设备适配 */ media (max-width: 1024px) { .hero-banner { height: 60vh; padding: var(--spacing-xl); } .banner-title { font-size: var(--font-size-3xl); } .banner-description { font-size: var(--font-size-base); } .movie-card { width: 180px; } .movie-poster { height: 270px; } .nav-menu { gap: var(--spacing-md); } } /* 移动设备适配 */ media (max-width: 768px) { .navbar { height: 60px; padding: 0 var(--spacing-md); } .nav-logo .logo { height: 30px; } .nav-menu { display: none; /* 移动端隐藏导航菜单 */ } .hero-banner { height: 50vh; min-height: 400px; margin-top: 60px; padding: var(--spacing-lg); align-items: center; text-align: center; } .banner-title { font-size: var(--font-size-2xl); } .banner-description { font-size: var(--font-size-sm); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; } .banner-actions { justify-content: center; flex-wrap: wrap; } .movie-row { padding: 0 var(--spacing-md); } .movie-card { width: 140px; } .movie-poster { height: 210px; } .modal-content { width: 95%; margin: 10% auto; } } /* 小屏手机适配 */ media (max-width: 480px) { .hero-banner { height: 40vh; min-height: 300px; } .banner-title { font-size: var(--font-size-xl); } .banner-description { -webkit-line-clamp: 2; } .btn { padding: 6px 16px; font-size: var(--font-size-sm); } .movie-card { width: 120px; } .movie-poster { height: 180px; } .row-title { font-size: var(--font-size-lg); } } /* 横屏模式优化 */ media (max-height: 500px) and (orientation: landscape) { .hero-banner { height: 100vh; } .banner-content { max-width: 70%; } } /* 高分辨率屏幕优化 */ media (min-width: 1400px) { .nav-container { max-width: 1600px; } .movie-row { padding: 0 var(--spacing-2xl); } } /* 减少动画无障碍功能 */ media (prefers-re