twitter-bootstrap Bootstrap Paper 的单选框/复选框输入的材质样式在 IE/FF 中损坏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48835846/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 01:15:59  来源:igfitidea点击:

Bootstrap Paper's material style of radio/checkbox inputs broken in IE/FF

csstwitter-bootstrapmaterial-designhtml-inputbootstrap-themes

提问by KyleMit

According to Google's Material guidelinesfor selection controls(checkboxes, radio buttons, switches), these input fields should look like this:

根据Google 的选择控件(复选框、单选按钮、开关)的 Material 指南,这些输入字段应如下所示:

Material Selection Inputs

材料选择输入

The Bootstrap Paper Theme for v3.x(now called Materia in v4) is styled to hit this design target

v3.xBootstrap Paper 主题(现在在 v4 中称为Materia)的样式旨在达到此设计目标

In chrome, inputs are stylized correctly, but all other browsers merely fallback to native input controls, which disrupts the consistency of the design metaphor.

在 chrome 中,输入的样式是正确的,但所有其他浏览器只是回退到原生输入控件,这破坏了设计隐喻的一致性。

Here's an MCVE in jsFiddle/ Stack Snippets that will work / fail depending on browser:

这是jsFiddle/ Stack Snippets 中的 MCVE ,它将根据浏览器工作/失败:

<link href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/paper/bootstrap.min.css" rel="stylesheet"/>


<div class="checkbox">
  <label><input type="checkbox" value="check1"/> Check Opt 1 </label>
</div>
<div class="checkbox">
  <label><input type="checkbox" value="check2" checked/> Check Opt 2</label>
</div>

<div class="radio">
  <label><input type="radio" value="radio1" name="grp1" />Radio Opt 1</label>
</div>
<div class="radio">
  <label><input type="radio" value="radio2" name="grp1" checked/>Radio Opt 2</label>
</div>

And here how the previous code fares in each browser:

这里是之前的代码在每个浏览器中的表现:

Browser Compatability

浏览器兼容性

Is there a possible workaround for this or are we at the mercy of the browser to style inputs how they deem fit?

是否有可能的解决方法,或者我们是否受浏览器的支配来设置他们认为合适的样式输入?

This question was also asked on the project's issues page in github issue #497, but closed citing browser incompatibility

这个问题也在github issue #497的项目问题页面上被问到,但由于浏览器不兼容而关闭

回答by KyleMit

The core problem faced by the implementation of the Paper Theme is it does so by styling the <input type="checkbox" />elements using :beforeor :afterpseudo-elements.

Paper Theme 的实现面临的核心问题是它通过<input type="checkbox" />使用:before:after伪元素来设置元素的样式。

Per this the W3C specsand this answer in can I use a pseudo-element on an input field?

根据这个W3C 规范和这个答案,我可以在输入字段上使用伪元素吗?

:beforeand :afterrender inside a container and <input>s can not contain elements

:before:after在容器内渲染并且<input>s 不能包含元素

The fact that it works in chrome is the exception, not the rule, but we're not out of luck ...

它在 chrome 中工作的事实是例外,而不是规则,但我们并不走运......

Pure CSS Approach

纯 CSS 方法

So we'll want to avoid styling anything withinthe actual checkbox itself, but we can apply those same styles to the label instead, which will still toggle the checkbox that it describes.

因此,我们希望避免实际复选框本身设置任何样式,但我们可以将这些相同的样式应用于标签,这仍然会切换它所描述的复选框。

Step 1- Label Based Toggle

第 1 步- 基于标签的切换

We do have to restructure the HTML so that checkbox comes beforethe label, instead of insideit. We'll do that so we can use the :checkedand adjacent sibling selector +to conditionally style the label based on whether or not the checkbox is checked.

我们必须重构 HTML,以便复选框出现标签之前,而不是在标签内部。我们将这样做,以便我们可以使用:checked和 相邻的兄弟选择器+根据是否选中复选框来有条件地设置标签样式。

<!-- Old Format -->
<div class="checkbox">
  <label>
    <input type="checkbox" value="check1"/>
    Check Label Text
  </label>
</div>

<!-- New Format -->
<div class="label-check">
   <input type="checkbox" value="check1" id="myCheck">
   <label for="myCheck">Check Label Text</label>
</div>

Note: In order for this solution to work, you do need to make sure that you have valid HTMLwith unique IDs for every input and corresponding forattributes in the labels that describe them.

