第二章:基础页面实现 - 第二节:用户主页 - 个人资料与活动流

学习目标

  • 分析GitHub用户主页的布局结构和组件
  • 使用Tailwind CSS实现个人资料侧边栏的复杂布局
  • 构建活动流时间线及其各种卡片类型
  • 实现响应式设计,确保在移动设备上的良好体验
  • 掌握GitHub主页的交互设计模式

GitHub用户主页分析

GitHub的用户主页是展示个人资料和活动的核心页面。它包含丰富的信息和交互元素,主要分为两大部分:左侧的个人资料侧边栏和右侧的活动流时间线。

主要区域和功能

  1. 顶部导航栏(复用前一节的设计)
  2. 个人资料侧边栏(头像、名称、简介、统计数据等)
  3. 活动流时间线(提交、Issues、PR等活动)
  4. 贡献图表(活动热力图)
  5. 仓库列表(置顶仓库)

让我们逐步构建这个页面,先从页面的基本结构开始。

页面基本结构

首先,创建页面的HTML框架和Tailwind CSS配置:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>GitHub User Profile</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <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-primary": "#24292f",
            "github-text-secondary": "#57606a",
            "github-header-bg": "#24292f",
            "github-header-text": "#ffffff",
            "github-btn-primary": "#2da44e",
            "github-btn-primary-hover": "#2c974b",
          },
          fontFamily: {
            "github": [
              "-apple-system", 
              "BlinkMacSystemFont", 
              "Segoe UI", 
              "Noto Sans", 
              "Helvetica", 
              "Arial", 
              "sans-serif", 
              "Apple Color Emoji", 
              "Segoe UI Emoji"
            ],
          },
          borderRadius: {
            "github-md": "6px",
          },
          boxShadow: {
            "github-sm": "0 1px 0 rgba(27, 31, 36, 0.04)",
            "github-btn": "0 1px 0 rgba(27, 31, 36, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.25)",
          }
        }
      }
    }
  </script>
</head>
<body class="bg-white font-github text-github-text-primary">
  <!-- GitHub Header/Navbar -->
  <header class="bg-github-header-bg text-github-header-text py-3 px-4 flex items-center justify-between">
    <!-- GitHub Logo -->
    <div class="flex items-center">
      <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>
      
      <!-- Search bar -->
      <div class="relative ml-4 hidden md:block">
        <input type="text" placeholder="Search or jump to..." 
          class="bg-github-header-bg border border-gray-600 rounded-md text-sm text-white placeholder-gray-400 w-64 py-1 px-3">
      </div>
    </div>
    
    <!-- Navigation links -->
    <nav class="hidden md:flex items-center space-x-4">
      <a href="#" class="text-white hover:text-gray-300">Pull requests</a>
      <a href="#" class="text-white hover:text-gray-300">Issues</a>
      <a href="#" class="text-white hover:text-gray-300">Marketplace</a>
      <a href="#" class="text-white hover:text-gray-300">Explore</a>
    </nav>
    
    <!-- User menu -->
    <div class="flex items-center">
      <!-- Notifications icon -->
      <a href="#" class="text-white mr-4">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
          <path d="M8 16a2 2 0 0 0 1.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 0 0 8 16ZM3 5a5 5 0 0 1 10 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.519 1.519 0 0 1 13.482 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947Zm5-3.5A3.5 3.5 0 0 0 4.5 5v2.947c0 .346-.102.683-.294.97l-1.703 2.556a.017.017 0 0 0-.003.01l.001.006c0 .002.002.004.004.006l.006.004.007.001h10.964l.007-.001.006-.004.004-.006.001-.007a.017.017 0 0 0-.003-.01l-1.703-2.554a1.745 1.745 0 0 1-.294-.97V5A3.5 3.5 0 0 0 8 1.5Z"></path>
        </svg>
      </a>
      
      <!-- User avatar dropdown -->
      <div class="relative">
        <button class="flex items-center">
          <img src="https://avatars.githubusercontent.com/u/123456789?v=4" alt="User avatar" class="w-5 h-5 rounded-full">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="ml-1 text-white">
            <path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path>
          </svg>
        </button>
      </div>
    </div>
  </header>

  <!-- Main Content Area -->
  <main class="container mx-auto px-4 py-6 max-w-7xl">
    <!-- Two-column layout will go here -->
    <div class="flex flex-col md:flex-row gap-6">
      <!-- Left sidebar: User profile -->
      <div class="w-full md:w-1/4">
        <!-- Profile content will go here -->
      </div>
      
      <!-- Right content: Activity feed -->
      <div class="w-full md:w-3/4">
        <!-- Activity feed will go here -->
      </div>
    </div>
  </main>
