CSS-选择器12-:empty

本文详细介绍了 CSS 中的 :empty 选择器,并通过示例代码展示了如何使用该选择器来定位那些没有任何子元素(包括文本节点)的 HTML 元素。通过对 :empty 选择器的理解和应用,开发者可以更灵活地控制网页样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CSS选择器-系列文章

1、:empty选择器

:empty 选择器匹配没有子元素(包括文本节点)的每个元素。

2、效果演示

源代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>css-选择器-empty</title>
    <style type="text/css">
        p:empty{
            width: 100px;
            height: 20px;
            background: red;
        }
    </style>
</head>
<body>
    <p>p1</p>
    <p></p>
    <p>p2</p>
    <p>p3</p>
    <p>p4</p>
</body>
</html>

运行效果:


image.png

CSS选择器-系列文章
下一节 CSS-选择器13-:not

<template> <view class="container"> <!-- 搜索表单区域 --> <view class="search-card"> <view class="form-group title-group"> <text class="form-label">问卷标题:</text> <input v-model="formData.dcWjTitle" placeholder="请输入问卷标题" class="form-input title-input" /> </view> <view class="form-row"> <!-- 被测评人选择器 --> <view class="form-group form-group-half"> <text class="form-label">被测评人:</text> <view class="search-select-container"> <view class="input-container" @click="showBdrList = true"> <!-- 已选项显示 --> <view v-if="formData.dcId.length > 0" class="selected-display"> {{ selectedBdrLabel }} </view> <!-- 占位符 --> <text v-else-if="showBdrPlaceholder" class="placeholder-text"> 请选择被测评人 </text> <!-- 下拉箭头 --> <view class="dropdown-icon"> <text>▼</text> </view> </view> <!-- 下拉列表 --> <view v-if="showBdrList" class="dropdown-list"> <view class="search-box"> <input v-model="bdrSearchKeyword" placeholder="搜索被测评人" class="search-input" @input="filterBdrOptions" /> </view> <scroll-view scroll-y="true" class="dropdown-scroll"> <view v-for="(item, index) in filteredBdrOptions" :key="index" class="dropdown-item" :class="{ 'selected': formData.dcId[0] === item.value }" @click="handleBdrSelect(item)" > {{ item.label }} </view> <view v-if="filteredBdrOptions.length === 0" class="empty-option"> 无匹配结果 </view> </scroll-view> </view> <!-- 遮罩层 --> <view v-if="showBdrList" class="dropdown-mask" @click="showBdrList = false" ></view> </view> </view> <!-- 人员部门 --> <view class="form-group form-group-half"> <text class="form-label">人员部门:</text> <input v-model="formData.dcDept" placeholder="请输入部门" class="form-input" /> </view> </view> <!-- 提交状态和按钮组 --> <view class="form-row-bottom"> <!-- 提交状态 --> <view class="state-group"> <text class="form-label">提交状态:</text> <view class="search-select-container"> <view class="state-select-box" @click="toggleStateList"> <text class="selected-state"> {{ getStateLabel(formData.state) }} </text> <view class="dropdown-icon"> <text>▼</text> </view> </view> <!-- 状态下拉列表 --> <view v-if="showStateList" class="dropdown-list state-dropdown"> <view v-for="(state, index) in stateOptions" :key="index" class="dropdown-item" :class="{ 'selected': formData.state === state.value }" @click="handleStateSelect(state)" > {{ state.label }} </view> </view> <!-- 遮罩层 --> <view v-if="showStateList" class="dropdown-mask" @click="showStateList = false" ></view> </view> </view> <!-- 按钮组 --> <view class="button-group"> <button class="search-button" @click="handleSearch">搜索</button> <button class="reset-button" @click="handleReset">重置</button> </view> </view> </view> <!-- 数据显示区域 --> <view class="data-card"> <view class="card-header"> <button class="refresh-button" @click="refreshData">刷新数据</button> </view> <!-- 加载状态 --> <view v-if="loading" class="loading-container"> <view class="loading-spinner"></view> <text class="loading-text">加载中...</text> </view> <!-- 数据展示 --> <view v-else> <view v-for="(item, index) in surveyList" :key="index" class="data-card-item" > <view class="card-header-section"> <view class="card-title">{{ item.dcWjTitle }}</view> </view> <view class="card-body-section"> <view class="card-row"> <text class="card-label">被测评人:</text> <text class="card-value">{{ item.dcName }}</text> </view> <view class="card-row"> <text class="card-label">部门:</text> <text class="card-value">{{ item.dcDept }}</text> </view> <view class="card-row"> <text class="card-label">创建时间:</text> <text class="card-value">{{ item.createTime }}</text> </view> <view class="card-row"> <text class="card-label">提交时间:</text> <text class="card-value">{{ item.updateTime || '-' }}</text> </view> </view> <view class="card-footer-section"> <view class="status-container"> <view :class="[ 'status-tag', item.state === '1' ? 'status-submitted' : 'status-not-submitted' ]" > {{ item.state === '1' ? '已提交' : '未提交' }} </view> <view class="score">总分: {{ item.score || '0' }}</view> </view> <button class="view-button" @click="handleView(item)">编辑/查看</button> </view> </view> <!-- 空数据提示 --> <view v-if="surveyList.length === 0" class="empty"> <text>暂无数据</text> </view> </view> <!-- 分页控件 --> <view v-if="surveyList.length > 0" class="pagination-container"> <picker mode="selector" :range="[5, 10, 20, 50]" :value="[5, 10, 20, 50].indexOf(pagination.size)" @change="handleSizeChange" class="page-size-picker" > <view class="picker"> 每页 {{ pagination.size }} 条 </view> </picker> <view class="pagination-buttons"> <button :disabled="pagination.current === 1" @click="handlePageChange(pagination.current - 1)" class="page-button prev-button" > 上一页 </button> <text class="page-info"> 第 {{ pagination.current }} 页 / 共 {{ Math.ceil(pagination.total / pagination.size) }} 页 </text> <button :disabled="pagination.current >= Math.ceil(pagination.total / pagination.size)" @click="handlePageChange(pagination.current + 1)" class="page-button next-button" > 下一页 </button> </view> <text class="total-records">共 {{ pagination.total }} 条记录</text> </view> </view> </view> </template> <style scoped> .container { padding: 20rpx; background-color: #f5f5f5; min-height: 100vh; } /* 卷标题*/ .title-group { display: flex; align-items: center; gap: 20rpx; } /* 表单布局优化 */ .form-row { display: flex; flex-wrap: wrap; gap: 20rpx; margin-bottom: 20rpx; } .form-group { margin-bottom: 25rpx; width: 100%; } .form-group-half { flex: 1; min-width: 300rpx; } .form-label { font-size: 28rpx; color: #606266; font-weight: 500; white-space: nowrap; flex-shrink: 0; /* 防止标签被压缩 */ } .title-input { flex: 1; /* 输入框占据剩余空间 */ min-width: 0; /* 防止溢出 */ } .form-input { width: 100%; height: 80rpx; padding: 0 20rpx; border: 1px solid #dcdfe6; border-radius: 8rpx; font-size: 28rpx; background-color: #fff; box-sizing: border-box; } /* 搜索卡片优化 */ .search-card { background: #fff; border-radius: 16rpx; padding: 25rpx; margin-bottom: 25rpx; box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05); } .button-group { display: flex; gap: 15rpx; flex-shrink: 0; } .search-button, .reset-button { width: 150rpx; height: 80rpx; line-height: 80rpx; font-size: 28rpx; border-radius: 8rpx; text-align: center; border: none; padding: 0; margin: 0; box-sizing: border-box; } /* 按钮悬停效果 */ .search-button:hover, .reset-button:hover { opacity: 0.9; transform: translateY(-2rpx); } .search-button:active, .reset-button:active { opacity: 1; transform: translateY(0); } .search-button { background-color: #409eff; color: #fff; } .reset-button { background-color: #f5f7fa; color: #606266; border: 1px solid #dcdfe6; } /* 被测评人选择器优化 */ .search-select-container { position: relative; width: 100%; } .input-container { position: relative; width: 100%; height: 80rpx; padding: 0 60rpx 0 20rpx; border: 1px solid #dcdfe6; border-radius: 8rpx; background-color: #fff; display: flex; align-items: center; box-sizing: border-box; } .selected-display { color: #303133; font-size: 28rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; } .placeholder-text { color: #c0c4cc; font-size: 28rpx; flex: 1; } .dropdown-icon { position: absolute; right: 20rpx; top: 50%; transform: translateY(-50%); font-size: 24rpx; color: #606266; } .dropdown-list { position: absolute; top: 100%; left: 0; right: 0; max-height: 400rpx; background: #fff; border: 1px solid #dcdfe6; border-radius: 8rpx; z-index: 1000; box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1); margin-top: 8rpx; } .search-box { padding: 15rpx; border-bottom: 1px solid #f0f2f5; } .search-input { width: 100%; height: 70rpx; padding: 0 20rpx; border: 1px solid #dcdfe6; border-radius: 8rpx; font-size: 28rpx; background-color: #f5f7fa; box-sizing: border-box; } .dropdown-scroll { max-height: 300rpx; } .dropdown-item { padding: 20rpx; font-size: 28rpx; color: #333; border-bottom: 1px solid #f0f2f5; } .dropdown-item.selected { background-color: #f5f7fa; color: #409eff; font-weight: 500; } .dropdown-item:last-child { border-bottom: none; } .dropdown-mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: transparent; z-index: 999; } .empty-option { padding: 20rpx; text-align: center; color: #999; font-size: 28rpx; } /* 状态选择器优化 */ .state-select-box { position: relative; width: 100%; height: 80rpx; padding: 0 60rpx 0 20rpx; border: 1px solid #dcdfe6; border-radius: 8rpx; font-size: 28rpx; background-color: #fff; display: flex; align-items: center; box-sizing: border-box; } .selected-state { color: #303133; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .state-dropdown { max-height: 300rpx; } /* 数据卡片优化 */ .data-card { background: #fff; border-radius: 16rpx; padding: 25rpx; box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.05); } .card-header { margin-bottom: 25rpx; } .refresh-button { background-color: #409eff; color: #fff; height: 70rpx; line-height: 70rpx; font-size: 28rpx; border-radius: 8rpx; border: none; } .data-card-item { background: #fff; border-radius: 12rpx; padding: 25rpx; margin-bottom: 25rpx; box-shadow: 0 2rpx 6rpx rgba(0,0,0,0.03); border: 1px solid #ebeef5; } .card-header-section { padding-bottom: 15rpx; border-bottom: 1px solid #f0f2f5; margin-bottom: 15rpx; } .card-title { font-size: 32rpx; font-weight: bold; color: #303133; line-height: 1.4; word-break: break-word; } .card-body-section { margin-bottom: 15rpx; } .card-row { display: flex; margin-bottom: 12rpx; font-size: 28rpx; } .card-label { color: #606266; width: 150rpx; flex-shrink: 0; } .card-value { color: #303133; flex: 1; word-break: break-word; } .card-footer-section { display: flex; justify-content: space-between; align-items: center; padding-top: 15rpx; border-top: 1px solid #f0f2f5; } .status-container { display: flex; align-items: center; gap: 15rpx; } .status-tag { padding: 6rpx 18rpx; border-radius: 40rpx; font-size: 24rpx; font-weight: 500; } .status-submitted { background-color: #f0f9eb; color: #67c23a; border: 1px solid #e1f3d8; } .status-not-submitted { background-color: #fef0f0; color: #f56c6c; border: 1px solid #fde2e2; } .score { font-size: 28rpx; color: #e6a23c; font-weight: 500; } .view-button { background-color: #409eff; color: #fff; height: 60rpx; line-height: 60rpx; padding: 0 25rpx; font-size: 26rpx; border-radius: 40rpx; border: none; } /* 分页样式优化 */ .pagination-container { margin-top: 30rpx; display: flex; flex-direction: column; align-items: center; gap: 15rpx; } .page-size-picker { width: 200rpx; height: 60rpx; border: 1px solid #dcdfe6; border-radius: 8rpx; text-align: center; line-height: 60rpx; font-size: 26rpx; background: #fff; } .pagination-buttons { display: flex; align-items: center; gap: 15rpx; } .page-button { height: 60rpx; line-height: 60rpx; padding: 0 25rpx; font-size: 26rpx; border-radius: 8rpx; background-color: #f5f7fa; color: #606266; border: 1px solid #dcdfe6; } .page-button:disabled { opacity: 0.5; background-color: #fafafa; } .page-info { font-size: 26rpx; color: #606266; } .total-records { font-size: 26rpx; color: #909399; } /* 加载状态样式 */ .loading-container { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 80rpx 0; } .loading-spinner { width: 70rpx; height: 70rpx; border: 6rpx solid #f3f3f3; border-top: 6rpx solid #3498db; border-radius: 50%; animation: spin 1s linear infinite; margin-bottom: 25rpx; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .loading-text { color: #666; font-size: 28rpx; } /* 空数据提示 */ .empty { text-align: center; padding: 80rpx 0; color: #999; font-size: 30rpx; } .form-row-bottom { display: flex; align-items: center; justify-content: space-between; gap: 20rpx; margin-top: 10rpx; } .state-group { flex: 1; display: flex; align-items: center; gap: 15rpx; } </style> 我想要被测评人和人员部门和问卷标题一样,文字和框在同一行
最新发布
07-26
<think>我们将调整被测评人和人员部门的布局,使标签和输入框在同一行显示。具体做法是使用Flex布局,并为每个表单项的容器设置合适的样式。 主要修改点: 1. 为被测评人和人员部门的容器(.form-group-half)添加Flex布局,使其内部的标签和输入框容器在同一行。 2. 调整标签和输入框容器的宽度比例,确保标签不会换行且输入框占据剩余空间。 3. 由于被测评人是一个自定义的下拉选择器,我们需要调整其内部容器的宽度。 注意:被测评人选择器目前是一个块级元素,我们需要将其设置为Flex布局并调整宽度。 修改步骤: 1. 在.form-group-half上设置display: flex,并让子元素垂直居中(align-items: center)。 2. 给.form-label设置固定宽度(比如150rpx)或者使用flex-shrink:0防止被压缩,同时设置文本不换行。 3. 给输入框容器(包括被测评人的选择器容器)设置flex:1,使其占据剩余空间。 但是,被测评人的选择器容器(.search-select-container)本身已经是块级元素,我们只需要调整它的宽度为100%即可,因为父容器已经是flex,它会自动扩展。 另外,由于被测评人的下拉列表是绝对定位,宽度设置为100%是相对于父容器(.search-select-container)的,所以不需要调整。 具体代码修改如下:</think>我将调整被测评人和人员部门的布局,使标签和输入框在同一行显示。以下是优化后的完整代码: ```html <template> <view class="container"> <!-- 搜索表单区域 --> <view class="search-card"> <!-- 问卷标题 --> <view class="form-group title-group"> <text class="form-label">问卷标题:</text> <input v-model="formData.dcWjTitle" placeholder="请输入问卷标题" class="form-input title-input" /> </view> <view class="form-row"> <!-- 被测评人选择器 --> <view class="form-group form-group-half bdr-group"> <view class="label-input-group"> <text class="form-label">被测评人:</text> <view class="search-select-container"> <view class="input-container" @click="showBdrList = true"> <!-- 已选项显示 --> <view v-if="formData.dcId.length > 0" class="selected-display"> {{ selectedBdrLabel }} </view> <!-- 占位符 --> <text v-else-if="showBdrPlaceholder" class="placeholder-text"> 请选择被测评人 </text> <!-- 下拉箭头 --> <view class="dropdown-icon"> <text>▼</text> </view> </view> <!-- 下拉列表 --> <view v-if="showBdrList" class="dropdown-list"> <view class="search-box"> <input v-model="bdrSearchKeyword" placeholder="搜索被测评人" class="search-input" @input="filterBdrOptions" /> </view> <scroll-view scroll-y="true" class="dropdown-scroll"> <view v-for="(item, index) in filteredBdrOptions" :key="index" class="dropdown-item" :class="{ 'selected': formData.dcId[0] === item.value }" @click="handleBdrSelect(item)" > {{ item.label }} </view> <view v-if="filteredBdrOptions.length === 0" class="empty-option"> 无匹配结果 </view> </scroll-view> </view> <!-- 遮罩层 --> <view v-if="showBdrList" class="dropdown-mask" @click="showBdrList = false" ></view> </view> </view> </view> <!-- 人员部门 --> <view class="form-group form-group-half dept-group"> <view class="label-input-group"> <text class="form-label">人员部门:</text> <input v-model="formData.dcDept" placeholder="请输入部门" class="form-input" /> </view> </view> </view> <!-- 提交状态和按钮组 --> <view class="form-row-bottom"> <!-- 提交状态 --> <view class="state-group"> <text class="form-label">提交状态:</text> <view class="search-select-container"> <view class="state-select-box" @click="toggleStateList"> <text class="selected-state"> {{ getStateLabel(formData.state) }} </text> <view class="dropdown-icon"> <text>▼</text> </view> </view> <!-- 状态下拉列表 --> <view v-if="showStateList" class="dropdown-list state-dropdown"> <view v-for="(state, index) in stateOptions" :key="index" class="dropdown-item" :class="{ 'selected': formData.state === state.value }" @click="handleStateSelect(state)" > {{ state.label }} </view> </view> <!-- 遮罩层 --> <view v-if="showStateList" class="dropdown-mask" @click="showStateList = false" ></view> </view> </view> <!-- 按钮组 --> <view class="button-group"> <button class="search-button" @click="handleSearch">搜索</button> <button class="reset-button" @click="handleReset">重置</button> </view> </view> </view> <!-- 数据显示区域 --> <!-- 保持不变 --> </view> </template> <style scoped> /* 新增样式 */ .label-input-group { display: flex; align-items: center; gap: 15rpx; width: 100%; } /* 被测评人选择器容器 */ .search-select-container { flex: 1; min-width: 0; } /* 部门输入框 */ .dept-group .form-input { flex: 1; min-width: 0; } /* 响应式调整 */ @media (max-width: 768px) { .bdr-group .label-input-group, .dept-group .label-input-group { flex-direction: column; align-items: flex-start; gap: 10rpx; } .search-select-container, .dept-group .form-input { width: 100%; } } </style> ``` ### 主要修改点: 1. **添加包裹容器**: - 为每个表单项添加 `label-input-group` 容器 ```html <view class="label-input-group"> <text class="form-label">被测评人:</text> <!-- 输入框或选择器 --> </view> ``` 2. **Flex 布局实现同行显示**: ```css .label-input-group { display: flex; align-items: center; gap: 15rpx; width: 100%; } ``` 3. **标签优化**: ```css .form-label { white-space: nowrap; flex-shrink: 0; } ``` 4. **输入元素自适应**: ```css .search-select-container, .dept-group .form-input { flex: 1; min-width: 0; } ``` 5. **响应式设计**: ```css @media (max-width: 768px) { .label-input-group { flex-direction: column; align-items: flex-start; } .search-select-container, .dept-group .form-input { width: 100%; } } ``` ### 实现原理: 1. **Flex 容器**:`.label-input-group` 作为 Flex 容器,使标签和输入元素水平排列 2. **空间分配**: - 标签使用 `flex-shrink: 0` 保持固定宽度 - 输入元素使用 `flex: 1` 占据剩余空间 3. **溢出处理**:`min-width: 0` 解决 flex 容器中的溢出问题 4. **响应式切换**: - 在小屏幕上切换为垂直布局 - 输入元素宽度设为100% ### 修改效果: 1. **被测评人**: - 标签和选择框在同一行显示 - 选择框自适应剩余空间 - 小屏幕下标签和选择框垂直排列 2. **人员部门**: - 标签和输入框在同一行显示 - 输入框自适应剩余空间 - 小屏幕下标签和输入框垂直排列 这样修改后,所有表单字段的标签和输入元素都保持在同一行,视觉上更加整齐一致,同时在不同屏幕尺寸下保持良好的响应式效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值