本章概述

Bootstrap 提供了丰富的基础组件,包括按钮、表单、警告框、徽章、面包屑、卡片等。这些组件是构建现代网页界面的基础元素。本章将详细介绍这些基础组件的使用方法和自定义技巧。

按钮组件

1. 基础按钮

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bootstrap 按钮组件</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container my-5">
        <h1 class="text-center mb-5">Bootstrap 按钮组件演示</h1>
        
        <!-- 基础按钮样式 -->
        <section class="mb-5">
            <h2 class="text-primary mb-4">基础按钮样式</h2>
            
            <div class="mb-4">
                <h5>主要按钮样式</h5>
                <div class="d-flex flex-wrap gap-2 mb-3">
                    <button type="button" class="btn btn-primary">Primary</button>
                    <button type="button" class="btn btn-secondary">Secondary</button>
                    <button type="button" class="btn btn-success">Success</button>
                    <button type="button" class="btn btn-danger">Danger</button>
                    <button type="button" class="btn btn-warning">Warning</button>
                    <button type="button" class="btn btn-info">Info</button>
                    <button type="button" class="btn btn-light">Light</button>
                    <button type="button" class="btn btn-dark">Dark</button>
                    <button type="button" class="btn btn-link">Link</button>
                </div>
            </div>
            
            <div class="mb-4">
                <h5>轮廓按钮样式</h5>
                <div class="d-flex flex-wrap gap-2 mb-3">
                    <button type="button" class="btn btn-outline-primary">Primary</button>
                    <button type="button" class="btn btn-outline-secondary">Secondary</button>
                    <button type="button" class="btn btn-outline-success">Success</button>
                    <button type="button" class="btn btn-outline-danger">Danger</button>
                    <button type="button" class="btn btn-outline-warning">Warning</button>
                    <button type="button" class="btn btn-outline-info">Info</button>
                    <button type="button" class="btn btn-outline-light">Light</button>
                    <button type="button" class="btn btn-outline-dark">Dark</button>
                </div>
            </div>
        </section>
        
        <!-- 按钮尺寸 -->
        <section class="mb-5">
            <h2 class="text-primary mb-4">按钮尺寸</h2>
            
            <div class="mb-4">
                <h5>不同尺寸的按钮</h5>
                <div class="d-flex flex-wrap align-items-center gap-2 mb-3">
                    <button type="button" class="btn btn-primary btn-lg">大按钮</button>
                    <button type="button" class="btn btn-primary">默认按钮</button>
                    <button type="button" class="btn btn-primary btn-sm">小按钮</button>
                </div>
            </div>
            
            <div class="mb-4">
                <h5>块级按钮</h5>
                <div class="d-grid gap-2">
                    <button class="btn btn-primary" type="button">块级按钮</button>
                    <button class="btn btn-outline-secondary" type="button">块级按钮</button>
                </div>
            </div>
            
            <div class="mb-4">
                <h5>响应式块级按钮</h5>
                <div class="d-grid gap-2 d-md-block">
                    <button class="btn btn-primary" type="button">在小屏幕上是块级</button>
                    <button class="btn btn-success" type="button">在大屏幕上是内联</button>
                </div>
            </div>
        </section>
        
        <!-- 按钮状态 -->
        <section class="mb-5">
            <h2 class="text-primary mb-4">按钮状态</h2>
            
            <div class="row g-4">
                <div class="col-md-6">
                    <h5>活动状态</h5>
                    <div class="d-flex flex-wrap gap-2 mb-3">
                        <button type="button" class="btn btn-primary active">活动的主要按钮</button>
                        <button type="button" class="btn btn-outline-primary active">活动的轮廓按钮</button>
                    </div>
                </div>
                
                <div class="col-md-6">
                    <h5>禁用状态</h5>
                    <div class="d-flex flex-wrap gap-2 mb-3">
                        <button type="button" class="btn btn-primary" disabled>禁用的主要按钮</button>
                        <button type="button" class="btn btn-outline-primary" disabled>禁用的轮廓按钮</button>
                    </div>
                </div>
            </div>
            
            <div class="mb-4">
                <h5>加载状态</h5>
                <div class="d-flex flex-wrap gap-2">
                    <button class="btn btn-primary" type="button" disabled>
                        <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
                        加载中...
                    </button>
                    <button class="btn btn-success" type="button" disabled>
                        <span class="spinner-grow spinner-grow-sm" role="status" aria-hidden="true"></span>
                        处理中...
                    </button>
                </div>
            </div>
        </section>
        
        <!-- 按钮组 -->
        <section class="mb-5">
            <h2 class="text-primary mb-4">按钮组</h2>
            
            <div class="mb-4">
                <h5>基础按钮组</h5>
                <div class="btn-group" role="group" aria-label="基础按钮组">
                    <button type="button" class="btn btn-outline-primary">左</button>
                    <button type="button" class="btn btn-outline-primary">中</button>
                    <button type="button" class="btn btn-outline-primary">右</button>
                </div>
            </div>
            
            <div class="mb-4">
                <h5>按钮工具栏</h5>
                <div class="btn-toolbar" role="toolbar" aria-label="按钮工具栏">
                    <div class="btn-group me-2" role="group" aria-label="第一组">
                        <button type="button" class="btn btn-outline-secondary">1</button>
                        <button type="button" class="btn btn-outline-secondary">2</button>
                        <button type="button" class="btn btn-outline-secondary">3</button>
                        <button type="button" class="btn btn-outline-secondary">4</button>
                    </div>
                    <div class="btn-group me-2" role="group" aria-label="第二组">
                        <button type="button" class="btn btn-outline-secondary">5</button>
                        <button type="button" class="btn btn-outline-secondary">6</button>
                        <button type="button" class="btn btn-outline-secondary">7</button>
                    </div>
                    <div class="btn-group" role="group" aria-label="第三组">
                        <button type="button" class="btn btn-outline-secondary">8</button>
                    </div>
                </div>
            </div>
            
            <div class="mb-4">
                <h5>垂直按钮组</h5>
                <div class="btn-group-vertical" role="group" aria-label="垂直按钮组">
                    <button type="button" class="btn btn-outline-primary">按钮 1</button>
                    <button type="button" class="btn btn-outline-primary">按钮 2</button>
                    <button type="button" class="btn btn-outline-primary">按钮 3</button>
                    <button type="button" class="btn btn-outline-primary">按钮 4</button>
                </div>
            </div>
        </section>
        
        <!-- 下拉按钮 -->
        <section class="mb-5">
            <h2 class="text-primary mb-4">下拉按钮</h2>
            
            <div class="row g-4">
                <div class="col-md-6">
                    <h5>单个下拉按钮</h5>
                    <div class="dropdown">
                        <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                            下拉按钮
                        </button>
                        <ul class="dropdown-menu">
                            <li><a class="dropdown-item" href="#">操作</a></li>
                            <li><a class="dropdown-item" href="#">另一个操作</a></li>
                            <li><a class="dropdown-item" href="#">其他操作</a></li>
                        </ul>
                    </div>
                </div>
                
                <div class="col-md-6">
                    <h5>分割下拉按钮</h5>
                    <div class="btn-group">
                        <button type="button" class="btn btn-danger">操作</button>
                        <button type="button" class="btn btn-danger dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
                            <span class="visually-hidden">切换下拉菜单</span>
                        </button>
                        <ul class="dropdown-menu">
                            <li><a class="dropdown-item" href="#">操作</a></li>
                            <li><a class="dropdown-item" href="#">另一个操作</a></li>
                            <li><a class="dropdown-item" href="#">其他操作</a></li>
                            <li><hr class="dropdown-divider"></li>
                            <li><a class="dropdown-item" href="#">分离的链接</a></li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