</body>
</html>

个人资料侧边栏实现

接下来,让我们实现左侧的个人资料侧边栏:

<!-- Left sidebar: User profile -->
<div class="w-full md:w-1/4">
  <!-- Profile picture -->
  <div class="mb-4">
    <div class="relative group">
      <div class="rounded-full overflow-hidden border border-github-border">
        <img src="https://avatars.githubusercontent.com/u/123456789?v=4" alt="User avatar" class="w-full">
      </div>
      <div class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-50 rounded-full opacity-0 group-hover:opacity-100 transition-opacity">
        <span class="text-white">😄</span>
      </div>
    </div>
  </div>
  
  <!-- Name and username -->
  <div class="mb-4">
    <h1 class="text-2xl font-bold">John Doe</h1>
    <p class="text-github-text-secondary">johndoe</p>
  </div>
  
  <!-- Bio -->
  <div class="mb-4">
    <p>
      Software developer passionate about web technologies and open source. Building tools to make developers' lives easier.
    </p>
  </div>
  
  <!-- Edit profile button -->
  <div class="mb-4">
    <button class="w-full py-1 px-3 text-sm bg-github-bg border border-github-border rounded-github-md hover:bg-gray-100 font-medium">
      Edit profile
    </button>
  </div>
  
  <!-- Followers info -->
  <div class="mb-4 flex items-center text-sm">
    <a href="#" class="flex items-center hover:text-github-blue">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="mr-1 text-github-text-secondary">
        <path d="M2 5.5a3.5 3.5 0 1 1 5.898 2.549 5.508 5.508 0 0 1 3.034 4.084.75.75 0 1 1-1.482.235 4 4 0 0 0-7.9 0 .75.75 0 0 1-1.482-.236A5.507 5.507 0 0 1 3.102 8.05 3.493 3.493 0 0 1 2 5.5ZM11 4a3.001 3.001 0 0 1 2.22 5.018 5.01 5.01 0 0 1 2.56 3.012.749.749 0 0 1-.885.954.752.752 0 0 1-.549-.514 3.507 3.507 0 0 0-2.522-2.372.75.75 0 0 1-.574-.73v-.352a.75.75 0 0 1 .416-.672A1.5 1.5 0 0 0 11 5.5.75.75 0 0 1 11 4Zm-5.5-.5a2 2 0 1 0-.001 3.999A2 2 0 0 0 5.5 3.5Z"></path>
      </svg>
      <span class="font-bold">128</span>&nbsp;followers
    </a>
    <span class="mx-1">·</span>
    <a href="#" class="hover:text-github-blue">
      <span class="font-bold">56</span>&nbsp;following
    </a>
  </div>
  
  <!-- Contact and details -->
  <div class="mb-6">
    <ul class="space-y-1 text-sm">
      <!-- Company -->
      <li class="flex items-center">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="mr-2 text-github-text-secondary">
          <path d="M1.5 14.25c0 .138.112.25.25.25H4v-1.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 .75.75v1.25h2.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM3 3h4v2H3Zm0 3h4v2H3Zm5-3h2v2H8Zm0 3h2v2H8ZM3 9h2v2H3Zm3 0h2v2H6Zm3 0h2v2H9Z"></path>
        </svg>
        <span>Awesome Tech Inc.</span>
      </li>
      
      <!-- Location -->
      <li class="flex items-center">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="mr-2 text-github-text-secondary">
          <path d="m12.596 11.596-3.535 3.536a1.5 1.5 0 0 1-2.122 0l-3.535-3.536a6.5 6.5 0 1 1 9.192-9.193 6.5 6.5 0 0 1 0 9.193Zm-1.06-8.132v-.001a5 5 0 1 0-7.072 7.072L8 14.07l3.536-3.534a5 5 0 0 0 0-7.072ZM8 9a2 2 0 1 1 0-4 2 2 0 0 1 0 4Z"></path>
        </svg>
        <span>San Francisco, CA</span>
      </li>
      
      <!-- Website -->
      <li class="flex items-center">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="mr-2 text-github-text-secondary">
          <path d="M7.775 3.275a.75.75 0 0 0 1.06 1.06l1.25-1.25a2 2 0 1 1 2.83 2.83l-2.5 2.5a2 2 0 0 1-2.83 0 .75.75 0 0 0-1.06 1.06 3.5 3.5 0 0 0 4.95 0l2.5-2.5a3.5 3.5 0 0 0-4.95-4.95l-1.25 1.25Zm-4.69 9.64a2 2 0 0 1 0-2.83l2.5-2.5a2 2 0 0 1 2.83 0 .75.75 0 0 0 1.06-1.06 3.5 3.5 0 0 0-4.95 0l-2.5 2.5a3.5 3.5 0 0 0 4.95 4.95l1.25-1.25a.75.75 0 0 0-1.06-1.06l-1.25 1.25a2 2 0 0 1-2.83 0Z"></path>
        </svg>
        <a href="#" class="text-github-blue hover:underline">johndoe.dev</a>
      </li>
      
      <!-- Twitter -->
      <li class="flex items-center">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="mr-2 text-github-text-secondary">
          <path d="M8.38 14.408 8 14.376l-.38.033a7.25 7.25 0 0 1-6.212-3.287l-.117-.168-.023-.436a7.316 7.316 0 0 1 2.857-6.358 7.221 7.221 0 0 1 3.877-1.132l.006 1.44-.466.055a5.313 5.313 0 0 0-2.86.984A5.275 5.275 0 0 0 2.74 9.166a5.225 5.225 0 0 0 4.266 3.593 5.279 5.279 0 0 0 4.897-1.49l-1.204-1.225a3.438 3.438 0 0 1-2.66.945 3.428 3.428 0 0 1-2.77-1.436 3.378 3.378 0 0 1-.672-2.309c0-.073 0-.137.005-.145L8.582 6.11l.005.147a1.415 1.415 0 0 0 .423 1.064 1.417 1.417 0 0 0 1.32.395 1.412 1.412 0 0 0 1.132-1.383c0-.296-.031-.578-.079-.783l.483-.483a7.29 7.29 0 0 1 .177 1.266 7.304 7.304 0 0 1-1.983 5.027A7.243 7.243 0 0 1 8.38 14.408Z"></path>
        </svg>
        <a href="#" class="text-github-blue hover:underline">@johndoe</a>
      </li>
    </ul>
  </div>
  
  <!-- Achievements -->
  <div class="mb-6">
    <h2 class="font-semibold text-base mb-2">Achievements</h2>
    <div class="flex flex-wrap gap-1">
      <a href="#" class="block">
        <img src="https://github.githubassets.com/images/modules/profile/achievements/pull-shark-default.png" alt="Pull Shark" class="w-16 h-16 rounded-full border border-github-border">
      </a>
      <a href="#" class="block">
        <img src="https://github.githubassets.com/images/modules/profile/achievements/starstruck-default.png" alt="Starstruck" class="w-16 h-16 rounded-full border border-github-border">
      </a>
      <a href="#" class="block">
        <img src="https://github.githubassets.com/images/modules/profile/achievements/yolo-default.png" alt="YOLO" class="w-16 h-16 rounded-full border border-github-border">
      </a>
    </div>
  </div>
  
  <!-- Organizations -->
  <div class="mb-6">
    <h2 class="font-semibold text-base mb-2">Organizations</h2>
    <div class="flex flex-wrap gap-2">
      <a href="#" class="block">
        <img src="https://avatars.githubusercontent.com/u/9919?v=4" alt="GitHub" class="w-8 h-8 rounded border border-github-border">
      </a>
      <a href="#" class="block">
        <img src="https://avatars.githubusercontent.com/u/6412038?v=4" alt="React" class="w-8 h-8 rounded border border-github-border">
      </a>
      <a href="#" class="block">
        <img src="https://avatars.githubusercontent.com/u/13629408?v=4" alt="Tailwind Labs" class="w-8 h-8 rounded border border-github-border">
      </a>
    </div>
  </div>
