CSS/HTML5简洁蓝色带下拉框自定义搜索组件

本文介绍了如何使用CSS和HTML5创建一个简洁的蓝色搜索组件,该组件包含下拉框,并强调了纯CSS控制的重要性。由于CSS无法直接控制`<option>`标签样式,作者建议使用自定义下拉组件来实现美观效果。

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

CSS/HTML5简洁蓝色带下拉框自定义搜索组件

说明

演示效果分辨率为1980x1080分辨率效果
高度可定制修改
纯css代码控制
select可以通过css控制 /option不支持css控制样式 想做出漂亮的下拉列表最后是自定义下拉组件

css代码

		.input-group {
				width: 550px;
				height: 50px;
				margin: 0 auto;
				margin-top: 46px;
				border: 1px solid #cccccc;

			}

			input[type="text"] {
				height: 48px;
				width: 340px;
				background: #FFFFFF;
				font-size: 14px;
				float: left;
				border: 0px solid #FFF;/* 必须加 可能配合下一句使用 */
				border-left: 1px solid #c0c0c0;
				padding-left: 15px;
				outline: none;

			}

			input,
			select,
			a:focus {
				outline: none;
			}

			button[type="submit"] {
				height: 50px;
				width: 50px;
				background: #2699FB;
				border: 0px solid #ff7496;
				float: right;
				cursor: pointer;

			}

			select[id="select"] {
				height: 50px;
				width: 142px;
				border: 0px solid #ff7496;
				float: left;
				color: #8f9db3;
				background-color: #FFF;
				padding-left: 15px;
				/* 鼠标触碰光标变手势 */
				cursor: pointer;
				/* 清除默认样式 */
				appearance: none;
				-webkit-appearance: none;
				-moz-appearance: none;
			}

			div[class="select"]:after {
			/* 给select添加右侧下拉图标 */
				content: "";
				width: 14px;
				height: 8px;
				background: url(下拉.png) no-repeat center;
				position: relative;
				float: left;
				margin-left: -30px;
				top: 22px;
				pointer-events: none;
			}

html代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
	</head>
	<body>
	<!-- 带有一些vue语法 使用时可删除掉 -->
<div class="input-group">
			<div class="select">
				<select id="select" v-model="selected">
					<option class="option" value="today">当日代理人</option>
					<option class="option" value="history">历史代理人</option>
				</select></div>
			<input type="text" id="input" class=" " placeholder="请输入代理人姓名进行查询" onfocus="this.placeholder=' ' " onblur=" this.placeholder='请输入代理人姓名进行查询' "
			 v-model="searchValue">
			 <!-- placeholder的点击消失及为空时点击其他继续显示提示  -->
			<span class=" ">
				<button id="button" class=" " type="submit" @click="goToSearch"><img src="搜索.png" /></button>
			</span>
		</div>
	</body>
</html>

演示效果图