表单组件

1. 基础表单控件

<!-- 基础表单控件示例 -->
<div class="container my-5">
    <h2 class="text-primary mb-4">表单组件</h2>
    
    <div class="row">
        <div class="col-lg-8">
            <form>
                <!-- 文本输入 -->
                <div class="mb-3">
                    <label for="exampleFormControlInput1" class="form-label">邮箱地址</label>
                    <input type="email" class="form-control" id="exampleFormControlInput1" placeholder="name@example.com">
                </div>
                
                <!-- 文本域 -->
                <div class="mb-3">
                    <label for="exampleFormControlTextarea1" class="form-label">留言内容</label>
                    <textarea class="form-control" id="exampleFormControlTextarea1" rows="3" placeholder="请输入您的留言..."></textarea>
                </div>
                
                <!-- 选择框 -->
                <div class="mb-3">
                    <label for="exampleFormControlSelect1" class="form-label">选择城市</label>
                    <select class="form-select" id="exampleFormControlSelect1">
                        <option selected>请选择城市</option>
                        <option value="1">北京</option>
                        <option value="2">上海</option>
                        <option value="3">广州</option>
                        <option value="4">深圳</option>
                    </select>
                </div>
                
                <!-- 多选选择框 -->
                <div class="mb-3">
                    <label for="exampleFormControlSelect2" class="form-label">多选示例</label>
                    <select class="form-select" id="exampleFormControlSelect2" multiple>
                        <option>选项 1</option>
                        <option>选项 2</option>
                        <option>选项 3</option>
                        <option>选项 4</option>
                        <option>选项 5</option>
                    </select>
                </div>
                
                <!-- 文件上传 -->
                <div class="mb-3">
                    <label for="formFile" class="form-label">文件上传</label>
                    <input class="form-control" type="file" id="formFile">
                </div>
                
                <!-- 多文件上传 -->
                <div class="mb-3">
                    <label for="formFileMultiple" class="form-label">多文件上传</label>
                    <input class="form-control" type="file" id="formFileMultiple" multiple>
                </div>
                
                <!-- 范围滑块 -->
                <div class="mb-3">
                    <label for="customRange1" class="form-label">范围滑块</label>
                    <input type="range" class="form-range" id="customRange1">
                </div>
                
                <!-- 复选框 -->
                <div class="mb-3">
                    <div class="form-check">
                        <input class="form-check-input" type="checkbox" value="" id="flexCheckDefault">
                        <label class="form-check-label" for="flexCheckDefault">
                            默认复选框
                        </label>
                    </div>
                    <div class="form-check">
                        <input class="form-check-input" type="checkbox" value="" id="flexCheckChecked" checked>
                        <label class="form-check-label" for="flexCheckChecked">
                            选中的复选框
                        </label>
                    </div>
                </div>
                
                <!-- 单选按钮 -->
                <div class="mb-3">
                    <div class="form-check">
                        <input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioDefault1">
                        <label class="form-check-label" for="flexRadioDefault1">
                            默认单选按钮
                        </label>
                    </div>
                    <div class="form-check">
                        <input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioDefault2" checked>
                        <label class="form-check-label" for="flexRadioDefault2">
                            选中的单选按钮
                        </label>
                    </div>
                </div>
                
                <!-- 开关 -->
                <div class="mb-3">
                    <div class="form-check form-switch">
                        <input class="form-check-input" type="checkbox" role="switch" id="flexSwitchCheckDefault">
                        <label class="form-check-label" for="flexSwitchCheckDefault">默认开关</label>
                    </div>
                    <div class="form-check form-switch">
                        <input class="form-check-input" type="checkbox" role="switch" id="flexSwitchCheckChecked" checked>
                        <label class="form-check-label" for="flexSwitchCheckChecked">选中的开关</label>
                    </div>
                </div>
                
                <!-- 表单控件尺寸 -->
                <div class="mb-3">
                    <label for="largeInput" class="form-label">大尺寸输入框</label>
                    <input class="form-control form-control-lg" type="text" id="largeInput" placeholder="大尺寸输入框">
                </div>
                
                <div class="mb-3">
                    <label for="defaultInput" class="form-label">默认尺寸输入框</label>
                    <input class="form-control" type="text" id="defaultInput" placeholder="默认尺寸输入框">
                </div>
                
                <div class="mb-3">
                    <label for="smallInput" class="form-label">小尺寸输入框</label>
                    <input class="form-control form-control-sm" type="text" id="smallInput" placeholder="小尺寸输入框">
                </div>
                
                <!-- 只读和禁用 -->
                <div class="mb-3">
                    <label for="readOnlyInput" class="form-label">只读输入框</label>
                    <input class="form-control" type="text" id="readOnlyInput" value="只读输入框" readonly>
                </div>
                
                <div class="mb-3">
                    <label for="disabledInput" class="form-label">禁用输入框</label>
                    <input class="form-control" type="text" id="disabledInput" value="禁用输入框" disabled>
                </div>
                
                <!-- 表单验证 -->
                <div class="mb-3">
                    <label for="validationServer01" class="form-label">有效输入</label>
                    <input type="text" class="form-control is-valid" id="validationServer01" value="Mark" required>
                    <div class="valid-feedback">
                        看起来不错!
                    </div>
                </div>
                
                <div class="mb-3">
                    <label for="validationServer02" class="form-label">无效输入</label>
                    <input type="text" class="form-control is-invalid" id="validationServer02" value="" required>
                    <div class="invalid-feedback">
                        请提供有效的输入。
                    </div>
                </div>
                
                <button type="submit" class="btn btn-primary">提交</button>
            </form>
        </div>
    </div>
