为啥 :read-only CSS 伪类应用于此复选框?

Posted

技术标签:

【中文标题】为啥 :read-only CSS 伪类应用于此复选框?【英文标题】:Why is :read-only CSS pseudo-class being applied on this checkbox?为什么 :read-only CSS 伪类应用于此复选框? 【发布时间】:2022-01-19 08:06:30 【问题描述】:

我有以下 SCSS 代码:

input[type="checkbox"] 
    ...
    &:read-only, &[readonly] 
        cursor: default;
        filter: grayscale(1);
    

这将应用于 <input type="checkbox" id="checkbox" onChange=this.rememberMe />

遵循MDN: :read-only 文档:

它将选择用户无法编辑的任何元素。

为什么它被应用到我的可编辑输入上?

该问题同时适用于 Firefox 和 Chrome。

【问题讨论】:

【参考方案1】: 因为<input type="checkbox" /><input type="radio" />(以及大多数其他元素)本质上是只读的。 与<input type="text" /><input type="date" /> 不同,当您与复选框或单选按钮交互(即切换)时,您不会更改其value,而是更改其checked 状态。 是的,我同意这是违反直觉的。

因此...

    不应出于任何目的将<input readonly 属性应用于radiocheckbox。 因为它不会做任何有用的事情。 您不应定义一个 CSS 选择器,该选择器使用 :read-only 伪类来选择具有显式 html <input readonly 属性集的 <input> 元素。 改为使用 has-attribute-selector:input[readonly]。 完全避免使用:read-only 伪类because it also selects pretty-much every HTML element on the page too; a function with little practical utility, imo 可能是个好主意。

现在,如果您想要一个“只读复选框/收音机”,那么很遗憾,您没有太多好的选项;相反,您有可怕的选择和勉强足够的选择......:

There is this popular QA,但是大多数投票最高的答案都有我认为坏主意的建议:例如依赖客户端脚本来阻止用户交互...very imperfectly (来自那些不知道收音机和复选框可以通过多种方式进行操作的人,而不仅仅是onclick,或者使用CSS的pointer-events: none;,而完全无视计算机键盘既存在也经常被人类计算机操作员使用。 我认为最差的建议是使用<input type="checkbox/radio" disabled />、as demonstrated with this answer。 (The <input type="hidden"> is necessary because disabled (and unchecked) inputs are not submitted,这是 1990 年代后期当时新兴的浏览器供应商对principle of least astonishment 的又一次违反。

如果您想在所有input 元素除了 单选框和复选框上使用:read-only 伪类,那么您需要仔细考虑(并对其进行测试,使用document.querySeletorAll("input:read-only") 的变体)在浏览器的控制台中!)

我建议您不要在没有明确指定 [type=""] 属性选择器的情况下使用 input 元素的选择器应用任何样式 - 这是因为带有“input”之类选择器的样式(没有任何属性选择器)将应用于我们还不知道的未来 HTML 输入元素,并且可能在不久的将来的任何时候引入,也许下周谷歌浏览器会添加一个新的 <input type="human-dna-sample" /> 或微软将 <input type="clippy" /> 添加到他们的 Edge 浏览器的特别 retro 版本中 - 所以你绝对不希望将 :read-only 样式应用于这些元素,直到你至少知道它的外观和工作方式 - 并且因此浏览器将使用其默认/本机样式,如果他们碰巧在您的网站上遇到它,这不会违反您的用户/访问者的期望。

...所以这意味着您需要为每个已知的<input type="..."> 写出规则作为重复的input[type=""] 样式规则,现在您可能想知道是否有任何基于默认值的input 元素的伪类原生外观,因为它们中的许多确实看起来共享相似(如果不完全相同)的原生外观和视觉语义(以及阴影 DOM 结构,如果适用) - 例如在桌面 Chrome 中,输入类型 textpassword、@ 987654360@、searchurltel 和更多显然都是围绕同一个原生 textbox 小部件构建的,所以 肯定 肯定是一个伪类对于不同的输入“种类”,对吧?像input:textbox-kind 代表textpassword 等,input:checkbox-kind 代表checkboxradio - 不幸的是这样的东西不存在,如果明天推出,W3C 的 CSS 委员会可能不会批准它至少再过几年——所以在那之前我们需要明确枚举我们所知道的每一个input[type=""],以便我们可以准确地预测浏览器将如何使用我们的type=""-specific 样式呈现它们规则而不是把所有东西都扔成input 看看有什么坚持。

...幸好列表不是too long,所以我刚刚把规则写出来了:

随意复制+粘贴;它甚至几乎没有版权。 我想看看这在我有生之年在互联网上传播到什么程度

底部是一个 CSS 选择器,它将通过使用一组详尽的 :not([type="..."]) 选择器以及不匹配的 input 元素仅选择 未来<input 元素type="" 属性为空或完全缺失。

/* Textbox-kind: */ 
input[type="text"]:read-only,
input[type="password"]:read-only,
input[type="search"]:read-only,
input[type="tel"]:read-only,
input[type="url"]:read-only,
input[type="email"]:read-only,
input[type="number"]:read-only 
    background-color: #ccc;
    cursor: 'not-allowed';


/* Date/time pickers: */ 
input[type="date"]:read-only,
input[type="datetime-local"]:read-only,
input[type="time"]:read-only,
input[type="week"]:read-only,
input[type="month"]:read-only 
    background-color: #ccc;
    cursor: 'not-allowed';


/* Button-kind (these are all practically obsolete now btw, as the <button> element is far, far, far superior in every way) */
input[type="button"]:disabled,
input[type="reset"]:disabled,
input[type="submit"]:disabled,
input[type="image"]:disabled 
    background-color: #ccc;
    border: 1px outset #666;
    cursor: 'not-allowed';
    color: #666;
    text-shadow: 0 1px rgba(255,255,255,0.2);


/* Checkbox-kind (Don't use `:read-only` with these): */
input[type="checkbox"]:disabled,
input[type="radio"]:disabled 
    /* I'm not setting any properties here because it's impossible to effectively style these elements without resorting to image-replacements using the `:checked` state in selectors for their parent or adjacent `<label>` or ::before/::after` of other proximate elements. */


/* Weird-stuff-kind: */ 
input[type="color"]:read-only,
input[type="file"]:read-only,
input[type="hidden"]:read-only,
input[type="range"]:read-only 
    /* Again, due to differences in how different browsers and platforms display (and consequently style) these inputs I don't think it's worth doing anything. */


/* If you **really** want to select _future_ <input> elements in-advance... do this: */

input[type]:not([type="text"]):not([type="password"]):not([type="search"]):not([type="tel"]):not([type="url"]):not([type="email"]):not([type="number"]):not([type="date"]):not([type="datetime-local"]):not([type="time"]):not([type="week"]):not([type="month"]):not([type="button"]):not([type="reset"]):not([type="submit"]):not([type="image"]):not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="file"]):not([type="hidden"]):not([type="range"]) 


【讨论】:

现在很清楚了。谢谢。

以上是关于为啥 :read-only CSS 伪类应用于此复选框?的主要内容,如果未能解决你的问题,请参考以下文章

为啥用css中伪类hover实现(鼠标悬停显示文字,鼠标移走文字消失)的效果失败(脚本没有错)?

CSS ::before 和 ::after 伪元素用法

css选择器中,为啥nth

浅谈css伪类和伪元素的区别、优先级

知道css有个content属性吗?有什么作用?有什么应用?可以伪类清除浮动

CSS :hover伪类选择器