注意:为了使此解决方案起作用,您确实需要确保您拥有有效的 HTML,每个输入的 ID 都是唯一的,并且for在描述它们的标签中具有相应的属性。

At this point in time, we can ditch the inputs, and style the labels with our own :beforepseudo elements that looklike checkboxes or radio buttons. To keep things simple for now, in step one, we can mimic the controls with the following Unicode Characters ... ?, ?, ?, ?

此时,我们可以放弃输入,并使用我们自己的看起来像复选框或单选按钮的:before伪元素来设置标签的样式。现在为了简单起见,在第一步中,我们可以使用以下 Unicode 字符来模拟控件...... , ? , ? , ?

Here's an bare bones version with the basic gist of the CSS to style each label conditionally:

这是一个带有 CSS 基本要点的基本版本,用于有条件地设置每个标签的样式:

input[type='checkbox'],[type='radio']     { display: none; }
[type='checkbox']         + label::before { content: "10";}
[type='checkbox']:checked + label::before { content: "11";}
[type='radio']            + label::before { content: "B58";}
[type='radio']:checked    + label::before { content: "C9";}

We can also improve on this baseline quite a bit by adding some colorization, hovering effects, cursor properties, transition effects, and text shadows to make the unicode characters look and feel like actual buttons.

我们还可以通过添加一些着色、悬停效果、光标属性、过渡效果和文本阴影,使 unicode 字符看起来和感觉像实际按钮,从而大大改进此基线。

Here's a more fleshed out demo in jsFiddleand Stack Snippets:

这是jsFiddle和 Stack Snippets 中更充实的演示:

body {
  font-size:1.3em;
  color: #2b2b2b;
  background:white;
}
.label-check input {  display:none; }

.label-check label::before {
  width: 1.4em;
  text-align: center;
  display: inline-block;
  cursor: pointer;
  color: black;
  transition: color .3s ease;
  text-shadow: 0px 0px 1px #cccccc;
}
.label-check label:hover::before {
  text-shadow: 0px 0px 1px #6286d0;
}
.label-check [type='checkbox']:checked + label::before,
.label-check [type='radio']:checked    + label::before{ 
  color: #056dce;
}

.label-check [type='checkbox']         + label::before { content: "10";}
.label-check [type='checkbox']:checked + label::before { content: "11";}
.label-check [type='radio']            + label::before { content: "B58";}
.label-check [type='radio']:checked    + label::before { content: "C9";}
<h3>
  Inputs... we don't need no stinkin Inputs
</h3>

<div class="label-check">
  <div>
    <input type="checkbox" name="checkGrp1" id="check1_Opt1">
    <label for="check1_Opt1">A Label Here 1</label>
  </div>
  <div>
    <input type="checkbox" name="checkGrp1" id="check1_Opt2" checked>
    <label for="check1_Opt2">A Label Here 2</label>
  </div>
</div>

<div class="label-check">
  <div>
    <input type="radio" name="radioGrp1" id="radio1_Opt1">
    <label for="radio1_Opt1">Radio Label 1</label>
  </div>
  <div>
    <input type="radio" name="radioGrp1" id="radio1_Opt2" checked>
    <label for="radio1_Opt2">Radio Label 2</label>
  </div>  
</div>

Step 2- Apply Material Style to label:beforewith CSS

第 2 步-label:before使用 CSS应用材质样式

With the concept of using a the label's stylized pseudo elements as a toggle in play, we can apply Paper's styles / CSS instead of just { content: "\2610";}to give our checkboxes a Material look and feel.

通过使用标签的风格化伪元素作为切换的概念,我们可以应用 Paper 的样式/CSS 而不是仅仅{ content: "\2610";}为我们的复选框提供 Material 外观和感觉。

To do that, let's look at how the styles were supposedto work. We can look at the source code that describes checks and radios on Github in bootstrap.css#L7182

为此,让我们看看样式应该如何工作。我们可以在bootstrap.css#L7182 中查看 Github 上描述检查和无线电的源代码

The :afterelement is being used to style the surrounding box/circle while the :beforeelement adds the inner selection when the box is :checked.

:after元素用于设置周围框/圆圈的样式,而:before当框为 时,该元素添加内部选择:checked

Here are the high level styles for the checkbox:

以下是复选框的高级样式:

Material Checkbox CSS

材质复选框 CSS

Note: The check mark is made by rotating a rectangle 45 degrees and adding a white border to the bottom and right.

注意:复选标记是通过将矩形旋转 45 度并在底部和右侧添加白色边框来制作的。

And here's a high level view of the styles for the radio button:

这是单选按钮样式的高级视图:

Material Radio CSS

材质单选 CSS

Note: The radio button container and inside is just a regular CSS circle (border-radius:50%) with varying sizes which can animate by scaling up or down.

注意:单选按钮容器和内部只是一个普通的 CSS 圆圈 ( border-radius:50%),具有不同的大小,可以通过放大或缩小来制作动画。

So we'll migrate any pseudo elements found on the checkbox input to it's adjacent label like this:

因此,我们将在复选框输入中找到的任何伪元素迁移到它的相邻标签,如下所示:

/* old */ input[type="radio"]:before
/* new */ input[type="radio"] + label:before

After some careful conversion, here's a demo in jsFiddleand Stack Snippets:

经过一些仔细的转换,这里是jsFiddle和 Stack Snippets 中的一个演示:

body {
  padding: 0 25px;
  font-size: 1.2em;
}


.checkbox, .radio {
    margin: 10px;
}
.checkbox, .radio {
    position: relative;
}


.label-check label {
  padding-left: 20px;
}
.label-check input[type="radio"],
.label-check input[type="checkbox"] {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
    opacity: 0;
    position: absolute;
    margin: 0;
    z-index: -1;
    width: 0;
    height: 0;
    overflow: hidden;
    left: 0;
    pointer-events: none;
}
.label-check input[type="radio"]:focus {
  outline: none;
}
.label-check input[type="radio"] + label:before,
.label-check input[type="radio"] + label:after {
  content: "";
  display: block;
  position: absolute;
  left: -10px;
  top: 1px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  -webkit-transition: 240ms;
  -o-transition: 240ms;
  transition: 240ms;
}
.label-check input[type="radio"] + label:before {
    left: -8px;
    top: 3px;
}
.label-check input[type="radio"] + label:before {
  background-color: #2196f3;
  -webkit-transform: scale(0);
      -ms-transform: scale(0);
       -o-transform: scale(0);
          transform: scale(0);
}
.label-check input[type="radio"] + label:after{
  top: 1px;
  border: 2px solid #666666;
  z-index:1;
}
.label-check input[type="radio"]:checked + label:before {
  -webkit-transform: scale(0.6);
      -ms-transform: scale(0.6);
       -o-transform: scale(0.6);
          transform: scale(0.6);
}
.label-check input[type="radio"]:disabled:checked + label:before {
  background-color: #bbbbbb;
}
.label-check input[type="radio"]:checked + label:after {
  border-color: #2196f3;
}
.label-check input[type="radio"]:disabled + label:after,
.label-check  input[type="radio"]:disabled:checked + label:after {
  border-color: #bbbbbb;
}
.label-check input[type="checkbox"]:focus {
  outline: none;
}
.label-check input[type="checkbox"]:focus + label:after{
  border-color: #2196f3;
}
.label-check input[type="checkbox"] + label:after {
  content: "";
  position: absolute;
  top: 2px;
  left: -10px; 
  display: block;
  width: 18px;
  height: 18px;
  margin-top: -2px;
  margin-right: 5px;
  border: 2px solid #666666;
  border-radius: 2px;
  -webkit-transition: 240ms;
       -o-transition: 240ms;
          transition: 240ms;
}
.label-check input[type="checkbox"]:checked + label:before {
  content: "";
  position: absolute;
  top: 2px;
  left: -3px;
  display: table;
  width: 6px;
  height: 12px;
  border: 2px solid #fff;
  border-top-width: 0;
  border-left-width: 0;
  -webkit-transform: rotate(45deg);
      -ms-transform: rotate(45deg);
       -o-transform: rotate(45deg);
          transform: rotate(45deg);
  z-index:1;
}
.label-check input[type="checkbox"]:checked + label:after{
  background-color: #2196f3;
  border-color: #2196f3;
}
.label-check input[type="checkbox"]:disabled + label:after {
  border-color: #bbbbbb;
}
.label-check  input[type="checkbox"]:disabled:checked + label:after {
  background-color: #bbbbbb;
  border-color: transparent;
}
<h3>
 Material Label Based Checks