</div>

2. 输入组

<!-- 输入组示例 -->
<div class="container my-5">
    <h2 class="text-primary mb-4">输入组</h2>
    
    <div class="row">
        <div class="col-lg-8">
            <!-- 基础输入组 -->
            <div class="mb-3">
                <label for="basic-addon1" class="form-label">用户名</label>
                <div class="input-group">
                    <span class="input-group-text" id="basic-addon1">@</span>
                    <input type="text" class="form-control" placeholder="用户名" aria-label="用户名" aria-describedby="basic-addon1">
                </div>
            </div>
            
            <div class="mb-3">
                <label for="basic-addon2" class="form-label">收件人用户名</label>
                <div class="input-group">
                    <input type="text" class="form-control" placeholder="收件人用户名" aria-label="收件人用户名" aria-describedby="basic-addon2">
                    <span class="input-group-text" id="basic-addon2">@example.com</span>
                </div>
            </div>
            
            <div class="mb-3">
                <label for="basic-url" class="form-label">您的个人网址</label>
                <div class="input-group">
                    <span class="input-group-text" id="basic-addon3">https://example.com/users/</span>
                    <input type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3">
                </div>
            </div>
            
            <div class="mb-3">
                <label for="basic-addon4" class="form-label">金额</label>
                <div class="input-group">
                    <span class="input-group-text">¥</span>
                    <input type="text" class="form-control" aria-label="金额">
                    <span class="input-group-text">.00</span>
                </div>
            </div>
            
            <!-- 带按钮的输入组 -->
            <div class="mb-3">
                <label for="button-addon1" class="form-label">搜索</label>
                <div class="input-group">
                    <button class="btn btn-outline-secondary" type="button" id="button-addon1">搜索</button>
                    <input type="text" class="form-control" placeholder="" aria-label="搜索" aria-describedby="button-addon1">
                </div>
            </div>
            
            <div class="mb-3">
                <div class="input-group">
                    <input type="text" class="form-control" placeholder="搜索关键词" aria-label="搜索关键词" aria-describedby="button-addon2">
                    <button class="btn btn-primary" type="button" id="button-addon2">搜索</button>
                </div>
            </div>
            
            <!-- 带下拉菜单的输入组 -->
            <div class="mb-3">
                <div class="input-group">
                    <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">下拉菜单</button>
                    <ul class="dropdown-menu">
                        <li><a class="dropdown-item" href="#">操作</a></li>
                        <li><a class="dropdown-item" href="#">另一个操作</a></li>
                        <li><a class="dropdown-item" href="#">其他操作</a></li>
                        <li><hr class="dropdown-divider"></li>
                        <li><a class="dropdown-item" href="#">分离的链接</a></li>
                    </ul>
                    <input type="text" class="form-control" aria-label="带下拉菜单的文本输入">
                </div>
            </div>
            
            <!-- 输入组尺寸 -->
            <div class="mb-3">
                <div class="input-group input-group-sm">
                    <span class="input-group-text" id="inputGroup-sizing-sm">小</span>
                    <input type="text" class="form-control" aria-label="小尺寸" aria-describedby="inputGroup-sizing-sm">
                </div>
            </div>
            
            <div class="mb-3">
                <div class="input-group">
                    <span class="input-group-text" id="inputGroup-sizing-default">默认</span>
                    <input type="text" class="form-control" aria-label="默认尺寸" aria-describedby="inputGroup-sizing-default">
                </div>
            </div>
            
            <div class="mb-3">
                <div class="input-group input-group-lg">
                    <span class="input-group-text" id="inputGroup-sizing-lg">大</span>
                    <input type="text" class="form-control" aria-label="大尺寸" aria-describedby="inputGroup-sizing-lg">
                </div>
            </div>
        </div>
    </div>
</div>

警告框组件

1. 基础警告框