</div>

活动流时间线实现

接下来,实现右侧的活动流时间线,包括各种类型的活动卡片:

<!-- Right content: Activity feed -->
<div class="w-full md:w-3/4">
  <!-- Profile tabs -->
  <div class="border-b border-github-border mb-6">
    <nav class="flex flex-wrap -mb-px">
      <a href="#" class="px-4 py-2 border-b-2 border-github-blue text-github-blue font-semibold">
        Overview
      </a>
      <a href="#" class="px-4 py-2 border-b-2 border-transparent hover:border-gray-300 text-github-text-secondary hover:text-github-text-primary">
        Repositories
      </a>
      <a href="#" class="px-4 py-2 border-b-2 border-transparent hover:border-gray-300 text-github-text-secondary hover:text-github-text-primary">
        Projects
      </a>
      <a href="#" class="px-4 py-2 border-b-2 border-transparent hover:border-gray-300 text-github-text-secondary hover:text-github-text-primary">
        Packages
      </a>
      <a href="#" class="px-4 py-2 border-b-2 border-transparent hover:border-gray-300 text-github-text-secondary hover:text-github-text-primary">
        Stars
      </a>
    </nav>
  </div>
  
  <!-- Pinned Repositories -->
  <div class="mb-8">
    <div class="flex justify-between items-center mb-4">
      <h2 class="text-base font-semibold">Pinned</h2>
      <a href="#" class="text-sm text-github-blue hover:underline">Customize your pins</a>
    </div>
    
    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
      <!-- Pinned Repo 1 -->
      <div class="border border-github-border rounded-github-md p-4">
        <div class="flex justify-between items-start mb-2">
          <div>
            <h3 class="font-semibold">
              <a href="#" class="text-github-blue hover:underline">awesome-project</a>
            </h3>
            <p class="text-sm text-github-text-secondary">A collection of awesome resources for developers</p>
          </div>
          <button class="text-github-text-secondary hover:text-github-text-primary">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
              <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"></path>
            </svg>
          </button>
        </div>
        <div class="mb-4">
          <p class="text-sm text-github-text-secondary">Public</p>
        </div>
        <div class="flex items-center text-github-text-secondary text-sm">
          <span class="flex items-center mr-3">
            <span class="w-3 h-3 rounded-full bg-yellow-500 mr-1"></span>
            JavaScript
          </span>
          <span class="flex items-center mr-3">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="mr-1">
              <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"></path>
            </svg>
            128
          </span>
          <span class="flex items-center">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="mr-1">
              <path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 0-6 0Zm1.5 0a.75.75 0 1 1 1.5 0 .75.75 0 0 1-1.5 0Zm6.75.75a.75.75 0 0 0 0-1.5h-3a.75.75 0 0 0 0 1.5h3ZM4.5 15a.75.75 0 0 0 .75-.75v-.5a.75.75 0 0 0-1.5 0v.5c0 .414.336.75.75.75ZM4.5 13.5a.75.75 0 0 0 .75-.75v-.5a.75.75 0 0 0-1.5 0v.5c0 .414.336.75.75.75ZM4.5 12a.75.75 0 0 0 .75-.75v-.5a.75.75 0 0 0-1.5 0v.5c0 .414.336.75.75.75ZM4.5 10.5a.75.75 0 0 0 .75-.75v-.5a.75.75 0 0 0-1.5 0v.5c0 .414.336.75.75.75Z"></path>
            </svg>
            42
          </span>
        </div>
      </div>
      
      <!-- Pinned Repo 2 -->
      <div class="border border-github-border rounded-github-md p-4">
        <div class="flex justify-between items-start mb-2">
          <div>
            <h3 class="font-semibold">
              <a href="#" class="text-github-blue hover:underline">react-components</a>
            </h3>
            <p class="text-sm text-github-text-secondary">Collection of reusable React components</p>
          </div>
          <button class="text-github-text-secondary hover:text-github-text-primary">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor">
              <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"></path>
            </svg>
          </button>
        </div>
        <div class="mb-4">
          <p class="text-sm text-github-text-secondary">Public</p>
        </div>
        <div class="flex items-center text-github-text-secondary text-sm">
          <span class="flex items-center mr-3">
            <span class="w-3 h-3 rounded-full bg-blue-500 mr-1"></span>
            TypeScript
          </span>
          <span class="flex items-center mr-3">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="mr-1">
              <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"></path>
            </svg>
            95
          </span>
          <span class="flex items-center">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="mr-1">
              <path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 0-6 0Zm1.5 0a.75.75 0 1 1 1.5 0 .75.75 0 0 1-1.5 0Zm6.75.75a.75.75 0 0 0 0-1.5h-3a.75.75 0 0 0 0 1.5h3ZM4.5 15a.75.75 0 0 0 .75-.75v-.5a.75.75 0 0 0-1.5 0v.5c0 .414.336.75.75.75ZM4.5 13.5a.75.75 0 0 0 .75-.75v-.5a.75.75 0 0 0-1.5 0v.5c0 .414.336.75.75.75ZM4.5 12a.75.75 0 0 0 .75-.75v-.5a.75.75 0 0 0-1.5 0v.5c0 .414.336.75.75.75ZM4.5 10.5a.75.75 0 0 0 .75-.75v-.5a.75.75 0 0 0-1.5 0v.5c0 .414.336.75.75.75Z"></path>
            </svg>
            37
          </span>
        </div>
      </div>
    </div>
  </div>
  
  <!-- Contribution activity -->
  <div class="mb-8">
    <h2 class="text-base font-semibold mb-4">Contribution activity</h2>
    
    <!-- Contribution graph -->
    <div class="border border-github-border rounded-github-md p-4 mb-6">
      <div class="flex justify-between items-center mb-4">
        <h3 class="text-sm font-semibold">March 2025</h3>
        <div class="flex text-xs text-github-text-secondary">
          <span class="mr-1">Less</span>
          <div class="flex items-center">
            <span class="block w-3 h-3 bg-github-bg border border-github-border"></span>
            <span class="block w-3 h-3 bg-green-100 border border-github-border"></span>
            <span class="block w-3 h-3 bg-green-300 border border-github-border"></span>
            <span class="block w-3 h-3 bg-green-500 border border-github-border"></span>
            <span class="block w-3 h-3 bg-green-700 border border-github-border"></span>
          </div>
          <span class="ml-1">More</span>
        </div>
      </div>
      
      <!-- Simplified contribution calendar (would be a heatmap in real GitHub) -->
      <div class="grid grid-cols-7 gap-1">
        <!-- Generate a 7x5 grid of squares for a simplified contribution graph -->
        <!-- Each square represents a day, colored based on contribution count -->
        <div class="w-4 h-4 bg-github-bg border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-100 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-github-bg border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-300 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-100 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-500 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-github-bg border border-github-border rounded-sm"></div>
        
        <div class="w-4 h-4 bg-green-100 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-300 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-500 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-700 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-500 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-300 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-100 border border-github-border rounded-sm"></div>
        
        <div class="w-4 h-4 bg-github-bg border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-100 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-github-bg border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-300 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-100 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-700 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-100 border border-github-border rounded-sm"></div>
        
        <div class="w-4 h-4 bg-green-300 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-500 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-300 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-github-bg border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-100 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-github-bg border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-300 border border-github-border rounded-sm"></div>
        
        <div class="w-4 h-4 bg-green-100 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-github-bg border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-100 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-300 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-500 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-700 border border-github-border rounded-sm"></div>
        <div class="w-4 h-4 bg-green-300 border border-github-border rounded-sm"></div>
      </div>
    </div>
    
    <!-- Activity feed timeline -->
    <div class="border-l-2 border-github-border ml-2 pl-4">
      <!-- Activity Header -->
      <div class="flex items-center mb-4 -ml-6">
        <span class="w-4 h-4 bg-white border-2 border-github-border rounded-full"></span>
        <h3 class="ml-2 text-sm font-semibold">March 2025</h3>
      </div>
      
      <!-- Activity Item: Created Repository -->
      <div class="mb-4 relative">
        <div class="absolute -left-[22px] mt-1 w-3 h-3 bg-green-500 border-2 border-white rounded-full"></div>
        <div class="flex flex-col sm:flex-row sm:items-center text-sm mb-1">
          <span class="font-semibold mr-1">Created repository</span>
          <span class="text-github-text-secondary">15 days ago</span>
        </div>
        <div class="border border-github-border rounded-github-md p-3">
          <div class="flex items-start">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="mr-2 text-github-text-secondary mt-1">
              <path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v.5a.25.25 0 0 1-.25.25h-3.5a.25.25 0 0 1-.25-.25Z"></path>
            </svg>
            <div>
              <h4 class="font-semibold">
                <a href="#" class="text-github-blue hover:underline">johndoe/tailwind-github-clone</a>
              </h4>
              <p class="text-github-text-secondary text-sm">A GitHub UI clone built with Tailwind CSS</p>
            </div>
          </div>
        </div>
      </div>
      
      <!-- Activity Item: Created Pull Request -->
      <div class="mb-4 relative">
        <div class="absolute -left-[22px] mt-1 w-3 h-3 bg-github-purple border-2 border-white rounded-full"></div>
        <div class="flex flex-col sm:flex-row sm:items-center text-sm mb-1">
          <span class="font-semibold mr-1">Opened a pull request</span>
          <span class="text-github-text-secondary">20 days ago</span>
        </div>
        <div class="border border-github-border rounded-github-md p-3">
          <div class="flex items-start">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="mr-2 text-github-purple mt-1">
              <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM9.75 8.75a.75.75 0 0 0 0 1.5h2.5a.75.75 0 0 0 0-1.5h-2.5Zm0 2.5a.75.75 0 0 0 0 1.5h2.5a.75.75 0 0 0 0-1.5h-2.5Zm-7.5 4v-1.625a3.75 3.75 0 1 0 0-7.5V4.5a3.75 3.75 0 1 0 0 7.5V13.5a.75.75 0 0 0 .75.75h3a.75.75 0 0 0 0-1.5Zm6-3a1.5 1.5 0 1 1 3 0 1.5 1.5 0 0 1-3 0Z"></path>
            </svg>
            <div>
              <h4 class="font-semibold">
                <a href="#" class="text-github-text-primary hover:underline">Fix navigation responsive issues</a>
                <span class="text-github-text-secondary ml-1">#42</span>
              </h4>
              <p class="text-github-text-secondary text-sm">
                <a href="#" class="text-github-blue hover:underline">open-source/awesome-project</a>
              </p>
            </div>
          </div>
        </div>
      </div>
      
      <!-- Activity Item: Issue Comment -->
      <div class="mb-4 relative">
        <div class="absolute -left-[22px] mt-1 w-3 h-3 bg-github-blue border-2 border-white rounded-full"></div>
        <div class="flex flex-col sm:flex-row sm:items-center text-sm mb-1">
          <span class="font-semibold mr-1">Commented on issue</span>
          <span class="text-github-text-secondary">22 days ago</span>
        </div>
        <div class="border border-github-border rounded-github-md p-3">
          <div class="flex items-start mb-2">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" class="mr-2 text-github-green mt-1">
              <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path>
              <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path>
            </svg>
            <div>
              <h4 class="font-semibold">
                <a href="#" class="text-github-text-primary hover:underline">Bug: Mobile menu not working on iOS</a>
                <span class="text-github-text-secondary ml-1">#28</span>
              </h4>
              <p class="text-github-text-secondary text-sm">
                <a href="#" class="text-github-blue hover:underline">open-source/awesome-project</a>
              </p>
            </div>
          </div>
          <div class="pl-6 border-l-2 border-github-border ml-1">
            <p class="text-sm">I've found a solution to this. It appears to be a Safari-specific issue with the event delegation on touch events.</p>
          </div>
        </div>
      </div>
      
      <!-- Activity Item: Commit Push -->
      <div class="mb-4 relative">
        <div class="absolute -left-[22px] mt-1 w-3 h-3 bg-github-green border-2 border-white rounded-full"></div>
        <div class="flex flex-col sm:flex-row sm:items-center text-sm mb-1">
          <span class="font-semibold mr-1">Pushed 3 commits to</span>
          <a href="#" class="text-github-blue hover:underline mr-1">johndoe/react-components</a>
          <span class="text-github-text-secondary">25 days ago</span>
        </div>
        <div class="border border-github-border rounded-github-md p-3">
          <div class="flex flex-col divide-y divide-github-border">
            <div class="pb-2 mb-2 flex items-start">
              <img src="https://avatars.githubusercontent.com/u/123456789?v=4" alt="User avatar" class="w-5 h-5 rounded-full mr-2">
              <div>
                <p class="text-sm font-mono">
                  <a href="#" class="font-semibold text-github-text-primary hover:underline">a1b2c3d</a>
                  <span class="text-github-text-primary">Fix button focus state on dark mode</span>
                </p>
              </div>
            </div>
            <div class="py-2 flex items-start">
              <img src="https://avatars.githubusercontent.com/u/123456789?v=4" alt="User avatar" class="w-5 h-5 rounded-full mr-2">
              <div>
                <p class="text-sm font-mono">
                  <a href="#" class="font-semibold text-github-text-primary hover:underline">e4f5g6h</a>
                  <span class="text-github-text-primary">Add accessibility improvements to dropdown</span>
                </p>
              </div>
            </div>
            <div class="pt-2 flex items-start">
              <img src="https://avatars.githubusercontent.com/u/123456789?v=4" alt="User avatar" class="w-5 h-5 rounded-full mr-2">
              <div>
                <p class="text-sm font-mono">
                  <a href="#" class="font-semibold text-github-text-primary hover:underline">i7j8k9l</a>
                  <span class="text-github-text-primary">Update documentation for new features</span>
                </p>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <!-- Show more activity link -->
      <div class="text-center my-4">
        <a href="#" class="text-github-blue hover:underline text-sm">
          Show more activity
        </a>
      </div>
    </div>
  </div>
