1. 顶部导航栏:包含Logo、搜索框、用户信息。
  2. 侧边栏菜单:包含我的音乐、推荐歌单、排行榜等。
    • 轮播图:展示推荐内容。
    • 推荐歌单:以网格形式展示。
    • 新歌速递:列表形式展示最新歌曲。
    • 排行榜:展示多个榜单。
  3. 底部播放器:包含播放/暂停、上一首/下一首、进度条、音量控制等。

第一步:项目文件结构

创建一个项目文件夹,并在其中创建以下文件:

html网易云音乐网页制作
(图片来源网络,侵删)
netease-music/
├── index.html          # HTML主文件
├── css/
│   └── style.css       # CSS样式文件
├── js/
│   └── main.js         # JavaScript交互逻辑
└── images/             # 存放图片资源
    ├── logo.png
    ├── banner1.jpg
    ├── banner2.jpg
    └── ... (其他歌曲封面等)

第二步:HTML 结构 (index.html)

这是整个页面的骨架,我们使用语义化的HTML5标签,并引入我们将要编写的CSS和JS文件。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">网易云音乐</title>
    <link rel="stylesheet" href="css/style.css">
    <!-- 引入字体图标库,这里使用Font Awesome作为示例 -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head>
<body>
    <!-- 顶部导航栏 -->
    <header class="header">
        <div class="header-left">
            <h1 class="logo">网易云音乐</h1>
        </div>
        <div class="header-center">
            <div class="search-box">
                <input type="text" placeholder="音乐、歌词、歌手">
                <button><i class="fas fa-search"></i></button>
            </div>
        </div>
        <div class="header-right">
            <a href="#" class="login-btn">登录</a>
            <a href="#" class="user-avatar"><img src="https://picsum.photos/seed/user1/40/40.jpg" alt="用户头像"></a>
        </div>
    </header>
    <div class="main-container">
        <!-- 侧边栏 -->
        <aside class="sidebar">
            <ul class="menu-list">
                <li class="menu-item active"><a href="#"><i class="fas fa-home"></i> 发现音乐</a></li>
                <li class="menu-item"><a href="#"><i class="fas fa-music"></i> 我的音乐</a></li>
                <li class="menu-item"><a href="#"><i class="fas fa-list"></i> 创建的歌单</a></li>
                <li class="menu-item"><a href="#"><i class="fas fa-star"></i> 我喜欢的音乐</a></li>
            </ul>
            <div class="playlists">
                <h3>创建的歌单</h3>
                <ul>
                    <li><a href="#">我喜欢的音乐</a></li>
                    <li><a href="#">搜索“周杰伦”</a></li>
                    <li><a href="#">搜索“林俊杰”</a></li>
                </ul>
            </div>
        </aside>
        <!-- 主内容区 -->
        <main class="content">
            <!-- 轮播图 -->
            <section class="banner">
                <div class="banner-slides">
                    <div class="slide active"><img src="https://picsum.photos/seed/banner1/800/300.jpg" alt="轮播图1"></div>
                    <div class="slide"><img src="https://picsum.photos/seed/banner2/800/300.jpg" alt="轮播图2"></div>
                    <div class="slide"><img src="https://picsum.photos/seed/banner3/800/300.jpg" alt="轮播图3"></div>
                </div>
                <div class="banner-dots">
                    <span class="dot active"></span>
                    <span class="dot"></span>
                    <span class="dot"></span>
                </div>
            </section>
            <!-- 推荐歌单 -->
            <section class="recommend-playlists">
                <h2 class="section-title">推荐歌单</h2>
                <div class="playlist-grid">
                    <!-- 歌单项将通过JS动态生成 -->
                </div>
            </section>
            <!-- 新歌速递 -->
            <section class="new-songs">
                <h2 class="section-title">新歌速递</h2>
                <div class="song-list">
                    <!-- 歌曲列表将通过JS动态生成 -->
                </div>
            </section>
            <!-- 排行榜 -->
            <section class="charts">
                <h2 class="section-title">排行榜</h2>
                <div class="charts-container">
                    <!-- 榜单将通过JS动态生成 -->
                </div>
            </section>
        </main>
    </div>
    <!-- 底部播放器 -->
    <footer class="player">
        <div class="player-left">
            <div class="now-playing">
                <img src="https://picsum.photos/seed/nowplaying/50/50.jpg" alt="正在播放" class="song-cover">
                <div class="song-info">
                    <div class="song-name">起风了</div>
                    <div class="artist-name">买辣椒也用券</div>
                </div>
            </div>
        </div>
        <div class="player-center">
            <div class="player-controls">
                <button class="control-btn prev-btn"><i class="fas fa-step-backward"></i></button>
                <button class="control-btn play-btn"><i class="fas fa-play"></i></button>
                <button class="control-btn next-btn"><i class="fas fa-step-forward"></i></button>
            </div>
            <div class="progress-bar">
                <span class="current-time">0:00</span>
                <div class="progress-track">
                    <div class="progress-filled"></div>
                </div>
                <span class="total-time">3:50</span>
            </div>
        </div>
        <div class="player-right">
            <button class="control-btn volume-btn"><i class="fas fa-volume-up"></i></button>
            <div class="volume-bar">
                <div class="volume-track">
                    <div class="volume-filled"></div>
                </div>
            </div>
        </div>
    </footer>
    <script src="js/main.js"></script>