<!-- 警告框示例 -->
<div class="container my-5">
    <h2 class="text-primary mb-4">警告框组件</h2>
    
    <!-- 基础警告框 -->
    <div class="mb-4">
        <h5>基础警告框</h5>
        <div class="alert alert-primary" role="alert">
            这是一个主要警告框——查看它!
        </div>
        <div class="alert alert-secondary" role="alert">
            这是一个次要警告框——查看它!
        </div>
        <div class="alert alert-success" role="alert">
            这是一个成功警告框——查看它!
        </div>
        <div class="alert alert-danger" role="alert">
            这是一个危险警告框——查看它!
        </div>
        <div class="alert alert-warning" role="alert">
            这是一个警告警告框——查看它!
        </div>
        <div class="alert alert-info" role="alert">
            这是一个信息警告框——查看它!
        </div>
        <div class="alert alert-light" role="alert">
            这是一个浅色警告框——查看它!
        </div>
        <div class="alert alert-dark" role="alert">
            这是一个深色警告框——查看它!
        </div>
    </div>
    
    <!-- 带链接的警告框 -->
    <div class="mb-4">
        <h5>带链接的警告框</h5>
        <div class="alert alert-primary" role="alert">
            这是一个主要警告框,带有 <a href="#" class="alert-link">示例链接</a>。如果您愿意,请点击它。
        </div>
        <div class="alert alert-success" role="alert">
            这是一个成功警告框,带有 <a href="#" class="alert-link">示例链接</a>。如果您愿意,请点击它。
        </div>
    </div>
    
    <!-- 带图标的警告框 -->
    <div class="mb-4">
        <h5>带图标的警告框</h5>
        <div class="alert alert-success d-flex align-items-center" role="alert">
            <svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Success:">
                <use xlink:href="#check-circle-fill"/>
            </svg>
            <div>
                操作成功完成!
            </div>
        </div>
        
        <div class="alert alert-warning d-flex align-items-center" role="alert">
            <svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Warning:">
                <use xlink:href="#exclamation-triangle-fill"/>
            </svg>
            <div>
                请注意这个重要信息。
            </div>
        </div>
        
        <div class="alert alert-danger d-flex align-items-center" role="alert">
            <svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Danger:">
                <use xlink:href="#exclamation-triangle-fill"/>
            </svg>
            <div>
                发生了一个错误,请重试。
            </div>
        </div>
    </div>
    
    <!-- 可关闭的警告框 -->
    <div class="mb-4">
        <h5>可关闭的警告框</h5>
        <div class="alert alert-warning alert-dismissible fade show" role="alert">
            <strong>注意!</strong> 您应该检查下面的一些字段。
            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
        </div>
        
        <div class="alert alert-info alert-dismissible fade show" role="alert">
            <h4 class="alert-heading">信息提示</h4>
            <p>这是一个重要的信息提示。您可以在这里放置更多的内容。</p>
            <hr>
            <p class="mb-0">记住,您可以随时关闭这个警告框。</p>
            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
        </div>
    </div>
    
    <!-- 复杂内容的警告框 -->
    <div class="mb-4">
        <h5>复杂内容的警告框</h5>
        <div class="alert alert-success" role="alert">
            <h4 class="alert-heading">干得好!</h4>
            <p>您已经成功阅读了这个重要的警告消息。这个示例文本将运行更长一点,以便您可以看到警告框内的间距如何与这种内容一起工作。</p>
            <hr>
            <p class="mb-0">每当您需要时,请务必使用边距工具来保持整洁。</p>
        </div>
    </div>
</div>

<!-- SVG 图标定义 -->
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
    <symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16">
        <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.061L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
    </symbol>
    <symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16">
        <path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
    </symbol>
</svg>

徽章组件

1. 基础徽章

<!-- 徽章示例 -->
<div class="container my-5">
    <h2 class="text-primary mb-4">徽章组件</h2>
    
    <!-- 基础徽章 -->
    <div class="mb-4">
        <h5>基础徽章</h5>
        <h1>示例标题 <span class="badge bg-secondary">新</span></h1>
        <h2>示例标题 <span class="badge bg-secondary">新</span></h2>
        <h3>示例标题 <span class="badge bg-secondary">新</span></h3>
        <h4>示例标题 <span class="badge bg-secondary">新</span></h4>
        <h5>示例标题 <span class="badge bg-secondary">新</span></h5>
        <h6>示例标题 <span class="badge bg-secondary">新</span></h6>
    </div>
    
    <!-- 不同颜色的徽章 -->
    <div class="mb-4">
        <h5>不同颜色的徽章</h5>
        <span class="badge bg-primary">Primary</span>
        <span class="badge bg-secondary">Secondary</span>
        <span class="badge bg-success">Success</span>
        <span class="badge bg-danger">Danger</span>
        <span class="badge bg-warning text-dark">Warning</span>
        <span class="badge bg-info text-dark">Info</span>
        <span class="badge bg-light text-dark">Light</span>
        <span class="badge bg-dark">Dark</span>
    </div>
    
    <!-- 药丸徽章 -->
    <div class="mb-4">
        <h5>药丸徽章</h5>
        <span class="badge rounded-pill bg-primary">Primary</span>
        <span class="badge rounded-pill bg-secondary">Secondary</span>
        <span class="badge rounded-pill bg-success">Success</span>
        <span class="badge rounded-pill bg-danger">Danger</span>
        <span class="badge rounded-pill bg-warning text-dark">Warning</span>
        <span class="badge rounded-pill bg-info text-dark">Info</span>
        <span class="badge rounded-pill bg-light text-dark">Light</span>
        <span class="badge rounded-pill bg-dark">Dark</span>
    </div>
    
    <!-- 带计数的徽章 -->
    <div class="mb-4">
        <h5>带计数的徽章</h5>
        <button type="button" class="btn btn-primary position-relative">
            收件箱
            <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">
                99+
                <span class="visually-hidden">未读消息</span>
            </span>
        </button>
        
        <button type="button" class="btn btn-primary position-relative ms-3">
            个人资料
            <span class="position-absolute top-0 start-100 translate-middle p-2 bg-danger border border-light rounded-circle">
                <span class="visually-hidden">新警告</span>
            </span>
        </button>
    </div>
    
    <!-- 作为链接的徽章 -->
    <div class="mb-4">
        <h5>作为链接的徽章</h5>
        <a href="#" class="badge bg-primary text-decoration-none">Primary</a>
        <a href="#" class="badge bg-secondary text-decoration-none">Secondary</a>
        <a href="#" class="badge bg-success text-decoration-none">Success</a>
        <a href="#" class="badge bg-danger text-decoration-none">Danger</a>
        <a href="#" class="badge bg-warning text-dark text-decoration-none">Warning</a>
        <a href="#" class="badge bg-info text-dark text-decoration-none">Info</a>
        <a href="#" class="badge bg-light text-dark text-decoration-none">Light</a>
        <a href="#" class="badge bg-dark text-decoration-none">Dark</a>
    </div>