</div>

移动设备适配注意事项

在实现GitHub用户主页时,我们已经做了一些响应式设计的处理,但让我们总结一下关键的移动设备适配注意事项:

  1. 布局切换

    • 在桌面端是两列布局(侧边栏+主内容区)
    • 在移动端切换为单列布局,侧边栏内容移至顶部简化显示
  2. 导航栏简化

    • 移动端隐藏大部分导航链接
    • 使用汉堡菜单图标替代
  3. 个人资料内容精简

    • 移动端只展示最基本的用户信息
    • 完整的个人资料信息可能在单独页面中访问
  4. 卡片样式

    • 置顶仓库在桌面端双列显示
    • 在移动端改为单列全宽显示
  5. 触摸友好

    • 确保所有交互元素有足够的点击区域
    • 避免过小的互动目标

关键样式技术点

1. 侧边栏布局技术

GitHub的侧边栏使用了固定宽度和滚动独立的设计。我们使用了以下Tailwind类来实现:

<div class="w-full md:w-1/4">

这确保侧边栏在桌面上占据约1/4的宽度,而在移动设备上则是全宽。

2. 活动时间线

GitHub的活动时间线是一个左侧带有彩色点和垂直线的布局。我们使用相对和绝对定位来实现:

<div class="border-l-2 border-github-border ml-2 pl-4">
  <!-- 活动项 -->
  <div class="mb-4 relative">
    <div class="absolute -left-[22px] mt-1 w-3 h-3 bg-green-500 border-2 border-white rounded-full"></div>
    <!-- 活动内容 -->
  </div>
