# Fieldset

# 概述

  ;fieldset (opens new window) 用于对表单中的控件元素进行分组。

  ;fieldset是块级双标签,绝大多数浏览器都支持。

# 属性

# disabled

  ;fieldset的所有子代控件均会继承,即不可编辑状态。

<form method="post" action="http://www.baidu.com">
  <div>
    <label for="username">用户名</label>
    <input type="text" name="username">
  </div>
  <fieldset disabled>
    <legend>支付信息</legend>
    <div>
      <label for="phone">手机号</label>
      <input type="text" name="phone">
    </div>
    <div>
      <label for="type">支付方式</label>
      <input type="radio" name='type' value="1" id="type-1"><label for="type-1">现金</label>
      <input type="radio" name='type' value="0" id="type-0"><label for="type-0">其他</label>
    </div>
  </fieldset>
  <button type="submit">提交</button>
</form>

  ;Chrome浏览器呈现,禁用后鼠标、键盘Tab均无法选中。

  但是IE浏览器较为特殊,不仅可以输入,还能触发输入事件。

  更糟糕的是fieldset内部的按钮,点击还会触发事件。

  兼容IE11浏览器。

fieldset[disabled] {
  pointer-events: none;
}

  兼容IE9IE10

fieldset {
  position: relative;
}

fieldset[disabled]::after {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0);
}

  ;IE8及以下浏览器,样式处理较麻烦,可采用js处理。

<body>
  ...
  <script>
    function forEach(array, callback) {
      for (var i = 0; i < array.length; i++) {
        callback(array[i], i, array)
      }
    }

    var fieldsets = document.getElementsByTagName('fieldset')
    var inputs = []
    var buttons = []

    forEach(fieldsets, function (fieldset) {
      if (fieldset.disabled) {
        buttons = fieldset.getElementsByTagName('button')
        inputs = fieldset.getElementsByTagName('input')

        forEach(buttons, function (button) {
          button.disabled = true
        })

        forEach(inputs, function (input) {
          input.disabled = true
        })
      }
    })
  </script>
</body>

  在表单提交时,即使不可编辑状态的控件中含有默认值,也不会伴随form一起提交。

  提交时请求参数。

# form

  将fieldset关联为form的一部分,但是浏览器支持程度比较低。

  如下fieldset绑定formid属性,实现表单控件在form外部关联上了form

<form method="post" id="form" action="http://www.baidu.com">
  <div>
    <label for="username">用户名</label>
    <input type="text" name="username">
  </div>
  <button type="submit">提交</button>
</form>
<fieldset form="form">
  <legend>支付信息</legend>
  <div>
    <label for="phone">手机号</label>
    <input type="text" name="phone">
  </div>
  <div>
    <label for="type">支付方式</label>
    <input type="radio" name='type' value="1" id="type-1"><label for="type-1">现金</label>
    <input type="radio" name='type' value="0" id="type-0"><label for="type-0">其他</label>
  </div>
</fieldset>

# 样式

  ;fieldset默认包括内外边距,同时周围有一个非完全闭合的边框,可通过border属性修改其颜色和宽度等。

  注意边框线没有从文字上面穿过去,而是文字垂直居中压在边框线上,文字背景色是透明而非白色。

  若通过CSS模拟,定位文本到边框上是没法实现的,文字必然要设置白色背景色才能遮住边框,但是若fieldset的背景色为非白色,就会出现问题。

  另外一种可行的方式是文字和两个元素,其中两个元素需设置宽度和1px高度,三元素垂直方向居中对齐,但是最终实现效果也只能接近fileldset

# 文本位置和样式

  ;fieldset开口处的文字是legend元素渲染的,因此可修改legend元素的CSS属性来调整文本样式。

  可调整legend左右内边距来控制文字左右留白。

legend {
  padding: 0 50px;
}

  调整legend左外边距来控制文字位置,注意设置margin: auto可水平居中文字。

legend {
  padding: 0;
  animation: marginLeft 2s infinite alternate;
}

@keyframes marginLeft {
  100% {
    margin-left: 160px;
  }
}

  也可设置text-align属性控制文字位置。

legend {
  padding: 0;
  text-align: right;
}

# 应用场景

# 分割线

  如下文字两侧带横线。

  一般可通过伪元素实现,宽度自适应,浏览器兼容方面IE10及以下不兼容。

.hr {
  display: flex;
  align-items: center;
}

.hr::after,
.hr::before {
  content: '';
  flex: 1;
  height: 1px;
  background: #000;
}

.hr::before {
  margin-right: 10px;
}

.hr::after {
  margin-left: 10px;
}

<div class="hr">分隔线</div>

  以下仅fieldsetlegend两元素,宽度自适应,浏览器兼容性良好,IE7及以下不兼容。

fieldset {
  padding: 0;
  margin: 0;
  border: none;
  border-top: 1px solid #000;
}

legend {
  margin: auto;
  padding: 0 10px;
}

<fieldset>
  <legend>分割线</legend>
</fieldset>

# 文字环绕

  由四个fieldset定位叠加形成,貌似除了炫酷点实际没啥用处。

.container {
  position: relative;
  width: 300px;
  height: 300px;
}

fieldset {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: none;
  border-top: 10px solid #000;
  box-sizing: border-box;
}

legend {
  font-size: 24px;
  line-height: 10px;
  font-weight: bold;
  padding: 0 10px;
  animation: move 2s infinite linear alternate;
}

fieldset:nth-of-type(2) {
  transform: rotate(90deg);
}

fieldset:nth-of-type(3),
fieldset:nth-of-type(3) legend {
  transform: rotate(180deg);
}

fieldset:nth-of-type(4) {
  transform: rotate(-90deg);
}

@keyframes move {
  100% {
    margin-left: 70px;
  }
}

<div class="container">
  <fieldset>
    <legend>CSS</legend>
  </fieldset>
  <fieldset>
    <legend>HTML</legend>
  </fieldset>
  <fieldset>
    <legend>JavaScript</legend>
  </fieldset>
  <fieldset>
    <legend>TypeScript</legend>
  </fieldset>
</div>

# 🎉 写在最后

🍻伙伴们,如果你已经看到了这里,觉得这篇文章有帮助到你的话不妨点赞👍或 Star (opens new window) ✨支持一下哦!

手动码字,如有错误,欢迎在评论区指正💬~

你的支持就是我更新的最大动力💪~

GitHub (opens new window) / Gitee (opens new window)GitHub Pages (opens new window)掘金 (opens new window)CSDN (opens new window) 同步更新,欢迎关注😉~

最后更新时间: 3/6/2022, 9:06:37 PM