</body>
</html>

第三步:CSS 样式 (css/style.css)

这是页面的“皮肤”,负责布局、颜色、字体和动画,为了保持代码整洁,我们使用了一些CSS变量。

/* 全局样式和变量 */
:root {
    --primary-color: #C20C0C;
    --background-color: #222;
    --sidebar-bg: #000;
    --text-color: #fff;
    --text-secondary: #999;
    --border-color: #282828;
    --hover-bg: #333;
}
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    background-color: var(--background-color);
    color: var(--text-color);
    height: 100vh;
    display: flex;
    flex-direction: column;
}
/* 顶部导航栏 */
.header {
    height: 70px;
    background-color: var(--sidebar-bg);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 20px;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1000;
}
.logo {
    font-size: 24px;
    font-weight: bold;
    color: var(--primary-color);
}
.search-box {
    width: 300px;
    position: relative;
}
.search-box input {
    width: 100%;
    padding: 8px 35px 8px 15px;
    border: none;
    border-radius: 20px;
    background-color: var(--hover-bg);
    color: var(--text-color);
    outline: none;
}
.search-box button {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
}
.header-right a {
    color: var(--text-color);
    text-decoration: none;
    margin-left: 20px;
}
.user-avatar img {
    width: 40px;
    height: 40px;
    border-radius: 50%;
}
/* 主容器 */
.main-container {
    display: flex;
    margin-top: 70px; /* 为固定header留出空间 */
    height: calc(100vh - 70px - 70px); /* 减去header和footer的高度 */
}
/* 侧边栏 */
.sidebar {
    width: 200px;
    background-color: var(--sidebar-bg);
    padding: 20px 0;
    overflow-y: auto;
}
.menu-list {
    list-style: none;
}
.menu-item a {
    display: block;
    padding: 15px 20px;
    color: var(--text-secondary);
    text-decoration: none;
    transition: all 0.3s;
}
.menu-item a:hover, .menu-item.active a {
    color: var(--text-color);
    background-color: var(--hover-bg);
}
区 */
.content {
    flex: 1;
    padding: 20px;
    overflow-y: auto;
    background-color: #121212;
}
.section-title {
    font-size: 20px;
    margin-bottom: 20px;
    font-weight: 500;
}
/* 轮播图 */
.banner {
    position: relative;
    height: 300px;
    margin-bottom: 30px;
    border-radius: 8px;
    overflow: hidden;
}
.banner-slides .slide {
    position: absolute;
    width: 100%;
    height: 100%;
    opacity: 0;
    transition: opacity 1s ease-in-out;
}
.banner-slides .slide.active {
    opacity: 1;
}
.banner-slides img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.banner-dots {
    position: absolute;
    bottom: 15px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 8px;
}
.dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.5);
    cursor: pointer;
}
.dot.active {
    background-color: #fff;
}
/* 推荐歌单 */
.playlist-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 20px;
    margin-bottom: 40px;
}
.playlist-item {
    cursor: pointer;
}
.playlist-item img {
    width: 100%;
    border-radius: 8px;
    margin-bottom: 10px;
}
.playlist-item .play-count {
    font-size: 12px;
    color: var(--text-secondary);
}
/* 新歌速递 */
.song-list {
    display: flex;
    flex-direction: column;
    gap: 15px;
    margin-bottom: 40px;
}
.song-item {
    display: flex;
    align-items: center;
    padding: 10px;
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 0.3s;
}
.song-item:hover {
    background-color: var(--hover-bg);
}
.song-item img {
    width: 60px;
    height: 60px;
    border-radius: 4px;
    margin-right: 15px;
}
.song-item .song-info {
    flex: 1;
}
.song-item .song-name {
    font-size: 16px;
    margin-bottom: 5px;
}
.song-item .artist-name {
    font-size: 13px;
    color: var(--text-secondary);
}
/* 排行榜 */
.charts-container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 20px;
}
.chart-card {
    background-color: var(--hover-bg);
    border-radius: 8px;
    padding: 15px;
}
.chart-card h3 {
    font-size: 16px;
    margin-bottom: 15px;
}
.chart-list {
    list-style: none;
}
.chart-item {
    display: flex;
    align-items: center;
    padding: 8px 0;
    border-bottom: 1px solid var(--border-color);
}
.chart-item .rank {
    width: 25px;
    text-align: center;
    color: var(--text-secondary);
}
.chart-item .rank.top {
    color: var(--primary-color);
    font-weight: bold;
}
.chart-item .song-details {
    flex: 1;
    margin-left: 10px;
}
.chart-item .song-name {
    font-size: 14px;
    margin-bottom: 3px;
}
.chart-item .artist {
    font-size: 12px;
    color: var(--text-secondary);
}
/* 底部播放器 */
.player {
    height: 70px;
    background-color: var(--sidebar-bg);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 20px;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
}
.player-left .now-playing {
    display: flex;
    align-items: center;
}
.song-cover {
    width: 50px;
    height: 50px;
    border-radius: 4px;
    margin-right: 15px;
}
.song-info .song-name {
    font-size: 14px;
    margin-bottom: 3px;
}
.song-info .artist-name {
    font-size: 12px;
    color: var(--text-secondary);
}
.player-center {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0 40px;
}
.player-controls {
    display: flex;
    align-items: center;
    gap: 20px;
    margin-bottom: 10px;
}
.control-btn {
    background: none;
    border: none;
    color: var(--text-color);
    cursor: pointer;
    font-size: 16px;
}
.control-btn.play-btn {
    font-size: 24px;
    color: var(--primary-color);
}
.progress-bar {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 10px;
}
.progress-track {
    flex: 1;
    height: 4px;
    background-color: var(--border-color);
    border-radius: 2px;
    position: relative;
    cursor: pointer;
}
.progress-filled {
    height: 100%;
    background-color: var(--primary-color);
    border-radius: 2px;
    width: 30%; /* 初始进度 */
}
.player-right {
    display: flex;
    align-items: center;
    gap: 10px;
}
.volume-bar {
    width: 100px;
    height: 4px;
    background-color: var(--border-color);
    border-radius: 2px;
    position: relative;
    cursor: pointer;
    display: none; /* 默认隐藏,点击音量图标时显示 */
}
.volume-bar.show {
    display: block;
}
.volume-filled {
    height: 100%;
    background-color: var(--text-color);
    border-radius: 2px;
    width: 70%; /* 初始音量 */
}