</div>

面包屑组件

1. 基础面包屑

<!-- 面包屑示例 -->
<div class="container my-5">
    <h2 class="text-primary mb-4">面包屑组件</h2>
    
    <!-- 基础面包屑 -->
    <div class="mb-4">
        <h5>基础面包屑</h5>
        <nav aria-label="breadcrumb">
            <ol class="breadcrumb">
                <li class="breadcrumb-item active" aria-current="page">首页</li>
            </ol>
        </nav>
        
        <nav aria-label="breadcrumb">
            <ol class="breadcrumb">
                <li class="breadcrumb-item"><a href="#">首页</a></li>
                <li class="breadcrumb-item active" aria-current="page">图书馆</li>
            </ol>
        </nav>
        
        <nav aria-label="breadcrumb">
            <ol class="breadcrumb">
                <li class="breadcrumb-item"><a href="#">首页</a></li>
                <li class="breadcrumb-item"><a href="#">图书馆</a></li>
                <li class="breadcrumb-item active" aria-current="page">数据</li>
            </ol>
        </nav>
    </div>
    
    <!-- 自定义分隔符 -->
    <div class="mb-4">
        <h5>自定义分隔符</h5>
        <style>
            .breadcrumb-custom {
                --bs-breadcrumb-divider: '>';
            }
            .breadcrumb-arrow {
                --bs-breadcrumb-divider: '→';
            }
            .breadcrumb-dot {
                --bs-breadcrumb-divider: '•';
            }
        </style>
        
        <nav aria-label="breadcrumb">
            <ol class="breadcrumb breadcrumb-custom">
                <li class="breadcrumb-item"><a href="#">首页</a></li>
                <li class="breadcrumb-item"><a href="#">产品</a></li>
                <li class="breadcrumb-item active" aria-current="page">详情</li>
            </ol>
        </nav>
        
        <nav aria-label="breadcrumb">
            <ol class="breadcrumb breadcrumb-arrow">
                <li class="breadcrumb-item"><a href="#">首页</a></li>
                <li class="breadcrumb-item"><a href="#">分类</a></li>
                <li class="breadcrumb-item active" aria-current="page">商品</li>
            </ol>
        </nav>
        
        <nav aria-label="breadcrumb">
            <ol class="breadcrumb breadcrumb-dot">
                <li class="breadcrumb-item"><a href="#">首页</a></li>
                <li class="breadcrumb-item"><a href="#">博客</a></li>
                <li class="breadcrumb-item active" aria-current="page">文章</li>
            </ol>
        </nav>
    </div>
</div>

卡片组件

1. 基础卡片