</div>

这种技术创建了一条垂直线,通过绝对定位将彩色圆点放置在适当的位置。

3. 贡献图表

GitHub的贡献热力图是其最具特色的可视化元素之一。我们使用CSS网格来创建简化版本:

<div class="grid grid-cols-7 gap-1">
  <!-- 各种颜色的单元格 -->
  <div class="w-4 h-4 bg-github-bg border border-github-border rounded-sm"></div>
  <div class="w-4 h-4 bg-green-100 border border-github-border rounded-sm"></div>
  <!-- ... -->
</div>

这创建了一个7列的网格,每个单元格代表一天的贡献。

4. 卡片设计模式

GitHub大量使用卡片模式来组织内容。我们使用以下样式:

<div class="border border-github-border rounded-github-md p-4">
  <!-- 卡片内容 -->
</div>

这提供了一致的边框、圆角和内边距。

5. 悬停效果

GitHub的交互设计使用了微妙的悬停效果。例如:

<a href="#" class="text-github-blue hover:underline">

或者对于标签/按钮:

<button class="bg-github-bg hover:bg-gray-100">

常见问题与解决方案

问题1:保持侧边栏与主内容的平衡

解决方案:使用Flexbox或Grid布局,并为不同的视口大小设置适当的比例。在较小屏幕上转为堆叠布局。