第四步:JavaScript 交互 (js/main.js)

这是页面的“大脑”,负责处理用户的点击、播放音乐、切换内容等动态行为。

document.addEventListener('DOMContentLoaded', () => {
    // --- 模拟数据 ---
    const playlists = [
        { id: 1, name: '欧美经典', cover: 'https://picsum.photos/seed/pl1/200/200.jpg', playCount: '120万' },
        { id: 2, name: '华语新歌榜', cover: 'https://picsum.photos/seed/pl2/200/200.jpg', playCount: '98万' },
        { id: 3, name: '轻音乐', cover: 'https://picsum.photos/seed/pl3/200/200.jpg', playCount: '56万' },
        { id: 4, name: '摇滚在路上', cover: 'https://picsum.photos/seed/pl4/200/200.jpg', playCount: '42万' },
        { id: 5, name: '电音派对', cover: 'https://picsum.photos/seed/pl5/200/200.jpg', playCount: '35万' },
        { id: 6, name: '深夜emo', cover: 'https://picsum.photos/seed/pl6/200/200.jpg', playCount: '88万' },
    ];
    const newSongs = [
        { id: 1, name: '起风了', artist: '买辣椒也用券', cover: 'https://picsum.photos/seed/song1/60/60.jpg' },
        { id: 2, name: '漠河舞厅', artist: '柳爽', cover: 'https://picsum.photos/seed/song2/60/60.jpg' },
        { id: 3, name: '错位时空', artist: '艾辰', cover: 'https://picsum.photos/seed/song3/60/60.jpg' },
        { id: 4, name: '星辰大海', artist: '黄霄雲', cover: 'https://picsum.photos/seed/song4/60/60.jpg' },
        { id: 5, name: '孤勇者', artist: '陈奕迅', cover: 'https://picsum.photos/seed/song5/60/60.jpg' },
    ];
    const charts = [
        { id: 1, name: '飙升榜', songs: [
            { rank: 1, name: '错位时空', artist: '艾辰' },
            { rank: 2, name: '星辰大海', artist: '黄霄雲' },
            { rank: 3, name: '孤勇者', artist: '陈奕迅' },
        ]},
        { id: 2, name: '新歌榜', songs: [
            { rank: 1, name: '起风了', artist: '买辣椒也用券' },
            { rank: 2, name: '漠河舞厅', artist: '柳爽' },
            { rank: 3, name: '错位时空', artist: '艾辰' },
        ]},
        { id: 3, name: '原创榜', songs: [
            { rank: 1, name: '起风了', artist: '买辣椒也用券' },
            { rank: 2, name: '漠河舞厅', artist: '柳爽' },
            { rank: 3, name: '星辰大海', artist: '黄霄雲' },
        ]},
    ];
    // --- DOM 元素 ---
    const playlistGrid = document.querySelector('.playlist-grid');
    const songList = document.querySelector('.song-list');
    const chartsContainer = document.querySelector('.charts-container');
    const playBtn = document.querySelector('.play-btn i');
    const prevBtn = document.querySelector('.prev-btn');
    const nextBtn = document.querySelector('.next-btn');
    const progressFilled = document.querySelector('.progress-filled');
    const volumeFilled = document.querySelector('.volume-filled');
    const volumeBar = document.querySelector('.volume-bar');
    const volumeBtn = document.querySelector('.volume-btn');
    // --- 渲染函数 ---
    function renderPlaylists() {
        playlistGrid.innerHTML = playlists.map(p => `
            <div class="playlist-item">
                <img src="${p.cover}" alt="${p.name}">
                <p class="play-count"><i class="fas fa-play"></i> ${p.playCount}</p>
                <p>${p.name}</p>
            </div>
        `).join('');
    }
    function renderNewSongs() {
        songList.innerHTML = newSongs.map(s => `
            <div class="song-item">
                <img src="${s.cover}" alt="${s.name}">
                <div class="song-info">
                    <div class="song-name">${s.name}</div>
                    <div class="artist-name">${s.artist}</div>
                </div>
            </div>
        `).join('');
    }
    function renderCharts() {
        chartsContainer.innerHTML = charts.map(chart => `
            <div class="chart-card">
                <h3>${chart.name}</h3>
                <ul class="chart-list">
                    ${chart.songs.map(s => `
                        <li class="chart-item">
                            <span class="rank ${s.rank <= 3 ? 'top' : ''}">${s.rank}</span>
                            <div class="song-details">
                                <div class="song-name">${s.name}</div>
                                <div class="artist">${s.artist}</div>
                            </div>
                        </li>
                    `).join('')}
                </ul>
            </div>
        `).join('');
    }
    // --- 事件监听器 ---
    // 播放/暂停
    let isPlaying = false;
    playBtn.addEventListener('click', () => {
        isPlaying = !isPlaying;
        playBtn.classList.toggle('fa-play');
        playBtn.classList.toggle('fa-pause');
    });
    // 上一首/下一首
    prevBtn.addEventListener('click', () => {
        console.log('上一首');
        // 这里可以切换歌曲逻辑
    });
    nextBtn.addEventListener('click', () => {
        console.log('下一首');
        // 这里可以切换歌曲逻辑
    });
    // 进度条拖动(简化版)
    let isDragging = false;
    const progressTrack = document.querySelector('.progress-track');
    progressTrack.addEventListener('click', (e) => {
        const rect = progressTrack.getBoundingClientRect();
        const offsetX = e.clientX - rect.left;
        const percentage = (offsetX / rect.width) * 100;
        progressFilled.style.width = `${percentage}%`;
    });
    // 音量控制
    volumeBtn.addEventListener('click', () => {
        volumeBar.classList.toggle('show');
    });
    document.addEventListener('click', (e) => {
        if (!volumeBar.contains(e.target) && !volumeBtn.contains(e.target)) {
            volumeBar.classList.remove('show');
        }
    });
    const volumeTrack = document.querySelector('.volume-track');
    volumeTrack.addEventListener('click', (e) => {
        const rect = volumeTrack.getBoundingClientRect();
        const offsetY = e.clientY - rect.top; // 音量条通常垂直,这里用Y轴
        const percentage = 100 - (offsetY / rect.height) * 100; // 上大下小
        volumeFilled.style.height = `${percentage}%`;
    });
    // --- 初始化页面 ---
    renderPlaylists();
    renderNewSongs();
    renderCharts();
});