<!-- 卡片示例 -->
<div class="container my-5">
    <h2 class="text-primary mb-4">卡片组件</h2>
    
    <div class="row g-4">
        <!-- 基础卡片 -->
        <div class="col-md-4">
            <div class="card">
                <img src="https://via.placeholder.com/300x200" class="card-img-top" alt="示例图片">
                <div class="card-body">
                    <h5 class="card-title">卡片标题</h5>
                    <p class="card-text">这是一个简单的卡片示例,展示了卡片的基本结构和内容。</p>
                    <a href="#" class="btn btn-primary">查看详情</a>
                </div>
            </div>
        </div>
        
        <!-- 带页眉和页脚的卡片 -->
        <div class="col-md-4">
            <div class="card">
                <div class="card-header">
                    特色内容
                </div>
                <div class="card-body">
                    <h5 class="card-title">特殊标题处理</h5>
                    <p class="card-text">通过支持文本构建卡片标题,并构成卡片内容的大部分。</p>
                    <a href="#" class="btn btn-primary">开始使用</a>
                </div>
                <div class="card-footer text-muted">
                    2天前
                </div>
            </div>
        </div>
        
        <!-- 只有文本的卡片 -->
        <div class="col-md-4">
            <div class="card">
                <div class="card-body">
                    <h5 class="card-title">卡片标题</h5>
                    <h6 class="card-subtitle mb-2 text-muted">卡片副标题</h6>
                    <p class="card-text">一些快速示例文本,用于构建卡片标题并构成卡片内容的大部分。</p>
                    <a href="#" class="card-link">卡片链接</a>
                    <a href="#" class="card-link">另一个链接</a>
                </div>
            </div>
        </div>
        
        <!-- 列表组卡片 -->
        <div class="col-md-4">
            <div class="card">
                <div class="card-header">
                    功能列表
                </div>
                <ul class="list-group list-group-flush">
                    <li class="list-group-item">功能一</li>
                    <li class="list-group-item">功能二</li>
                    <li class="list-group-item">功能三</li>
                </ul>
            </div>
        </div>
        
        <!-- 混合内容卡片 -->
        <div class="col-md-4">
            <div class="card">
                <img src="https://via.placeholder.com/300x200" class="card-img-top" alt="示例图片">
                <div class="card-body">
                    <h5 class="card-title">卡片标题</h5>
                    <p class="card-text">这是一个更宽的卡片,支持下面的自然引导到额外内容。</p>
                </div>
                <ul class="list-group list-group-flush">
                    <li class="list-group-item">项目一</li>
                    <li class="list-group-item">项目二</li>
                    <li class="list-group-item">项目三</li>
                </ul>
                <div class="card-body">
                    <a href="#" class="card-link">卡片链接</a>
                    <a href="#" class="card-link">另一个链接</a>
                </div>
            </div>
        </div>
        
        <!-- 引用卡片 -->
        <div class="col-md-4">
            <div class="card text-center">
                <div class="card-body">
                    <blockquote class="blockquote mb-0">
                        <p>一个著名的引用,包含在一个blockquote元素中。</p>
                        <footer class="blockquote-footer">来自 <cite title="源标题">著名作者</cite></footer>
                    </blockquote>
                </div>
            </div>
        </div>
    </div>
    
    <!-- 卡片样式变体 -->
    <div class="row g-4 mt-4">
        <div class="col-md-4">
            <div class="card text-white bg-primary">
                <div class="card-header">页眉</div>
                <div class="card-body">
                    <h5 class="card-title">主要卡片标题</h5>
                    <p class="card-text">一些快速示例文本,用于构建卡片标题并构成卡片内容的大部分。</p>
                </div>
            </div>
        </div>
        
        <div class="col-md-4">
            <div class="card text-white bg-success">
                <div class="card-header">页眉</div>
                <div class="card-body">
                    <h5 class="card-title">成功卡片标题</h5>
                    <p class="card-text">一些快速示例文本,用于构建卡片标题并构成卡片内容的大部分。</p>
                </div>
            </div>
        </div>
        
        <div class="col-md-4">
            <div class="card text-white bg-danger">
                <div class="card-header">页眉</div>
                <div class="card-body">
                    <h5 class="card-title">危险卡片标题</h5>
                    <p class="card-text">一些快速示例文本,用于构建卡片标题并构成卡片内容的大部分。</p>
                </div>
            </div>
        </div>
    </div>
    
    <!-- 边框卡片 -->
    <div class="row g-4 mt-4">
        <div class="col-md-4">
            <div class="card border-primary">
                <div class="card-header">页眉</div>
                <div class="card-body text-primary">
                    <h5 class="card-title">主要边框卡片</h5>
                    <p class="card-text">一些快速示例文本,用于构建卡片标题并构成卡片内容的大部分。</p>
                </div>
            </div>
        </div>
        
        <div class="col-md-4">
            <div class="card border-success">
                <div class="card-header">页眉</div>
                <div class="card-body text-success">
                    <h5 class="card-title">成功边框卡片</h5>
                    <p class="card-text">一些快速示例文本,用于构建卡片标题并构成卡片内容的大部分。</p>
                </div>
            </div>
        </div>
        
        <div class="col-md-4">
            <div class="card border-danger">
                <div class="card-header">页眉</div>
                <div class="card-body text-danger">
                    <h5 class="card-title">危险边框卡片</h5>
                    <p class="card-text">一些快速示例文本,用于构建卡片标题并构成卡片内容的大部分。</p>
                </div>
            </div>
        </div>
    </div>
</div>

实际应用案例

1. 用户注册表单

<!-- 用户注册表单示例 -->
<div class="container my-5">
    <div class="row justify-content-center">
        <div class="col-md-6">
            <div class="card">
                <div class="card-header bg-primary text-white text-center">
                    <h4 class="mb-0">用户注册</h4>
                </div>
                <div class="card-body">
                    <form id="registrationForm" novalidate>
                        <div class="mb-3">
                            <label for="username" class="form-label">用户名 *</label>
                            <input type="text" class="form-control" id="username" required>
                            <div class="invalid-feedback">
                                请输入用户名。
                            </div>
                        </div>
                        
                        <div class="mb-3">
                            <label for="email" class="form-label">邮箱地址 *</label>
                            <input type="email" class="form-control" id="email" required>
                            <div class="invalid-feedback">
                                请输入有效的邮箱地址。
                            </div>
                        </div>
                        
                        <div class="mb-3">
                            <label for="password" class="form-label">密码 *</label>
                            <input type="password" class="form-control" id="password" required>
                            <div class="invalid-feedback">
                                请输入密码。
                            </div>
                        </div>
                        
                        <div class="mb-3">
                            <label for="confirmPassword" class="form-label">确认密码 *</label>
                            <input type="password" class="form-control" id="confirmPassword" required>
                            <div class="invalid-feedback">
                                请确认密码。
                            </div>
                        </div>
                        
                        <div class="mb-3">
                            <div class="form-check">
                                <input class="form-check-input" type="checkbox" id="agreement" required>
                                <label class="form-check-label" for="agreement">
                                    我同意 <a href="#" class="text-primary">服务条款</a> 和 <a href="#" class="text-primary">隐私政策</a>
                                </label>
                                <div class="invalid-feedback">
                                    您必须同意服务条款才能注册。
                                </div>
                            </div>
                        </div>
                        
                        <div class="d-grid">
                            <button type="submit" class="btn btn-primary btn-lg">注册账户</button>
                        </div>
                    </form>
                    
                    <div class="text-center mt-3">
                        <span class="text-muted">已有账户?</span>
                        <a href="#" class="text-primary">立即登录</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