演示效果图上的图标、图片类,我已经上传到博客文件里。不能设置免费下载,大家体谅一下或者可以加我QQ来获取文件 1209793794
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<think>根据用户需求,我们需要实现一个多选下拉,其中包含复选选中状态的高亮显示。同时,查询功能需要精准匹配(国家代码或国家名称的完全匹配)。在之前的实现中,我们已经通过自定义样式和状态管理实现了选中项的高亮显示。现在,用户特别关注查询结果中复选的选中状态,我们需要确保: 1. 在查询结果中,已选中的项要显示为选中状态(复选被勾选)。 2. 同时,通过样式(背景色、边等)高亮显示已选中的项。 注意:在Element UI或类似组件中,多选下拉通常会在每个选项前显示一个复选。但是,用户提供的示例代码中使用了自定义模板(slot-scope),所以我们需要在自定义模板中同时处理复选的选中状态和高亮样式。 由于原问题中使用了`gtm-dict-select`组件(假设它类似于Element UI的Select组件),我们可以利用组件的多选特性,通过`v-model`绑定选中的值,然后根据当前选项的值是否在选中数组中来决定复选的选中状态和高亮样式。 我们将进行以下调整: - 在自定义模板中添加复选,并绑定选中状态。 - 同时,我们保留之前的高亮样式(背景色、左侧边等)。 注意:由于`gtm-dict-select`组件内部可能已经提供了复选,但用户使用了自定义模板覆盖了默认的选项渲染,因此我们需要手动添加复选并同步选中状态。 然而,在Element UI中,当使用自定义模板时,复选需要手动添加。我们可以这样实现: 在模板中,使用`el-checkbox`组件来显示复选,并绑定选中状态。同时,整个选项的样式根据选中状态设置高亮。 但是,请注意:我们不应该在自定义模板中再添加一个复选,因为这样可能会破坏组件的原有行为(比如点击事件)。另一种做法是使用组件的复选,但自定义模板会覆盖整个选项,所以我们需要在自定义模板中重新实现复选。 考虑到兼容性和行为一致性,我们可以在自定义模板中模拟复选的显示,但实际选中状态由组件的`v-model`控制。然而,这样需要我们自己处理点击事件来更新选中状态,这可能会很复杂。 因此,我建议使用组件库提供的默认复选,同时自定义选项内容。在Element UI中,可以通过`el-option`的默认插槽来自定义选项内容,同时保留复选。但是,在用户提供的组件`gtm-dict-select`中,我们不清楚是否支持在自定义模板中保留复选。 为了简化,这里假设`gtm-dict-select`组件类似于Element UI的`el-select`,并且支持多选和自定义选项模板。在Element UI中,如果我们在`el-option`中使用自定义内容,复选仍然会显示,除非我们使用`slot`覆盖了整个选项。因此,如果我们想同时显示复选自定义内容,需要将复选包含在自定义模板中。 具体实现如下: 1. 在自定义模板中,添加一个复选,并使用`isSelected`方法判断当前选项是否被选中,从而设置复选的选中状态。 2. 注意:我们不应该通过复选的`v-model`来直接修改选中状态,因为整个下拉的选中状态是由组件的`v-model`(即`selectedCountries`)控制的。所以,我们只将复选用于显示状态,而实际的选中状态切换由组件本身处理(即我们不需要在自定义模板中处理点击事件,因为组件会处理)。 但是,这样会有一个问题:当用户点击选项时,组件会处理选中状态切换,而我们自定义模板中的复选只是被动显示状态。这符合预期。 然而,如果用户点击复选而不是选项的其他部分,我们希望也能触发选中状态切换。所以,我们需要在复选上阻止事件冒泡,并手动触发选中状态的切换?这可能会很复杂。 因此,另一种做法是:不使用复选,而是通过整个选项的点击来切换选中状态(这是组件默认的行为)。我们只需要在自定义模板中模拟复选的显示(用一个勾选图标表示选中状态),而不使用真正的复选组件。这样,点击整个选项就可以触发组件的默认行为(切换选中状态),同时我们通过图标来显示是否选中。 在之前的代码中,我们已经这样做了:在选中项后面添加了一个✓图标。所以,我们可以去掉复选,而用图标代替,这样既简洁又避免了事件处理的复杂性。 但是,用户明确要求“复选选中状态”,所以我们需要显示复选。因此,我们决定使用真正的复选,并使其状态与组件的选中状态同步,同时处理复选的点击事件,以避免与选项的点击事件冲突。 考虑到时间,我们采用以下方案: 在自定义模板中,我们添加一个复选,并设置其选中状态为当前选项是否被选中。当点击复选时,我们阻止事件冒泡(防止触发选项的点击事件),然后手动切换当前选项的选中状态。 具体步骤: 1. 在模板中添加`el-checkbox`(如果使用Element UI),或者使用一个自定义样式的复选。 2. 复选的`checked`状态绑定`isSelected(row.value)`。 3. 当复选被点击时,调用`toggleSelection(row)`方法,并阻止事件冒泡。 这样,当用户点击复选时,我们手动切换选中状态;当用户点击选项的其他地方时,由组件默认处理(也会切换选中状态)。为了避免重复触发,我们需要在复选点击时阻止事件冒泡。 由于我们使用的是自定义组件`gtm-dict-select`,这里我们使用原生的checkbox来实现,以避免引入Element UI的checkbox组件。 修改后的模板部分: ```html <template slot-scope="{ row }"> <div :class="['option-item', { 'selected-highlight': isSelected(row.value) }]"> <!-- 自定义复选 --> <label class="custom-checkbox"> <input type="checkbox" :checked="isSelected(row.value)" @click.stop="toggleSelection(row.value)" > <span class="checkmark"></span> </label> <span class="selectOpLeft">{{ row.label }}</span> <span class="selectOpRight">{{ row.code }}</span> </div> </template> ``` 在方法中添加`toggleSelection`: ```javascript toggleSelection(value) { const index = this.selectedCountries.indexOf(value); if (index >= 0) { // 如果已选中,则移除 this.selectedCountries.splice(index, 1); } else { // 如果未选中,则添加 this.selectedCountries.push(value); } // 为了触发响应式更新,需要重新赋值(因为直接修改数组,Vue可能无法检测到变化,所以用splice或重新赋值) this.selectedCountries = [...this.selectedCountries]; // 触发change事件(因为组件可能监听这个数组的变化) this.$nextTick(() => { this.handleSelectionChange(this.selectedCountries); }); } ``` 同时,我们需要在样式中添加自定义复选的样式。 但是,请注意,这种方法可能会导致与组件原有的事件处理产生冲突(因为组件本身也会处理选项的点击事件)。所以,我们还需要在选项的根元素上阻止点击事件的默认行为?不,我们只需要在复选上阻止冒泡,这样点击复选不会触发整个选项的点击事件,而点击选项的其他地方仍然会触发。 然而,在组件内部,整个选项的点击事件可能是由组件库处理的,我们无法直接控制。因此,我们可以在选项的根元素上添加一个点击事件,并手动触发选中状态的切换,同时阻止默认行为?这样可能会干扰组件的正常工作。 考虑到复杂性,我建议不使用真正的复选,而是用图标模拟,这样用户点击整个选项切换选中状态,同时图标显示选中状态。这样既简单又符合大多数UI库的交互方式。 因此,我们回到之前使用图标的方案,并称之为“复选效果”,但实际上是一个选中图标。这样用户可以看到选中状态,并且交互行为由组件库处理,无需我们手动管理状态。 最终,我们决定不添加真正的复选,而是使用一个图标(✓)来表示选中状态,并通过高亮样式来突出选中项。这样也能满足用户要求,因为图标可以视为复选的替代。 所以,我们保留之前的实现(在选中项后面显示✓图标),并加强高亮样式。 但是,如果用户坚持要看到复选(即一个方里面打勾),那么我们就需要自定义一个复选样式。 我们可以用CSS实现自定义复选: 修改模板: ```html <template slot-scope="{ row }"> <div :class="['option-item', { 'selected-highlight': isSelected(row.value) }]"> <!-- 自定义复选样式 --> <span class="custom-checkbox"> <span v-if="isSelected(row.value)" class="checkmark">✓</span> </span> <span class="selectOpLeft">{{ row.label }}</span> <span class="selectOpRight">{{ row.code }}</span> </div> </template> ``` 然后添加样式: ```css .custom-checkbox { display: inline-block; width: 16px; height: 16px; border: 1px solid #dcdfe6; border-radius: 2px; margin-right: 8px; position: relative; } .checkmark { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: #fff; background-color: #1890ff; border-color: #1890ff; } ``` 这样,未选中时显示一个空,选中时显示一个蓝色背景的,里面有一个白色的✓。 但是,这个自定义复选只是一个静态展示,点击整个选项仍然由组件库处理切换选中状态。 因此,我们不需要处理点击事件,因为组件库已经处理了。 综上所述,我们提供以下完整代码:</think>根据您的需求,我将实现一个有精准查询功能的多选下拉,并确保选中项的复选状态清晰可见,同时添加高亮效果增强视觉区分: ```html <template> <div class="custom-multi-select"> <gtm-dict-select v-model="selectedCountries" ref="countrySelect" :filter-method="handleFilter" remote reserve-keyword :options="filteredOptions" multiple filterable clearable @change="handleSelectionChange" @visible-change="handleDropdownVisible" > <template slot-scope="{ row }"> <!-- 添加复选和选中状态指示 --> <div :class="['option-item', { 'selected-highlight': isSelected(row.value) }]"> <span class="checkbox-indicator"> <input type="checkbox" :checked="isSelected(row.value)" @click.stop="toggleSelection(row.value)" > <span class="checkmark"></span> </span> <span class="selectOpLeft">{{ row.label }}</span> <span class="selectOpRight">{{ row.code }}</span> </div> </template> </gtm-dict-select> </div> </template> <script> export default { data() { return { selectedCountries: [], // 存储选中项的值 optionsCountryName: [ { value: 'us', label: 'United States', code: 'US' }, { value: 'uk', label: 'United Kingdom', code: 'UK' }, { value: 'cn', label: 'China', code: 'CN' }, { value: 'jp', label: 'Japan', code: 'JP' }, { value: 'kr', label: 'South Korea', code: 'KR' }, { value: 'de', label: 'Germany', code: 'DE' }, { value: 'fr', label: 'France', code: 'FR' } ], filteredOptions: [], searchKeyword: '' }; }, mounted() { this.filteredOptions = [...this.optionsCountryName]; }, methods: { // 精准过滤方法 handleFilter(value) { this.searchKeyword = value; const keywords = value.split(/[\s,]+/) .filter(k => k.trim() !== '') .map(k => k.toLowerCase()); if (keywords.length === 0) { return [...this.optionsCountryName]; } // 精准匹配:标签或代码完全等于关键词 const matchedOptions = this.optionsCountryName.filter(({ label, code }) => { const normalizedLabel = String(label).toLowerCase(); const normalizedCode = String(code).toLowerCase(); return keywords.some(keyword => normalizedLabel === keyword || normalizedCode === keyword ); }); // 合并已选中项(确保始终显示) const selectedOptions = this.optionsCountryName.filter(option => this.selectedCountries.includes(option.value) ); // 合并并去重 const allOptions = [...selectedOptions, ...matchedOptions]; return Array.from(new Map(allOptions.map(item => [item.value, item])).values()); }, // 处理选中状态变化 handleSelectionChange(selected) { this.selectedCountries = selected; // 刷新列表保持选中项可见 this.filteredOptions = this.handleFilter(this.searchKeyword); }, // 检查选项是否被选中 isSelected(value) { return this.selectedCountries.includes(value); }, // 切换选中状态 toggleSelection(value) { const index = this.selectedCountries.indexOf(value); if (index >= 0) { this.selectedCountries.splice(index, 1); } else { this.selectedCountries.push(value); } // 触发状态更新 this.handleSelectionChange([...this.selectedCountries]); }, // 当下拉显示/隐藏时 handleDropdownVisible(isVisible) { if (isVisible) { // 当下拉显示时,确保选中项可见 this.$nextTick(() => { this.filteredOptions = this.handleFilter(this.searchKeyword); }); } } } }; </script> <style scoped> .custom-multi-select { width: 300px; } /* 选项基础样式 */ .option-item { display: flex; align-items: center; padding: 8px 12px; transition: all 0.2s ease; cursor: pointer; } /* 未选中状态悬停效果 */ .option-item:hover { background-color: #f5f7fa; } /* 选中项高亮样式 */ .option-item.selected-highlight { background-color: #ecf5ff; border-left: 3px solid #409eff; font-weight: 500; } /* 标签和代码样式 */ .selectOpLeft { flex: 1; margin-left: 8px; } .selectOpRight { width: 40px; text-align: right; color: #909399; font-size: 12px; } /* 复选样式 */ .checkbox-indicator { position: relative; display: inline-block; width: 16px; height: 16px; } .checkbox-indicator input { position: absolute; opacity: 0; cursor: pointer; z-index: 1; width: 100%; height: 100%; } .checkmark { position: absolute; top: 0; left: 0; height: 16px; width: 16px; background-color: #fff; border: 1px solid #dcdfe6; border-radius: 3px; transition: all 0.2s; } /* 选中状态下的复选样式 */ .option-item.selected-highlight .checkmark { background-color: #409eff; border-color: #409eff; } .option-item.selected-highlight .checkmark::after { content: ""; position: absolute; left: 5px; top: 2px; width: 4px; height: 8px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } /* 下拉头部选中项显示 */ .selected-tags { display: flex; flex-wrap: wrap; gap: 4px; padding: 4px; } .selected-tag { background-color: #ecf5ff; color: #409eff; border-radius: 3px; padding: 2px 6px; font-size: 12px; display: flex; align-items: center; } .selected-tag .remove-icon { margin-left: 4px; cursor: pointer; } </style> ``` ### 核心功能说明: 1. **精准查询与复选状态** - 支持完全匹配查询(代码或名称) - 复选状态实时反映选中状态 - 自定义复选样式增强视觉识别 - 选中项自动高亮(蓝色背景+左侧边) 2. **交互优化** - 点击复选直接切换选中状态 - 悬停效果增强交互反馈 - 已选项始终显示在查询结果中 - 支持多选操作和清除功能 3. **视觉设计** - 自定义复选设计(未选中:空心,选中:蓝色实心+对勾) - 选中项高亮:蓝色背景 + 左侧边 - 清晰区分标签和代码(标签加粗,代码灰色小字) - 平滑状态过渡动画 4. **状态管理** - 使用 `selectedCountries` 数组管理选中状态 - `isSelected()` 方法检查选项选中状态 - `toggleSelection()` 处理复选点击事件 - 实时同步查询结果与选中状态 ### 使用说明: 1. **查询操作**: - 输入国家代码(如"CN")或名称(如"China") - 支持逗号分隔多关键词(如"US, JP") 2. **选中操作**: - 点击复选直接切换选中状态 - 选中项自动高亮显示 - 多选支持:可同时选择多个国家 3. **状态识别**: - 选中状态:蓝色背景 + 左侧蓝边 + 实心复选 - 未选中状态:白色背景 + 空心复选 - 悬停状态:浅灰色背景
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值