开源项目推荐
学习目标
- 精确复刻GitHub搜索结果页面的布局与样式
- 掌握使用Tailwind CSS实现过滤器组件与响应式搜索条
- 实现复杂列表与卡片布局的搜索结果展示
- 学习如何处理高级搜索筛选器与交互元素
- 掌握悬浮状态与微交互样式的实现技巧
页面分析
GitHub的搜索结果页是一个功能丰富的界面,用户可以通过它查找代码、仓库、用户和其他内容。该页面的主要特点包括:
- 顶部搜索条 - 允许用户调整或修改当前搜索
- 左侧过滤面板 - 提供各种筛选选项
- 主要结果区域 - 以列表形式显示搜索结果
- 排序与视图选项 - 允许用户自定义结果显示方式
下面我们将逐步实现这个页面,重点关注其布局结构和视觉样式。
分步实现过程
第一步:创建基础HTML结构
首先,让我们创建基本的HTML结构:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Search Results - GitHub</title>
<!-- 通过CDN引入Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- 引入Heroicons -->
<script src="https://unpkg.com/heroicons@2.0.18/24/outline/esm/index.js"></script>
<!-- 自定义配置以匹配GitHub颜色 -->
<script>
tailwind.config = {
theme: {
extend: {
colors: {
'github-blue': '#0969da',
'github-green': '#2da44e',
'github-red': '#cf222e',
'github-yellow': '#bf8700',
'github-purple': '#8250df',
'github-bg': '#f6f8fa',
'github-border': '#d0d7de',
'github-text': '#24292f',
'github-secondary': '#57606a',
},
}
}
}
</script>
</head>
<body class="bg-white text-github-text min-h-screen flex flex-col">
<!-- 整个页面内容将在这里构建 -->
</body>
</html>
第二步:实现导航栏
导航栏是GitHub界面的重要组成部分,保持了跨页面的一致性:
<header class="bg-white border-b border-github-border sticky top-0 z-10">
<div class="max-w-[1280px] mx-auto px-4 flex items-center justify-between h-16">
<!-- 左侧: Logo和导航 -->
<div class="flex items-center space-x-4">
<!-- GitHub Logo -->
<a href="#" class="text-github-text">
<svg height="32" aria-hidden="true" viewBox="0 0 16 16" version="1.1" width="32" class="fill-current">
<path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"></path>
</svg>
</a>
<!-- 导航链接 -->
<nav class="hidden md:flex space-x-4">
<a href="#" class="text-sm font-medium hover:text-github-blue">Pull requests</a>
<a href="#" class="text-sm font-medium hover:text-github-blue">Issues</a>
<a href="#" class="text-sm font-medium hover:text-github-blue">Codespaces</a>
<a href="#" class="text-sm font-medium hover:text-github-blue">Marketplace</a>
<a href="#" class="text-sm font-medium hover:text-github-blue">Explore</a>
</nav>
</div>
<!-- 右侧: 通知和个人资料 -->
<div class="flex items-center space-x-4">
<!-- 通知铃铛 -->
<button class="text-github-secondary hover:text-github-text">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0" />
</svg>
</button>
<!-- 创建新内容的加号按钮 -->
<div class="relative group">
<button class="text-github-secondary hover:text-github-text flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
</svg>
</button>
</div>
<!-- 用户头像 -->
<div class="relative group">
<button class="flex items-center">
<img src="https://github.com/identicons/user.png" alt="User avatar" class="w-5 h-5 rounded-full">
</button>
</div>
</div>
</div>
</header>
第三步:实现搜索头部区域
接下来,我们添加搜索结果页面顶部的搜索条和过滤标签:
<div class="bg-white border-b border-github-border">
<div class="max-w-[1280px] mx-auto px-4 py-4">
<!-- 搜索框 -->
<div class="relative mb-4">
<div class="flex items-center border border-github-border rounded-md bg-white overflow-hidden pr-3">
<input type="text" value="tailwind css" class="flex-grow px-3 py-1.5 text-sm outline-none" placeholder="Search GitHub">
<button class="flex items-center justify-center text-xs font-medium border border-github-border rounded-md px-3 py-1 ml-2 hover:bg-github-bg">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3 h-3 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M3 7.5L7.5 3m0 0L12 7.5M7.5 3v13.5m13.5 0L16.5 21m0 0L12 16.5m4.5 4.5V7.5" />
</svg>
Filters
</button>
<button class="ml-2 text-sm text-github-blue hover:underline">
Advanced
</button>
</div>
</div>
<!-- 过滤标签 -->
<div class="flex flex-wrap items-center mb-3">
<a href="#" class="flex items-center text-sm font-semibold text-github-text bg-github-bg border border-github-border rounded-full px-3 py-0.5 mr-2 mb-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1 text-github-secondary">
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
</svg>
Repositories
</a>
<a href="#" class="flex items-center text-sm text-github-secondary hover:text-github-text px-3 py-0.5 mr-2 mb-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M14.25 9.75L16.5 12l-2.25 2.25m-4.5 0L7.5 12l2.25-2.25M6 20.25h12A2.25 2.25 0 0020.25 18V6A2.25 2.25 0 0018 3.75H6A2.25 2.25 0 003.75 6v12A2.25 2.25 0 006 20.25z" />
</svg>
Code
</a>
<a href="#" class="flex items-center text-sm text-github-secondary hover:text-github-text px-3 py-0.5 mr-2 mb-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z" />
</svg>
Users
</a>
<a href="#" class="flex items-center text-sm text-github-secondary hover:text-github-text px-3 py-0.5 mr-2 mb-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 002.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 00-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z" />
</svg>
Issues
</a>
<a href="#" class="flex items-center text-sm text-github-secondary hover:text-github-text px-3 py-0.5 mr-2 mb-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15m0-3l-3-3m0 0l-3 3m3-3V15" />
</svg>
Pull requests
</a>
<a href="#" class="flex items-center text-sm text-github-secondary hover:text-github-text px-3 py-0.5 mr-2 mb-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.59 14.37a6 6 0 01-5.84 7.38v-4.8m5.84-2.58a14.98 14.98 0 006.16-12.12A14.98 14.98 0 009.631 8.41m5.96 5.96a14.926 14.926 0 01-5.841 2.58m-.119-8.54a6 6 0 00-7.381 5.84h4.8m2.581-5.84a14.927 14.927 0 00-2.58 5.84m2.699 2.7c-.103.021-.207.041-.311.06a15.09 15.09 0 01-2.448-2.448 14.9 14.9 0 01.06-.312m-2.24 2.39a4.493 4.493 0 00-1.757 4.306 4.493 4.493 0 004.306-1.758M16.5 9a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0z" />
</svg>
Discussions
</a>
<a href="#" class="flex items-center text-sm text-github-secondary hover:text-github-text px-3 py-0.5 mr-2 mb-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125" />
</svg>
Packages
</a>
<a href="#" class="flex items-center text-sm text-github-secondary hover:text-github-text px-3 py-0.5 mr-2 mb-2">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 7.5l3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0021 18V6a2.25 2.25 0 00-2.25-2.25H5.25A2.25 2.25 0 003 6v12a2.25 2.25 0 002.25 2.25z" />
</svg>
Wikis
</a>
</div>
<!-- 搜索状态 -->
<div class="text-sm text-github-secondary">
<span class="font-semibold text-github-text">3,576</span> repository results for <span class="font-semibold text-github-text">tailwind css</span>
</div>
</div>
</div>
第四步:创建主内容区域布局
现在,我们将创建主内容区的两栏布局,包括左侧过滤器和右侧结果列表:
<main class="flex-grow">
<div class="max-w-[1280px] mx-auto px-4 py-6">
<div class="flex flex-col md:flex-row gap-6">
<!-- 左侧过滤器面板 -->
<div class="w-full md:w-64 shrink-0">
<!-- 左侧过滤器内容将在下一步添加 -->
</div>
<!-- 右侧搜索结果 -->
<div class="flex-grow">
<!-- 搜索结果内容将在后续步骤添加 -->
</div>
</div>
</div>
</main>
第五步:实现左侧过滤器面板
接下来,我们填充左侧过滤器面板的内容:
<!-- 左侧过滤器面板 -->
<div class="w-full md:w-64 shrink-0">
<!-- 语言过滤器 -->
<div class="mb-6">
<h3 class="text-sm font-semibold mb-2">Languages</h3>
<div class="space-y-2">
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>JavaScript</span>
<span class="text-github-secondary">1.2k</span>
</a>
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>TypeScript</span>
<span class="text-github-secondary">845</span>
</a>
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>CSS</span>
<span class="text-github-secondary">763</span>
</a>
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>HTML</span>
<span class="text-github-secondary">421</span>
</a>
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>Vue</span>
<span class="text-github-secondary">389</span>
</a>
<a href="#" class="flex items-center justify-between text-sm text-github-blue font-medium">
<span>See more</span>
</a>
</div>
</div>
<!-- 主题过滤器 -->
<div class="mb-6">
<h3 class="text-sm font-semibold mb-2">Topics</h3>
<div class="space-y-2">
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>tailwindcss</span>
<span class="text-github-secondary">1.5k</span>
</a>
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>ui</span>
<span class="text-github-secondary">743</span>
</a>
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>components</span>
<span class="text-github-secondary">562</span>
</a>
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>react</span>
<span class="text-github-secondary">498</span>
</a>
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>design-system</span>
<span class="text-github-secondary">327</span>
</a>
<a href="#" class="flex items-center justify-between text-sm text-github-blue font-medium">
<span>See more</span>
</a>
</div>
</div>
<!-- 许可证过滤器 -->
<div class="mb-6">
<h3 class="text-sm font-semibold mb-2">License</h3>
<div class="space-y-2">
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>MIT</span>
<span class="text-github-secondary">1.8k</span>
</a>
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>Apache-2.0</span>
<span class="text-github-secondary">293</span>
</a>
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>ISC</span>
<span class="text-github-secondary">174</span>
</a>
<a href="#" class="flex items-center justify-between text-sm hover:text-github-blue">
<span>GNU GPL v3.0</span>
<span class="text-github-secondary">98</span>
</a>
<a href="#" class="flex items-center justify-between text-sm text-github-blue font-medium">
<span>See more</span>
</a>
</div>
</div>
<!-- 高级过滤器 -->
<div class="mb-6">
<details class="cursor-pointer group">
<summary class="text-sm font-semibold flex items-center mb-2 hover:cursor-pointer">
<span>More options</span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3.5 h-3.5 ml-1 transition-transform group-open:rotate-180">
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
</svg>
</summary>
<div class="space-y-2 mt-2">
<div class="flex items-center mb-2">
<input type="checkbox" id="archived" class="h-4 w-4 rounded border-github-border text-github-blue focus:ring-github-blue">
<label for="archived" class="ml-2 text-sm">Include archived</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="mirror" class="h-4 w-4 rounded border-github-border text-github-blue focus:ring-github-blue">
<label for="mirror" class="ml-2 text-sm">Include mirrors</label>
</div>
</div>
</details>
</div>
</div>
第六步:实现结果控制和排序选项
添加结果列表的排序和控制选项:
<!-- 右侧搜索结果 -->
<div class="flex-grow">
<!-- 排序与视图控制 -->
<div class="flex flex-wrap items-center justify-between pb-3 mb-4 border-b border-github-border">
<div class="flex items-center space-x-2 mb-2 sm:mb-0">
<button class="inline-flex items-center text-sm px-2 py-1 rounded-md border border-github-border bg-github-bg hover:bg-gray-100">
<span>Sort</span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3.5 h-3.5 ml-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
</svg>
</button>
</div>
<div class="flex items-center border border-github-border rounded-md overflow-hidden">
<button class="flex items-center justify-center bg-github-bg text-github-text p-1.5 hover:bg-gray-100 border-r border-github-border">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 6.75h12M8.25 12h12m-12 5.25h12M3.75 6.75h.007v.008H3.75V6.75zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zM3.75 12h.007v.008H3.75V12zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0zm-.375 5.25h.007v.008H3.75v-.008zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" />
</svg>
</button>
<button class="flex items-center justify-center p-1.5 hover:bg-gray-100">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
</svg>
</button>
</div>
</div>
<!-- 搜索结果列表 -->
<div class="space-y-4">
<!-- 搜索结果项 1 -->
<div class="p-4 border border-github-border rounded-md hover:bg-github-bg">
<div class="flex items-start justify-between mb-1">
<div class="flex items-center">
<a href="#" class="text-github-blue font-semibold hover:underline">tailwindlabs/tailwindcss</a>
<span class="ml-2 px-1.5 py-0.5 text-xs font-medium rounded-full bg-yellow-100 text-yellow-800">Public</span>
</div>
<button class="flex items-center text-github-secondary hover:text-github-text bg-github-bg hover:bg-gray-100 rounded-md px-3 py-1 border border-github-border text-sm">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" />
</svg>
Star
</button>
</div>
<p class="text-sm text-github-secondary mb-3">
A utility-first CSS framework for rapid UI development.
</p>
<div class="flex flex-wrap items-center text-xs text-github-secondary">
<div class="flex items-center mr-4 mb-1">
<span class="w-3 h-3 rounded-full bg-indigo-500 mr-1"></span>
CSS
</div>
<div class="flex items-center mr-4 mb-1">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3.5 h-3.5 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" />
</svg>
70.4k
</div>
<div class="flex items-center mr-4 mb-1">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3.5 h-3.5 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M7.217 10.907a2.25 2.25 0 100 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186l9.566-5.314m-9.566 7.5l9.566 5.314m0 0a2.25 2.25 0 103.935 2.186 2.25 2.25 0 00-3.935-2.186zm0-12.814a2.25 2.25 0 103.933-2.185 2.25 2.25 0 00-3.933 2.185z" />
</svg>
3.8k
</div>
<div class="flex items-center mb-1">
Updated 2 days ago
</div>
</div>
</div>
<!-- 搜索结果项 2 -->
<div class="p-4 border border-github-border rounded-md hover:bg-github-bg">
<div class="flex items-start justify-between mb-1">
<div class="flex items-center">
<a href="#" class="text-github-blue font-semibold hover:underline">themesberg/flowbite-react</a>
<span class="ml-2 px-1.5 py-0.5 text-xs font-medium rounded-full bg-yellow-100 text-yellow-800">Public</span>
</div>
<button class="flex items-center text-github-secondary hover:text-github-text bg-github-bg hover:bg-gray-100 rounded-md px-3 py-1 border border-github-border text-sm">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" />
</svg>
Star
</button>
</div>
<p class="text-sm text-github-secondary mb-3">
React components built with Tailwind CSS for faster UI development
</p>
<div class="flex flex-wrap items-center text-xs text-github-secondary">
<div class="flex items-center mr-4 mb-1">
<span class="w-3 h-3 rounded-full bg-blue-500 mr-1"></span>
TypeScript
</div>
<div class="flex items-center mr-4 mb-1">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3.5 h-3.5 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" />
</svg>
2.5k
</div>
<div class="flex items-center mr-4 mb-1">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3.5 h-3.5 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M7.217 10.907a2.25 2.25 0 100 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186l9.566-5.314m-9.566 7.5l9.566 5.314m0 0a2.25 2.25 0 103.935 2.186 2.25 2.25 0 00-3.935-2.186zm0-12.814a2.25 2.25 0 103.933-2.185 2.25 2.25 0 00-3.933 2.185z" />
</svg>
428
</div>
<div class="flex items-center mb-1">
Updated 3 days ago
</div>
</div>
</div>
<!-- 搜索结果项 3 -->
<div class="p-4 border border-github-border rounded-md hover:bg-github-bg">
<div class="flex items-start justify-between mb-1">
<div class="flex items-center">
<a href="#" class="text-github-blue font-semibold hover:underline">tailwindlabs/tailwindui-react</a>
<span class="ml-2 px-1.5 py-0.5 text-xs font-medium rounded-full bg-yellow-100 text-yellow-800">Public</span>
</div>
<button class="flex items-center text-github-secondary hover:text-github-text bg-github-bg hover:bg-gray-100 rounded-md px-3 py-1 border border-github-border text-sm">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" />
</svg>
Star
</button>
</div>
<p class="text-sm text-github-secondary mb-3">
React components from Tailwind UI, the official Tailwind CSS components library.
</p>
<div class="flex flex-wrap items-center text-xs text-github-secondary">
<div class="flex items-center mr-4 mb-1">
<span class="w-3 h-3 rounded-full bg-yellow-500 mr-1"></span>
JavaScript
</div>
<div class="flex items-center mr-4 mb-1">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3.5 h-3.5 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" />
</svg>
1.7k
</div>
<div class="flex items-center mr-4 mb-1">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3.5 h-3.5 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M7.217 10.907a2.25 2.25 0 100 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186l9.566-5.314m-9.566 7.5l9.566 5.314m0 0a2.25 2.25 0 103.935 2.186 2.25 2.25 0 00-3.935-2.186zm0-12.814a2.25 2.25 0 103.933-2.185 2.25 2.25 0 00-3.933 2.185z" />
</svg>
293
</div>
<div class="flex items-center mb-1">
Updated 1 week ago
</div>
</div>
</div>
<!-- 搜索结果项 4 -->
<div class="p-4 border border-github-border rounded-md hover:bg-github-bg">
<div class="flex items-start justify-between mb-1">
<div class="flex items-center">
<a href="#" class="text-github-blue font-semibold hover:underline">tw-elements/tw-elements</a>
<span class="ml-2 px-1.5 py-0.5 text-xs font-medium rounded-full bg-yellow-100 text-yellow-800">Public</span>
</div>
<button class="flex items-center text-github-secondary hover:text-github-text bg-github-bg hover:bg-gray-100 rounded-md px-3 py-1 border border-github-border text-sm">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" />
</svg>
Star
</button>
</div>
<p class="text-sm text-github-secondary mb-3">
Tailwind Elements is a powerful UI kit library with over 600+ components for TailwindCSS.
</p>
<div class="flex flex-wrap items-center text-xs text-github-secondary">
<div class="flex items-center mr-4 mb-1">
<span class="w-3 h-3 rounded-full bg-yellow-500 mr-1"></span>
JavaScript
</div>
<div class="flex items-center mr-4 mb-1">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3.5 h-3.5 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.563.563 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.563.563 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z" />
</svg>
1.4k
</div>
<div class="flex items-center mr-4 mb-1">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3.5 h-3.5 mr-1">
<path stroke-linecap="round" stroke-linejoin="round" d="M7.217 10.907a2.25 2.25 0 100 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186l9.566-5.314m-9.566 7.5l9.566 5.314m0 0a2.25 2.25 0 103.935 2.186 2.25 2.25 0 00-3.935-2.186zm0-12.814a2.25 2.25 0 103.933-2.185 2.25 2.25 0 00-3.933 2.185z" />
</svg>
254
</div>
<div class="flex items-center mb-1">
Updated 4 days ago
</div>
</div>
</div>
</div>
<!-- 分页控制 -->
<div class="flex items-center justify-center mt-8">
<nav class="inline-flex items-center">
<a href="#" class="px-3 py-1 rounded-l-md border border-github-border bg-white hover:bg-github-bg text-github-secondary disabled:opacity-50 disabled:cursor-not-allowed">
Previous
</a>
<a href="#" class="px-3 py-1 border-t border-b border-github-border bg-github-blue text-white hover:bg-blue-700">
1
</a>
<a href="#" class="px-3 py-1 border-t border-b border-github-border bg-white hover:bg-github-bg text-github-secondary">
2
</a>
<a href="#" class="px-3 py-1 border-t border-b border-github-border bg-white hover:bg-github-bg text-github-secondary">
3
</a>
<span class="px-3 py-1 border-t border-b border-github-border bg-white text-github-secondary">
...
</span>
<a href="#" class="px-3 py-1 border-t border-b border-github-border bg-white hover:bg-github-bg text-github-secondary">
20
</a>
<a href="#" class="px-3 py-1 rounded-r-md border border-github-border bg-white hover:bg-github-bg text-github-secondary">
Next
</a>
</nav>
</div>
</div>
第七步:添加页脚
最后,我们添加一个简单的页脚来完成页面:
<footer class="bg-white border-t border-github-border py-8 mt-12">
<div class="max-w-[1280px] mx-auto px-4">
<div class="flex flex-col md:flex-row justify-between items-center">
<div class="flex items-center space-x-1 text-xs text-github-secondary mb-4 md:mb-0">
<span>© 2023 GitHub, Inc.</span>
<span>•</span>
<a href="#" class="hover:text-github-blue hover:underline">Terms</a>
<span>•</span>
<a href="#" class="hover:text-github-blue hover:underline">Privacy</a>
<span>•</span>
<a href="#" class="hover:text-github-blue hover:underline">Security</a>
<span>•</span>
<a href="#" class="hover:text-github-blue hover:underline">Status</a>
<span>•</span>
<a href="#" class="hover:text-github-blue hover:underline">Docs</a>
</div>
<div class="flex items-center">
<a href="#" class="text-github-secondary hover:text-github-text">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0112 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 013 12c0-1.605.42-3.113 1.157-4.418" />
</svg>
</a>
</div>
</div>
</div>
</footer>
关键样式技术点解析
下面我们来解析在实现GitHub搜索结果页面时使用的几个重要Tailwind CSS技术点:
1. 响应式设计实现
GitHub的搜索结果页面在不同设备上有不同的布局。我们通过Tailwind的响应式前缀实现了这一点:
<div class="flex flex-col md:flex-row gap-6">
上面的代码在移动设备上使用列布局(flex-col
),而在中等尺寸及以上设备(md:
前缀,≥768px)上切换为行布局。这样可以确保在小屏幕上内容垂直排列,而在大屏幕上采用两栏布局。
2. 精确间距控制
GitHub界面以精确的间距控制著称。我们使用Tailwind的间距工具类(padding、margin、gap等)来精确复刻:
<div class="p-4 border border-github-border rounded-md hover:bg-github-bg">
上述代码为搜索结果项提供了统一的内边距(p-4
,等于1rem或16px)和边框样式。
3. 悬停状态处理
GitHub的交互元素(如链接、按钮)通常有悬停效果。使用Tailwind的hover:
前缀可以轻松实现:
<a href="#" class="text-github-secondary hover:text-github-blue hover:underline">
当用户将鼠标悬停在链接上时,文本颜色会变成GitHub的蓝色,并显示下划线。
4. 自定义颜色配置
为了精确匹配GitHub的品牌色,我们通过Tailwind的配置扩展了颜色系统:
tailwind.config = {
theme: {
extend: {
colors: {
'github-blue': '#0969da',
'github-green': '#2da44e',
// 其他颜色...
},
}
}
}
这样,我们可以在整个页面中使用这些自定义颜色,确保界面与GitHub保持一致。
5. 组状态控制
使用group
和group-open:
前缀来控制组件的状态变化:
<details class="cursor-pointer group">
<summary class="text-sm font-semibold flex items-center mb-2 hover:cursor-pointer">
<span>More options</span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-3.5 h-3.5 ml-1 transition-transform group-open:rotate-180">
<!-- ... -->
</svg>
</summary>
<!-- ... -->
</details>
在这个例子中,我们使用group
和group-open:rotate-180
来控制当details
元素打开时箭头图标旋转180度的动画效果。
6. 使用Flex布局实现复杂对齐
GitHub界面大量使用了灵活的布局结构。通过Tailwind的Flex相关类,我们可以轻松实现:
<div class="flex items-center justify-between pb-3 mb-4 border-b border-github-border">
上述代码创建了一个弹性容器,其中的项目垂直居中(items-center
)并水平两端对齐(justify-between
)。
常见问题与解决方案
问题1: 移动设备下的视图切换
问题: 在移动设备上,两栏布局变得不适合阅读。
解决方案: 使用Tailwind的响应式前缀,在移动设备上将布局改为单列:
<div class="flex flex-col md:flex-row gap-6">
<!-- 左侧过滤器 -->
<div class="w-full md:w-64 shrink-0">
<!-- ... -->
</div>
<!-- 右侧结果 -->
<div class="flex-grow">
<!-- ... -->
</div>
</div>
在移动设备上,过滤器面板和结果列表会垂直堆叠,而在中等尺寸及以上设备上则显示为两栏布局。
问题2: 图标处理和一致性
问题: 如何确保所有图标具有一致的大小和样式?
解决方案: 为所有图标添加统一的尺寸类,并使用currentColor
来继承文本颜色:
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 mr-1">
<!-- ... -->
</svg>
所有图标使用相同的宽度和高度类(w-4 h-4
,等于1rem或16px),并通过currentColor
自动适应父元素的文本颜色。
问题3: 复杂选择器的处理
问题: GitHub的分页控制有复杂的边框处理,如何使用Tailwind实现?
解决方案: 分解为多个独立组件,并分别应用边框样式:
<nav class="inline-flex items-center">
<a href="#" class="px-3 py-1 rounded-l-md border border-github-border...">Previous</a>
<a href="#" class="px-3 py-1 border-t border-b border-github-border...">1</a>
<a href="#" class="px-3 py-1 border-t border-b border-github-border...">2</a>
<!-- ... -->
<a href="#" class="px-3 py-1 rounded-r-md border border-github-border...">Next</a>
</nav>
我们为第一个和最后一个按钮应用了独特的样式(圆角和完整边框),而中间的按钮只有上、下和对应的左/右边框。
扩展与练习建议
练习1: 过滤器交互增强
尝试为过滤器选项添加交互行为,如点击”Languages”中的一个选项后,实现选中状态(加粗文本,添加背景色)和计数调整。
<!-- 选中状态示例 -->
<a href="#" class="flex items-center justify-between text-sm font-semibold bg-blue-50 text-github-blue hover:bg-blue-100 px-2 py-1 rounded-md">
<span>JavaScript</span>
<span>1.2k</span>
</a>
练习2: 添加搜索过滤器下拉菜单
实现搜索框旁边的”Filters”按钮点击后显示的下拉过滤菜单,包含各种高级过滤选项。
<div class="absolute right-0 top-full mt-2 w-64 bg-white border border-github-border rounded-md shadow-lg z-20">
<div class="p-3">
<h3 class="text-sm font-semibold mb-2">Filter repositories</h3>
<!-- 过滤选项 -->
</div>
</div>
练习3: 实现响应式导航
改进导航栏,在移动设备上将主导航链接折叠为一个汉堡菜单按钮。
<!-- 汉堡菜单按钮 -->
<button class="md:hidden">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
</svg>
</button>
<!-- 折叠菜单 -->
<div class="hidden md:flex">
<!-- 导航链接 -->
</div>
练习4: 添加暗黑模式支持
为搜索结果页面添加暗黑模式支持,遵循GitHub的暗黑模式颜色方案。
<!-- 在配置中添加暗黑模式颜色 -->
<script>
tailwind.config = {
theme: {
extend: {
colors: {
// 明亮模式颜色...
dark: {
'github-bg': '#0d1117',
'github-border': '#30363d',
'github-text': '#c9d1d9',
'github-secondary': '#8b949e',
// 其他暗黑模式颜色...
}
},
}
}
}
</script>
<!-- 使用暗黑模式类 -->
<div class="bg-white dark:bg-dark-github-bg text-github-text dark:text-dark-github-text">
<!-- 内容... -->
</div>
练习5: 优化移动用户体验
改进搜索结果在移动设备上的显示方式,考虑添加一个固定位置的过滤器切换按钮,让用户能够快速访问过滤选项。
<!-- 移动设备过滤器切换按钮 -->
<div class="fixed bottom-4 right-4 md:hidden">
<button class="flex items-center justify-center bg-github-blue text-white rounded-full w-12 h-12 shadow-lg">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 01-1.995 2.23l-.001.001c-.887.157-1.786.287-2.704.384 3.318 1.31 5.7 4.535 5.7 8.317v.5c0 2.043-.538 4-3 4-2.086 0-5.03-.706-8.283-1.024A2.8 2.8 0 009 21.75a5.25 5.25 0 01-3-9l1.024-.61-1.024-.61a5.25 5.25 0 013-9 2.8 2.8 0 00.92-.024z" />
</svg>
</button>
</div>
总结
在这一节中,我们详细学习了如何使用Tailwind CSS来复刻GitHub的搜索结果页面。通过拆解页面结构、分析关键组件,并逐步实现,我们成功构建了一个外观与功能都相似的界面。
主要学习要点包括:
- 响应式布局结构 - 使用Tailwind的响应式前缀在不同设备上提供合适的布局
- GitHub组件模式 - 了解GitHub界面常用的组件结构和样式模式
- 交互状态处理 - 通过
hover:
、focus:
和group-*
等状态修饰符实现交互效果 - 自定义颜色系统 - 如何配置和使用符合GitHub品牌的颜色方案
- 精确的间距控制 - 使用Tailwind的间距工具类精确复刻GitHub的视觉层次
搜索结果页面是GitHub中最常用的功能之一,它综合了多种UI组件和模式。通过本节的学习,你不仅能够理解如何实现这个特定页面,还能够掌握这些组件和技术应用到其他GitHub页面或你自己的项目中的方法。
在下一章中,我们将继续深入学习GitHub的核心功能页面,如仓库详情页、代码查看页等更加复杂的界面实现。