<div class="flex flex-col md:flex-row gap-6">
  <div class="w-full md:w-1/4"><!-- 侧边栏 --></div>
  <div class="w-full md:w-3/4"><!-- 主内容 --></div>
</div>

问题2:活动时间线的样式一致性

解决方案:使用相对/绝对定位和边框来创建一致的垂直线和彩色节点。对于嵌套内容,使用统一的内边距和边框样式。

<div class="border-l-2 border-github-border ml-2 pl-4">
  <div class="relative">
    <div class="absolute -left-[22px] mt-1 w-3 h-3 bg-github-blue border-2 border-white rounded-full"></div>
    <!-- 内容 -->
  </div>
</div>

问题3:移动设备上的复杂导航

解决方案:在小屏幕上隐藏非关键导航元素,提供汉堡菜单按钮。使用响应式类控制显示:

<nav class="hidden md:flex items-center space-x-4">
  <!-- 导航链接 -->
</nav>
<button class="md:hidden">
  <!-- 汉堡菜单图标 -->
</button>

扩展与练习建议

  1. 添加标签系统:在个人资料部分添加技能标签系统,展示用户的技术专长。

  2. 实现"编辑个人资料"弹窗:创建一个弹出表单,允许用户编辑个人资料信息。

  3. 完善贡献图表:实现一个更完整的贡献热力图,包括悬停时显示具体贡献数量的工具提示。

  4. 添加仓库过滤功能:在仓库部分添加过滤选项,允许按语言、最近更新等进行筛选。

  5. 实现切换主题功能:添加一个暗/亮主题切换按钮,并使用Tailwind的暗模式支持来适配GitHub的暗色主题。

总结

在本节中,我们成功复刻了GitHub的用户主页,包括个人资料侧边栏和活动流时间线。我们学习了如何使用Tailwind CSS实现复杂的布局结构、响应式设计和交互元素。

GitHub的用户主页是一个信息密集型页面,它巧妙地组织了大量内容,同时保持了清晰的视觉层次结构。通过仔细分析和实现这个页面,我们获得了关于界面设计、响应式布局和组件复用的宝贵经验。

关键要点包括:

  • 使用Flexbox创建响应式双列布局
  • 用相对/绝对定位实现活动时间线
  • 使用CSS网格绘制贡献热力图
  • 在移动设备上适当简化界面
  • 保持一致的卡片设计语言

在下一节中,我们将探索如何实现GitHub的仓库列表页面,进一步扩展我们的GitHub界面复刻项目。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qianmoQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值