</h3>

<div class="label-check">
  <div class="checkbox">
    <input type="checkbox" name="checkGrp1" id="check1_Opt1">
    <label for="check1_Opt1">A Label Here 1</label>
  </div>
  <div class="checkbox">
    <input type="checkbox" name="checkGrp1" id="check1_Opt2" checked>
    <label for="check1_Opt2">A Label Here 2</label>
  </div>
</div>

<div class="label-check">
  <div class="radio">
    <input type="radio" name="radioGrp1" id="radio1_Opt1">
    <label for="radio1_Opt1">Radio Label 1</label>
  </div>
  <div class="radio">
    <input type="radio" name="radioGrp1" id="radio1_Opt2" checked>
    <label for="radio1_Opt2">Radio Label 2</label>
  </div>  
</div>

HTML/JS Approach

HTML/JS 方法

There are some other material implementations that have hit this target in a cross browser friendly way. All of which typically rely on:

还有一些其他的材料实现以跨浏览器友好的方式达到了这个目标。所有这些通常都依赖于:

  1. Hiding the actual <input>element
  2. Placing a stylized checkbox box inside of the label
  1. 隐藏实际<input>元素
  2. 在标签内放置一个风格化的复选框

In some cases, this relies on formatting the HTML appropriately yourself at design time, or generating it when the site initializes.

在某些情况下,这依赖于自己在设计时适当地格式化 HTML,或者在站点初始化时生成它。

For example, FezVrasta's Material Design for Bootstrap, in both V3and V4will take an HTML structure like this:

例如,FezVrasta 的 Bootstrap 材料设计,在V3V4 中都将采用这样的 HTML 结构:

<div class="checkbox">
  <label>
    <input type="checkbox"> 
    Notifications
  </label>
</div>

And insert a new span when you call $.material.init()so the result looks like this:

并在调用时插入一个新的跨度,$.material.init()因此结果如下所示:

<div class="checkbox">
  <label>
    <input type="checkbox">
    <span class="checkbox-material">
      <span class="check"></span>
    </span>
    Notifications
  </label>
</div>

While this relies on the initialization to occur, it allows much more fine grained control of the CSS checkbox and radio button rather than shoving it all into pseudo elements.

虽然这依赖于初始化的发生,但它允许对 CSS 复选框和单选按钮进行更细粒度的控制,而不是将它们全部推送到伪元素中。

回答by WebDevBooster

Bootstrap 4 does come with a set of custom radios and checkboxes. Which means: They can be adjusted to style in any way you want.

Bootstrap 4 确实带有一组自定义收音机和复选框。这意味着:它们可以按照您想要的任何方式进行调整。

Here's an example of a custom checkbox that comes with Bootstrap 4 by default and is designed to look identical in all browsers:

这是 Bootstrap 4 默认附带的自定义复选框示例,其设计目的是在所有浏览器中看起来都相同

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

<div class="custom-control custom-checkbox">
  <input type="checkbox" class="custom-control-input" id="customCheck1">
  <label class="custom-control-label" for="customCheck1">Check this custom checkbox</label>
</div>

And here's an example of a custom radio (check the lastsnippet in that answer): https://stackoverflow.com/a/48401949/8270343

这是自定义收音机的示例(检查该答案中的最后一个片段):https: //stackoverflow.com/a/48401949/8270343

(note: only colors were adjusted in that case but the shapes and/or animations can be adjusted just as well)

(注意:在这种情况下只调整了颜色,但也可以调整形状和/或动画)

Reference link:

参考链接:

https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios-1

https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios-1

回答by Micha? Per?akowski

The v4 version seems to be working fine in Firefox:

v4 版本似乎在 Firefox 中运行良好:

<link href="https://maxcdn.bootstrapcdn.com/bootswatch/4.0.0-beta.3/materia/bootstrap.min.css" rel="stylesheet"/>


<div class="checkbox">
  <label><input type="checkbox" value="check1"/> Check Opt 1 </label>
</div>
<div class="checkbox">
  <label><input type="checkbox" value="check2" checked/> Check Opt 2</label>
</div>

<div class="radio">
  <label><input type="radio" value="radio1" name="grp1" />Radio Opt 1</label>
</div>
<div class="radio">
  <label><input type="radio" value="radio2" name="grp1" checked/>Radio Opt 2</label>
</div>