// 表单验证
(function() {
    'use strict';
    
    const form = document.getElementById('registrationForm');
    
    form.addEventListener('submit', function(event) {
        if (!form.checkValidity()) {
            event.preventDefault();
            event.stopPropagation();
        }
        
        form.classList.add('was-validated');
    }, false);
})();
</script>

2. 产品展示卡片

<!-- 产品展示卡片示例 -->
<div class="container my-5">
    <h2 class="text-center mb-5">热门产品</h2>
    
    <div class="row g-4">
        <div class="col-lg-3 col-md-6">
            <div class="card h-100">
                <div class="position-relative">
                    <img src="https://via.placeholder.com/300x200" class="card-img-top" alt="产品图片">
                    <span class="position-absolute top-0 start-0 badge bg-danger m-2">热销</span>
                    <span class="position-absolute top-0 end-0 badge bg-success m-2">-20%</span>
                </div>
                <div class="card-body d-flex flex-column">
                    <h5 class="card-title">智能手机</h5>
                    <p class="card-text flex-grow-1">最新款智能手机,配备先进的处理器和高清摄像头。</p>
                    <div class="mb-2">
                        <span class="text-decoration-line-through text-muted">¥2999</span>
                        <span class="h5 text-danger ms-2">¥2399</span>
                    </div>
                    <div class="mb-3">
                        <div class="d-flex align-items-center">
                            <div class="text-warning me-2">
                                ★★★★☆
                            </div>
                            <small class="text-muted">(128 评价)</small>
                        </div>
                    </div>
                    <div class="mt-auto">
                        <div class="d-grid gap-2">
                            <button class="btn btn-primary">立即购买</button>
                            <button class="btn btn-outline-secondary">加入购物车</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

### 3. 通知系统

