IE / FF

时间:2018-02-16 22:38:26

标签: css twitter-bootstrap material-design html-input bootstrap-themes

根据Google's Material guidelines for selection controls(复选框,单选按钮,开关),这些输入字段应如下所示:

Material Selection Inputs

Bootstrap Paper Theme for v3.x(现称为Materia in v4)的设计风格符合此设计目标

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

这里是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>
&#13;
&#13;
&#13;

以上代码在每个浏览器中的表现如下:

Browser Compatability

是否有可能的解决方法,或者我们是否可以根据浏览器的风格来设置他们认为合适的输入?

此问题也在github issue #497的项目问题页面上提出,但是引用了浏览器不兼容的问题

3 个答案:

答案 0 :(得分:2)

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

根据W3C specs

中的can I use a pseudo-element on an input field?及此答案
  

:before:after在容器内呈现,而<input>不能包含元素

它在chrome中运行的事实是例外,而不是规则,但我们并没有运气......

纯CSS方法

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

第1步 - 基于标签的切换

我们必须重新构建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>
  

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

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

这是一个简单的骨头版本,其中包含CSS的基本要点,可以有条件地为每个标签设置样式:

:before

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

以下是jsFiddle和Stack Snippets中更加充实的演示:

input[type='checkbox'],[type='radio']     { display: none; }
[type='checkbox']         + label::before { content: "\2610";}
[type='checkbox']:checked + label::before { content: "\2611";}
[type='radio']            + label::before { content: "\2B58";}
[type='radio']:checked    + label::before { content: "\25C9";}
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: "\2610";}
.label-check [type='checkbox']:checked + label::before { content: "\2611";}
.label-check [type='radio']            + label::before { content: "\2B58";}
.label-check [type='radio']:checked    + label::before { content: "\25C9";}

第2步 - 使用CSS将材质样式应用于<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>

使用标签的风格化伪元素作为游戏中的切换的概念,我们可以应用Paper的样式/ CSS而不仅仅是label:before来为我们的复选框提供材质外观。

要做到这一点,让我们看一下假设的样式是如何工作的。我们可以在bootstrap.css#L7182

中查看描述Github上的检查和无线电的源代码

{ content: "\2610";}元素用于设置周围框/圆的样式,而:after元素在框:before时添加内部选择。

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

Material Checkbox CSS

  

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

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

Material Radio CSS

  

注意:单选按钮容器和内部只是一个不同大小的常规CSS圈(:checked),可以通过向上或向下缩放来制作动画。

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

border-radius:50%

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

/* old */ input[type="radio"]:before
/* new */ input[type="radio"] + label:before
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;
}

HTML / JS方法

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

  1. 隐藏实际的<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>元素
  2. 在标签内放置一个风格化的复选框
  3. 在某些情况下,这依赖于在设计时自己格式化HTML,或者在网站初始化时生成HTML。

    例如,FezVrasta's Material Design for BootstrapV3中的V4将采用如下HTML结构:

    <input>

    当您致电<div class="checkbox"> <label> <input type="checkbox"> Notifications </label> </div> 时插入新的跨度,结果如下所示:

    $.material.init()

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

答案 1 :(得分:1)

Bootstrap 4附带了一组自定义无线电和复选框。这意味着:可以调整它们以任何您想要的方式

以下是默认情况下附带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>

以下是自定义广播的示例(请查看该答案中的最后代码段):https://stackoverflow.com/a/48401949/8270343

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

参考链接:

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

答案 2 :(得分:0)

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>