最终效果与如何运行

  1. 保存所有文件:确保 index.html, style.css, 和 main.js 文件都保存在正确的目录结构中。
  2. 打开 index.html:直接用浏览器(如 Chrome, Firefox, Edge)打开 netease-music/index.html 文件。

你将看到一个功能齐全的网易云音乐风格网页,包括静态布局和基础的交互功能。

html网易云音乐网页制作
(图片来源网络,侵删)

如何进一步改进?

这个版本是一个很好的起点,你可以继续扩展它:

  • 真实API数据:使用网易云音乐的真实API(需要申请开发者密钥)来获取歌曲、歌单、排行榜等数据,替换掉模拟数据。
  • 播放功能:使用HTML5的 <audio> 标签来实现真正的音乐播放,当用户点击播放按钮或歌曲列表时,加载并播放对应的音频文件。
  • 更复杂的交互:实现歌曲列表点击播放、切换歌曲时更新底部播放器信息、歌词滚动显示等。
  • 响应式设计:使用媒体查询(@media)让网页在手机和平板上也能有良好的显示效果。
  • 动画效果:使用CSS transitionanimation 或 JavaScript 库(如 GSAP)让页面动起来,比如菜单滑入、卡片悬浮效果等。
  • 后端技术:如果需要用户登录、创建歌单、保存播放记录等功能,就需要引入 Node.js, Python (Django/Flask), PHP 等后端技术。

希望这个详细的教程能帮助你成功制作出自己的网易云音乐网页!