输入在标签内时的CSS复选框和单选按钮?

Posted

技术标签:

【中文标题】输入在标签内时的CSS复选框和单选按钮?【英文标题】:CSS checkboxes & radio buttons when input is inside label? 【发布时间】:2012-10-30 07:08:54 【问题描述】:

我在这里广泛搜索了这个问题的答案,但还没有完全找到我正在寻找的东西。找到了这个CSS - How to Style a Selected Radio Buttons Label?,但答案涉及更改标记,这是我想避免的事情,我将在下面解释。

我正在尝试将自定义 css3 复选框和单选按钮添加到我的 XenForo 论坛主题中,并且我在此阅读的所有教程在输入后都有标签:

<input type="checkbox" id="c1" name="cc" />
<label for="c1">Check Box 1</label>

但在 XenForo 的标记中,输入位于标签内:

<label for="ctrl_enable_rte">
<input type="checkbox" name="enable_rte" value="1" id="ctrl_enable_rte" xen:checked "$visitor.enable_rte" />
xen:phrase use_rich_text_editor_to_create_and_edit_messages
</label>

我调查了为什么会这样,但是当标记是这种方式时,没有找到与自定义 CSS 复选框/单选按钮相关的任何内容。我想避免更改标记,因为我在这里处理的是一个论坛系统,这将涉及编辑一堆核心模板......然后我必须在每次论坛软件时更新标记发布更新(假设模板已更改)。

我尝试创建适用于此类标记的 CSS 规则,但到目前为止我还没有成功。我对 CSS 不太熟悉,没有记住每个选择器,而且伪类对我来说仍然很陌生,所以我希望这里有人能说明这是否可行,如果可以,我是如何做到的可能会去做。我的精灵已经准备好了,我只需要弄清楚 CSS。

我的主要问题是我不知道如何选择标签(当然只有与这些输入相关的标签)。通常类似

input[type="checkbox"] + label

已使用,但是当标签不在输入之后而是在输入之外/之前...我该如何选择它?

【问题讨论】:

不是为选中的输入选择标签(我相信在这种情况下不能用 CSS 完成,因为“父”选择器不存在),可能有 CSS 的解决方法。你具体想做什么? @WesleyMurch 我正在尝试通过添加一个精灵图像来自定义所有复选框/单选按钮,该精灵图像具有为每个不同状态(选中、悬停、焦点、活动、禁用)定义的背景位置。我不确定我可以选择什么来实现这一点,所有关于自定义 css3 复选框等的教程在输入之后都有标签,CSS 专门反映了这一点。抱歉,如果我没有准确或足够详细地回答您的问题。 您的回复很明确,但您的限制并不完全。因此,除了将输入保留在标签内的要求之外,您是否能够编辑 html?例如,您可以在每个复选框后添加一个空的&lt;span&gt;,还是将相邻的内容合并为一个?如果没有,恐怕你会被 javascript 卡住(这并不是一件坏事)。 【参考方案1】:

如果您可以编辑标记以包裹实际的标签文本,例如:

<label>
    <input type="checkbox">
    <span>One</span>
</label>
<label>
    <input type="checkbox">
    <span>Two</span>
</label>
<label>
    <input type="checkbox" disabled>
    <span>Three</span>
</label>

您可以使用 CSS 实现一些技巧:

label 
    position:relative;   
    cursor:pointer;

label [type="checkbox"] 
    display:none; /* use your custom sprites instead as background on the span */

[type="checkbox"] + span 
    display:inline-block;
    padding:1em;

:checked + span 
    background:#0f0;

[type="checkbox"][disabled] + span 
    background:#f00;  
​

演示:

label 
  position: relative;
  cursor: pointer;


label [type="checkbox"] 
  display: none;


[type="checkbox"]+span 
  display: inline-block;
  padding: 1em;


:checked+span 
  background: #0f0;
  display: inline-block;


[type="checkbox"][disabled]+span 
  background: #f00;
<label>
    <input type="checkbox">
    <span>One</span>
</label>
<label>
    <input type="checkbox">
    <span>Two</span>
</label>
<label>
    <input type="checkbox" disabled>
    <span>Three</span>
</label>

http://jsfiddle.net/dMhDM/1/

请记住,如果浏览器不支持:checked,这将失败。

这与其他解决方案基本相同,但stying是在span而不是label上完成的。

【讨论】:

虽然这将涉及编辑我想要避免的 HTML,但在某些模板模块中使用正则表达式可能会实现这种方法,这在论坛更新期间会更好和无缝。唯一的缺点是我仍然需要修改 73 个模板以及来自未来更新或插件的任何新模板。或许我应该放弃纯 CSS 解决方案,转而研究让 JS 在所有情况下都能完美运行。感谢您抽出宝贵时间回复并撰写示例,非常感谢。我相信它会帮助那些不像我这样特殊情况的人。 或者您可以简单地修改xen:phrase ... 输出的任何内容以将其包装在一个跨度中。我个人会使用 js,但我的公司通常支持 IE7 - 我嫉妒那些每天实际使用 CSS3 的人。 啊,是的,没想到。绝对是另一种可能性,尽管它可能会在某些领域引起一些怪异。显然,JS 似乎是唯一的出路……它会增加 CSS 所缺乏的额外浏览器兼容性。我只需要找出一个适合我的情况的好的 JS 解决方案。再次感谢。 简单的 js 解决方案是在选中或取消选中复选框时向包装器标签添加一个类。 我知道这已经过时了,但是,如果您遵循此示例,请考虑在输入上使用视觉隐藏作为显示:无将其从 DOM 流中删除,因此禁用键盘控件并制作它不太容易访问。【参考方案2】:

恕我直言,通过 PURE CSS 不搞乱 html 的最佳方法是

 input[type="checkbox"] 
     position: relative;
     cursor: pointer;
     padding: 0;
     margin-right: 10px;

 input[type="checkbox"]:before 
     content: '';
     margin-right: 10px;
     display: inline-block;
     margin-top: -2px;
     width: 20px;
     height: 20px;
     background: #fcfcfc;
     border: 1px solid #aaa;
     border-radius: 2px;

 input[type="checkbox"]:hover:before 
     background: #f5821f;

 input[type="checkbox"]:focus:before 
     box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);

 input[type="checkbox"]:checked:before 
     background: #f5821f;
     border-color: #f5821f;

 input[type="checkbox"]:disabled 
     color: #b8b8b8;
     cursor: auto;

 input[type="checkbox"]:disabled:before 
     box-shadow: none;
     background: #ddd;

 input[type="checkbox"]:checked:after 
     content: '';
     position: absolute;
     left: 5px;
     top: 8px;
     background: white;
     width: 2px;
     height: 2px;
     box-shadow: 2px 0 0 white, 4px 0 0 white, 4px -2px 0 white, 4px -4px 0 white, 4px -6px 0 white, 4px -8px 0 white;
     transform: rotate(45deg);

【讨论】:

太棒了! jsfiddle.net/ozv467na 这不需要任何特殊的 html 标签 输入层次结构 这在 Firefox 中不起作用。 input[type="checkbox"] 在 Firefox 中没有子元素,因此 ::before 和 ::after 不能存在。这在 Chrome 中有效,但基于 W3 规范使其保持打开状态的观点,即自闭合标签是否可以有子标签。【参考方案3】:

不幸的是,CSS 不允许基于子元素的父元素样式,这将是简单的示例:

div.a < div  border: solid 3px red; 

与根据父母选择孩子相反:

div.a > div  border: solid 3px red; 

你想做的事可以用jQuery来实现。

查看this 的帖子。

【讨论】:

有趣,我会调查一下。在查看其他答案之后,似乎 JS 确实是这里的关键,正如 Wesley Murch 所说,我可以通过简单地在包装标签中添加一个类来实现它。谢谢!【参考方案4】:

非常有趣的问题。说实话,我很确定仅靠 CSS 是不可能的。

如果标签的 for 属性 (ctrl_enable_rte) 存在某种模式,那么您就有希望了。例如,如果所有复选框标签都以rte 结尾,则可以使用

label[for$=rte]  ... 

如果没有这样的模式,并且复选框 ID 是任意选择的,您将不得不求助于 JavaScript。

【讨论】:

有趣,我得研究一下,看看是否有可能的解决方案,谢谢!编辑:似乎“ctrl_”用于复选框输入的所有地方,但它也用于没有复选框的标签。猜猜这毕竟行不通,而且 JS 看起来越来越像这里唯一的出路。 我不明白如何根据控件的选中状态来设置标签样式。状态为动态混合,for 属性为静态。

以上是关于输入在标签内时的CSS复选框和单选按钮?的主要内容,如果未能解决你的问题,请参考以下文章

Google Chrome 中的引导复选框和单选按钮标签问题

标签、复选框和单选按钮

css 自定义复选框和单选按钮设置

如何在复选框和单选按钮中设置默认值?

正确的分组复选框和单选按钮的方法

下拉菜单和单选按钮不粘