Django中Crispy Forms的ChoiceField下拉选项悬停样式修改
解决方案
首先明确:原生HTML的<option>元素的:hover伪类在多数现代浏览器中不被支持,这就是你直接写select option:hover无效的核心原因。另外,你代码里的类名存在拼写错误(boostrap-select应为bootstrap-select),如果使用了bootstrap-select插件,它会将原生select转换为自定义的<ul>/<li>结构模拟下拉选项,需要针对插件生成的DOM写CSS。
情况1:使用bootstrap-select插件
1. 修正forms.py中的类名拼写
select_cancer = forms.ChoiceField( label='Cancer', choices=ExtractCancer(), required=False, widget=forms.Select(attrs={'class':'bootstrap-select'}) # 修正拼写错误 )
2. 编写插件对应的CSS
/* 下拉框容器样式 */ .bootstrap-select { background-color: black; color: white; } /* 下拉菜单容器 */ .bootstrap-select .dropdown-menu { background-color: black; } /* 下拉选项默认样式 */ .bootstrap-select .dropdown-menu > li > a { color: white; background-color: black; } /* 鼠标悬停时的选项样式 */ .bootstrap-select .dropdown-menu > li > a:hover { background-color: blue; color: white; }
注意:确保已正确引入bootstrap-select的官方CSS和JS文件,否则插件无法正常渲染自定义结构。
情况2:使用原生Bootstrap(无额外插件)
原生select的option悬停无法直接用CSS控制,建议改用Bootstrap的Dropdown组件自定义下拉菜单,实现完全样式控制:
1. 自定义Widget(forms.py)
from django.forms.widgets import Widget from django.utils.safestring import mark_safe class CustomCancerDropdown(Widget): def __init__(self, choices, attrs=None): super().__init__(attrs) self.choices = choices def render(self, name, value, attrs=None, renderer=None): options_html = "" selected_label = "Select Cancer" # 生成下拉选项HTML for val, label in self.choices: selected_class = "selected" if val == value else "" if val == value: selected_label = label options_html += f'<li><a class="dropdown-item {selected_class}" data-value="{val}">{label}</a></li>' # 返回带隐藏input的自定义下拉结构(用于提交表单值) return mark_safe(f''' <div class="dropdown"> <button class="btn custom-dropdown-btn dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> {selected_label} </button> <ul class="dropdown-menu custom-dropdown-menu"> {options_html} </ul> <input type="hidden" name="{name}" value="{value or ''}"> </div> ''') # 在表单中使用自定义Widget select_cancer = forms.ChoiceField( label='Cancer', choices=ExtractCancer(), required=False, widget=CustomCancerDropdown(choices=ExtractCancer()) )
2. 自定义CSS样式
/* 下拉按钮样式 */ .custom-dropdown-btn { background-color: black; border-color: black; color: white; } .custom-dropdown-btn:hover { background-color: black; border-color: black; } /* 下拉菜单容器 */ .custom-dropdown-menu { background-color: black; } /* 下拉选项默认样式 */ .custom-dropdown-menu .dropdown-item { color: white; } /* 鼠标悬停样式 */ .custom-dropdown-menu .dropdown-item:hover { background-color: blue; color: white; } /* 选中选项的高亮样式 */ .custom-dropdown-menu .dropdown-item.selected { background-color: blue; }
3. 添加JavaScript同步选中值
document.addEventListener('DOMContentLoaded', function() { const dropdownItems = document.querySelectorAll('.custom-dropdown-menu .dropdown-item'); const hiddenInput = document.querySelector('input[name="select_cancer"]'); const dropdownBtn = document.querySelector('.custom-dropdown-btn'); dropdownItems.forEach(item => { item.addEventListener('click', function() { // 更新选中状态 dropdownItems.forEach(i => i.classList.remove('selected')); this.classList.add('selected'); // 同步隐藏input的表单值 hiddenInput.value = this.getAttribute('data-value'); // 更新按钮显示文本 dropdownBtn.textContent = this.textContent; }); }); });
内容的提问来源于stack exchange,提问作者David Kaplan
相关产品推荐
相关产品推荐