```html
<!-- 通知系统示例 -->
<div class="container my-5">
    <h2 class="text-center mb-5">通知系统</h2>
    
    <!-- 通知控制面板 -->
    <div class="row justify-content-center mb-4">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">
                    <h5 class="mb-0">通知演示</h5>
                </div>
                <div class="card-body">
                    <div class="d-flex flex-wrap gap-2">
                        <button type="button" class="btn btn-success" onclick="showAlert('success', '操作成功!', '您的操作已成功完成。')">成功通知</button>
                        <button type="button" class="btn btn-danger" onclick="showAlert('danger', '操作失败!', '发生了一个错误,请重试。')">错误通知</button>
                        <button type="button" class="btn btn-warning" onclick="showAlert('warning', '注意!', '请检查您的输入信息。')">警告通知</button>
                        <button type="button" class="btn btn-info" onclick="showAlert('info', '提示信息', '这是一条重要的提示信息。')">信息通知</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <!-- 通知容器 -->
    <div id="alertContainer" class="position-fixed top-0 end-0 p-3" style="z-index: 1050;"></div>
</div>

<script>
function showAlert(type, title, message) {
    const alertContainer = document.getElementById('alertContainer');
    const alertId = 'alert-' + Date.now();
    
    const alertHTML = `
        <div id="${alertId}" class="alert alert-${type} alert-dismissible fade show" role="alert">
            <strong>${title}</strong> ${message}
            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
        </div>
    `;
    
    alertContainer.insertAdjacentHTML('beforeend', alertHTML);
    
    // 自动关闭通知
    setTimeout(() => {
        const alertElement = document.getElementById(alertId);
        if (alertElement) {
            const bsAlert = new bootstrap.Alert(alertElement);
            bsAlert.close();
        }
    }, 5000);
}
</script>

自定义组件样式

1. 自定义按钮样式

/* 自定义按钮样式 */
.btn-gradient {
    background: linear-gradient(45deg, #007bff, #6610f2);
    border: none;
    color: white;
    transition: all 0.3s ease;
}

.btn-gradient:hover {
    background: linear-gradient(45deg, #0056b3, #520dc2);
    color: white;
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}

.btn-rounded {
    border-radius: 50px;
    padding: 0.5rem 1.5rem;
}

.btn-shadow {
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    transition: all 0.3s ease;
}

.btn-shadow:hover {
    box-shadow: 0 6px 12px rgba(0,0,0,0.15);
    transform: translateY(-1px);
}

/* 自定义卡片样式 */
.card-hover {
    transition: all 0.3s ease;
    cursor: pointer;
}

.card-hover:hover {
    transform: translateY(-5px);
    box-shadow: 0 8px 25px rgba(0,0,0,0.15);
}

.card-glass {
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.2);
}

/* 自定义表单样式 */
.form-floating-custom .form-control {
    border-radius: 10px;
    border: 2px solid #e9ecef;
    transition: all 0.3s ease;
}

.form-floating-custom .form-control:focus {
    border-color: #007bff;
    box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}

.form-floating-custom .form-label {
    color: #6c757d;
    transition: all 0.3s ease;
}

.form-floating-custom .form-control:focus ~ .form-label {
    color: #007bff;
}

2. 响应式组件优化

/* 响应式按钮优化 */
@media (max-width: 576px) {
    .btn-responsive {
        width: 100%;
        margin-bottom: 0.5rem;
    }
    
    .btn-group-responsive {
        flex-direction: column;
    }
    
    .btn-group-responsive .btn {
        border-radius: 0.375rem !important;
        margin-bottom: 0.25rem;
    }
}

/* 响应式卡片优化 */
@media (max-width: 768px) {
    .card-responsive {
        margin-bottom: 1rem;
    }
    
    .card-responsive .card-body {
        padding: 1rem;
    }
    
    .card-responsive .card-title {
        font-size: 1.1rem;
    }
}

/* 响应式表单优化 */
@media (max-width: 576px) {
    .form-responsive .input-group {
        flex-direction: column;
    }
    
    .form-responsive .input-group .btn {
        border-radius: 0.375rem;
        margin-top: 0.5rem;
    }
    
    .form-responsive .input-group .form-control {
        border-radius: 0.375rem;
    }
}

组件可访问性

1. 键盘导航支持

<!-- 可访问性优化示例 -->
<div class="container my-5">
    <h2 class="text-primary mb-4">可访问性优化</h2>
    
    <!-- 可访问的按钮组 -->
    <div class="mb-4">
        <h5>可访问的按钮组</h5>
        <div class="btn-group" role="group" aria-label="操作按钮组">
            <button type="button" class="btn btn-outline-primary" aria-describedby="edit-help">编辑</button>
            <button type="button" class="btn btn-outline-secondary" aria-describedby="delete-help">删除</button>
            <button type="button" class="btn btn-outline-success" aria-describedby="save-help">保存</button>
        </div>
        <div id="edit-help" class="form-text">编辑当前项目</div>
        <div id="delete-help" class="form-text">删除当前项目</div>
        <div id="save-help" class="form-text">保存更改</div>
    </div>
    
    <!-- 可访问的表单 -->
    <div class="mb-4">
        <h5>可访问的表单</h5>
        <form>
            <div class="mb-3">
                <label for="accessible-email" class="form-label">邮箱地址 <span class="text-danger">*</span></label>
                <input type="email" class="form-control" id="accessible-email" aria-describedby="email-help" required>
                <div id="email-help" class="form-text">我们永远不会与其他人分享您的邮箱。</div>
            </div>
            
            <fieldset class="mb-3">
                <legend class="form-label">选择您的偏好</legend>
                <div class="form-check">
                    <input class="form-check-input" type="radio" name="preference" id="pref1" value="option1">
                    <label class="form-check-label" for="pref1">选项 1</label>
                </div>
                <div class="form-check">
                    <input class="form-check-input" type="radio" name="preference" id="pref2" value="option2">
                    <label class="form-check-label" for="pref2">选项 2</label>
                </div>
            </fieldset>
            
            <button type="submit" class="btn btn-primary" aria-describedby="submit-help">提交</button>
            <div id="submit-help" class="form-text">点击提交您的信息</div>
        </form>
    </div>
</div>

性能优化建议

1. 组件懒加载

// 组件懒加载实现
class ComponentLazyLoader {
    constructor() {
        this.observer = new IntersectionObserver(this.handleIntersection.bind(this), {
            threshold: 0.1
        });
    }
    
    observe(element) {
        this.observer.observe(element);
    }
    
    handleIntersection(entries) {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                this.loadComponent(entry.target);
                this.observer.unobserve(entry.target);
            }
        });
    }
    
    loadComponent(element) {
        const componentType = element.dataset.component;
        
        switch(componentType) {
            case 'card':
                this.loadCard(element);
                break;
            case 'form':
                this.loadForm(element);
                break;
            default:
                console.warn('Unknown component type:', componentType);
        }
    }
    
    loadCard(element) {
        // 动态加载卡片内容
        const cardHTML = `
            <div class="card">
                <div class="card-body">
                    <h5 class="card-title">动态加载的卡片</h5>
                    <p class="card-text">这个卡片是通过懒加载技术动态加载的。</p>
                </div>
            </div>
        `;
        element.innerHTML = cardHTML;
    }
    
    loadForm(element) {
        // 动态加载表单内容
        const formHTML = `
            <form>
                <div class="mb-3">
                    <label for="lazy-input" class="form-label">动态输入框</label>
                    <input type="text" class="form-control" id="lazy-input">
                </div>
                <button type="submit" class="btn btn-primary">提交</button>
            </form>
        `;
        element.innerHTML = formHTML;
    }
}

// 使用懒加载
const lazyLoader = new ComponentLazyLoader();
document.querySelectorAll('[data-lazy-component]').forEach(element => {
    lazyLoader.observe(element);
});

本章总结

本章详细介绍了 Bootstrap 的基础组件系统:

主要内容

  1. 按钮组件

    • 基础按钮样式和变体
    • 按钮尺寸和状态
    • 按钮组和下拉按钮
    • 响应式按钮设计
  2. 表单组件

    • 基础表单控件
    • 输入组和表单验证
    • 表单布局和样式
    • 可访问性优化
  3. 信息展示组件

    • 警告框的使用和自定义
    • 徽章组件的应用场景
    • 面包屑导航的实现
    • 卡片组件的灵活运用
  4. 实际应用案例

    • 用户注册表单设计
    • 产品展示卡片布局
    • 通知系统的实现
  5. 高级技巧

    • 自定义组件样式
    • 响应式组件优化
    • 可访问性最佳实践
    • 性能优化策略

最佳实践

  1. 语义化使用:选择合适的组件类型表达内容含义
  2. 一致性设计:保持组件样式和交互的一致性
  3. 响应式适配:确保组件在不同设备上的良好表现
  4. 可访问性:遵循 WCAG 指南,提供良好的用户体验
  5. 性能考虑:合理使用组件,避免过度渲染

练习题

基础练习

  1. 创建一个包含不同类型按钮的工具栏
  2. 设计一个用户登录表单,包含验证功能
  3. 实现一个产品信息卡片,展示图片、标题、价格和操作按钮
  4. 创建一个通知系统,支持不同类型的消息提示

进阶练习

  1. 设计一个响应式的电商产品列表页面
  2. 实现一个多步骤表单向导,使用卡片和按钮组件
  3. 创建一个可自定义的仪表板,包含各种信息展示组件
  4. 开发一个组件库,扩展 Bootstrap 的基础组件功能

通过本章的学习,您应该能够熟练使用 Bootstrap 的基础组件,创建功能丰富、用户友好的网页界面。btn btn-outline-secondary”>加入购物车