如何在不同div中使用TailwindCSS peer标记实现表单切换?
解决TailwindCSS Peer标记在嵌套Div中失效的问题
问题原因
Tailwind的peer和peer-checked基于CSS通用兄弟选择器(~)工作,要求带peer类的元素(此处为单选按钮)与被控制元素(表单区块)必须是同一父级下的兄弟元素。若将单选按钮放入嵌套Div,二者的兄弟关系被打破,peer-checked无法定位目标元素,导致表单始终隐藏。
解决方案
保留实际单选按钮与表单区块的兄弟关系,同时用自定义元素模拟单选框外观,将模拟元素和标签放入布局Div实现自定义样式——既满足布局需求,又不破坏Peer的关联逻辑。
修改后的完整代码
<form action="{% url 'requestservice:req_service' %}" method="POST"> <!-- 实际单选按钮:隐藏但保留功能,与表单区块保持兄弟关系 --> <input type="radio" id="single" value="SINGLE" class="peer/single absolute opacity-0 cursor-pointer" name="property_type" checked> <!-- 自定义布局Div:包含模拟单选框和标签 --> <div class="flex items-center cursor-pointer mb-3" onclick="document.getElementById('single').checked = true"> <div class="w-4 h-4 rounded-full border-2 border-gray-300 transition-all peer-checked/single:border-sky-500 peer-checked/single:bg-sky-500 peer-checked/single:bg-[url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><circle cx="10" cy="10" r="6" fill="white"/></svg>')] bg-no-repeat bg-center"></div> <label for="single" class="ml-2 text-sm peer-checked/single:text-sky-500">Single Unit</label> </div> <input type="radio" id="multiple" value="MULTIPLE" class="peer/multiple absolute opacity-0 cursor-pointer" name="property_type"> <div class="flex items-center cursor-pointer mb-3" onclick="document.getElementById('multiple').checked = true"> <div class="w-4 h-4 rounded-full border-2 border-gray-300 transition-all peer-checked/multiple:border-sky-500 peer-checked/multiple:bg-sky-500 peer-checked/multiple:bg-[url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><circle cx="10" cy="10" r="6" fill="white"/></svg>')] bg-no-repeat bg-center"></div> <label for="multiple" class="ml-2 text-sm peer-checked/multiple:text-sky-500">Multiple D. Unit</label> </div> <!-- Multiple Unit表单:与单选按钮保持兄弟关系,peer-checked正常生效 --> <div class="hidden peer-checked/multiple:block bg-white px-2 py-2 w-full space-y-2 md:space-y-3 rounded-xl"> <div class="block"> <p class="font-medium text-gray-950 text-sm"> Name of property: </p> <input type='text' name="multiple_property_name" class="w-full p-1 focus:border-1 focus:outline-yellow-300 border border-red-100 shadow-md shadow-red-100 rounded-lg " placeholder="Property name"> </div> <div class="font-medium flex space-x-5"> <p class="font-medium text-sm"> Central Server Room Avaliable: </p> <input type="radio" name="central_server_room"> </div> <div class="block "> <p class="font-medium text-sm"> Number of houses in MDU </p> <input name="number_of_houses" placeholder="Number of houses" class="w-full p-1 focus:border-1 focus:outline-yellow-300 border border-red-100 shadow-md shadow-red-100 rounded-lg" type="number"> </div> </div> <!-- Single Unit表单:与单选按钮保持兄弟关系,peer-checked正常生效 --> <div class="hidden peer-checked/single:block bg-white px-2 py-2 space-y-2 w-full rounded-xl"> <div class="block space-y-1"> <p class="font-medium"> Name of property: </p> <input type='text' name="single_property_name" class="w-full p-1 focus:border-1 focus:outline-yellow-300 border border-red-100 shadow-md shadow-red-100 rounded-lg " placeholder="Property name"> </div> </div> <div class="bg-inherit w-full h-3"></div> <div class="flex justify-center"> <input type="submit" class="bg-red-500 font-medium p-1 text-white text-center rounded-lg" value="Request Service"> </div> </form>
关键说明
- 隐藏原生单选框:用
absolute opacity-0隐藏原生单选按钮,但保留name属性和选中状态功能,确保单选逻辑正常。 - 模拟单选框外观:用圆形Div模拟单选按钮样式,通过
peer-checked控制其边框色、背景色及选中后的内部白点(SVG实现)。 - 布局Div交互:给布局Div添加
onclick事件,点击时触发对应原生单选框的选中状态,保证用户交互正常。 - 保留兄弟关系:原生单选框与表单区块始终处于同一父级,
peer-checked可正常触发显示/隐藏逻辑。 - 修正原代码错误:原代码中第二个标签的
for属性误写为draft,已修正为multiple,确保标签与单选框关联正确。
内容的提问来源于stack exchange,提问作者O.G Bellz
相关产品推荐
相关产品推荐

