Go to comments

HTML+CSS宝典 HTML进阶 美化表单元素

一、伪类选择器

:focus

该伪类选择器表示元素聚焦时的样式


什么是聚焦?

下面有 a、input、button 三个元素,

其中用鼠标点击 input 文本框的时候,文本框外面多了一个蓝色的边框,是默认的聚焦样式,是浏览器通过伪类选择器  :focus 来实现的

<p>
  <a href="">lorem</a>
</p>

<p>
  <input type="text">
</p>

<p>
  <button>提交</button>
</p>

检查元素

1. 选中左边文本框 input 代码

2. 右边点击 :hov (打开 Force element state)

3. 按照视频的方法选择 :focus 没有出现浏览器默认的样式,应该是浏览器升级了,现在选择 :focus-visible 是浏览器设置的现默认样式了

image.png

分析一下浏览器默认给聚焦样式哪些设置(课程里不是 :focus-visible 是 :focus )

:focus-visible { 

  outline: -webkit-focus-ring-color auto 1px;

1. :focus-visible 冒号前面没有加元素选择器,表示浏览器给页面上所有元素,都设置了这个聚焦样式(课程里是 :focus )

2. outline 表示外边框,外边框是不占据尺寸的

3. -webkit-focus-ring-color 是谷歌浏览器特有的颜色

4. auto 是外边框的样式,我们常常设置 solid。auto 表示自动的,浏览器会根据实际情况来设置,input 的外边框的四个角有点弧度更加贴合 input 元素

5. 1px 边框的宽度,但是这个地方说一下,当设置边框样式为 auto 值的时候,边框宽度是无效的,是浏览器自行决定边框宽度


不仅是 input 元素有聚焦样式,其他所有元素都有聚焦样式,都有 :focus-visible 设置到样式,

另外两个元素要怎么聚焦呢?

按键盘的“Tab 键”来回切换,就可以看到聚焦样式


tabindex 属性可以控制 Tab 键的切换顺序,按照 tabindex 属性的数字顺序去切换

<p>
  <a href="https://www.baidu.com" tabindex="2">lorem</a>
</p>

<p>
  <input type="text" tabindex="1">
</p>

<p>
  <button tabindex="3">提交</button>
</p>


覆盖 input 元素默认聚焦的边框样式

1. 通过伪类选择器 :focus 设置 input 元素的聚焦样式

2. 把外边框 outline: none 去掉,input 元素聚焦后就没有外边框了

input:focus{
  outline: none;
}


不同的浏览器 input 默认边框样式不一样,

为了在每一个浏览器里面统一,需要覆盖浏览器的默认样式,怎么覆盖掉呢?

设置为 outline: none 或设置为其它值  outline: 1px solid #ff8c8c

input:focus{
  outline: 1px solid #008c8c;
}


然后发现 input 还有一个边框,

1. 因为浏览器的默认样式还给 input 设置了input:focus-visible(课程里面是 input:focus )

2. outline-offset: 0px 表示外边框的偏移量

input:focus-visible { 课程里的选择器是 input:focus

  outline-offset: 0px;

}


这里说一下,

如果默认外边框  outline 的样式不是 solid 是自动 auto,这个偏移量 outline-offset 没有效果

input:focus{
  outline: 1px auto #008c8c;
  outline-offset: 1px; /* 没有效果 */
}


外边框 outline 的样式设置为 solid,偏移量 outline-offset: 0px 就有效了,我们从 -3 ~ 6 调试就看到偏移量到效果了

<style>

input:focus{
  outline: 1px solid #008c8c;
  outline-offset: 1px; /* 取值从-3~0~6测试一下就看出便宜了效果了 */
}

</style>

<input type="text">


outline-offset: 0px 设置为 0 还有默认的边,实测设置为 -1 看不到默认边框了

<style>
  /* 不聚焦时的样式 */
  input{
    outline:1px solid #ccc;
    outline-offset:-1px;
  }

  /* 聚焦时的样式 */
  input:focus{
    outline:1px solid #008c8c;
    outline-offset:-1px;
  }
</style>

<input type="text">


课程后面有最好的方法是,

去掉外边框 outline: none,然后设置边框样式。然后还可以设置很多样式,比如聚焦的时候字体是红色,鼠标离开字体是灰色

/* 不聚焦时的样式 */
input{
  outline: none;
  border: 1px solid #ccc;
  color: #999;
}

/* 聚焦时的样式 */
input:focus{
  border: 1px solid #008c8c;
  color:red;
}


:checked

伪类选择器表示“单选框”或“多选框”被选中时的样式,其他元素就不要用(特指单选或多选框被选中时的样式,就像a元素有自己特有的伪类,爱恨法则


单选框背景设置成红色是生效的,但是没有显示效果,

因为单选框和多选框是可替换元素,可替换元素里面有些样式是我们控制不了的

<style>
  input:checked{
    background: red;
  }
</style>

<p>
  <input type="radio" name="gender" value="female" checked> 女
  <input type="radio" name="gender" value="male"> 男
</p>


单选框和多选框,几乎没什么样式让我们控制,这个 :checked 有什么用呢?

加号 + 选择选中的是下一个兄弟元素,

被选中后,设置下一个兄弟 label 元素的样式,可以达到意想不到的效果 

<style>
  input:checked + label{
    color:red;
  }
</style>

<input type="radio" name="gender" value="female" checked id="radfemale">
<label for="radfemale">女</label>

<input type="radio" name="gender" value="male" id="radmale">
<label for="radmale">男</label>


总结新学的两个伪类

:focus

:checked


重置表单元素样式,

常见用法不仅是 :focus、:checked 这两个伪类,还有其它东西


:disbled 也是一个伪类

button:disabled{} 意思是按钮禁用状态下他的样式

not-allowed 表示鼠标不允许的样式

<button class="fill" disabled>注册</button>
<button class="fill">提交</button>

<style>
  .fill{
    border: none;
    padding: 5px 10px;
    background-color: #00a1d6;
    color: #fff;
  }
  .fill:disabled{
    background-color: #f5f5f5;
    color:rgba(0,0,0, .25);
    cursor:not-allowed; /* 表示不允许的鼠标样式 */
  }
</style>


::placeholder 该伪类选择input 文本框 placeholder 的文字设置

input[type="text"]::placeholder, input[type="password"]::placeholder{
  color:#ccc;
}


二、表单中常见的做法

表单元素的样式是浏览器给的,

但是每个浏览器又不一样,不重置在不同的浏览器看到的效果就不一样,

还有浏览器默认的样式,跟设计稿不一样,基于这些情况都需要对表单样式进行重置


1. 重置 input 和 textarea


怎么重置呢?

去掉默认边框,去掉聚焦时候的默认样式,然后写我们自己的样式

<style>
  /**
   * 1.去掉默认样式
   */
  input,textarea,button,select{/* 去掉边框 */
    border: none;
  }
  input:focus, 
  textarea:focus, 
  button:focus, 
  select:focus{ /* 去掉聚焦时候的默认外边框 */
    outline: none;
    outline-offset: 0;
  }

  /**
   * 2.我们自己的样式
   */
  input[type="text"], textarea, select{ /* 设置文本框边框 */
    border:1px solid #ccc;
  }
  input[type="text"]:focus, textarea:focus{ /* 添加聚焦时候的样式 */
    border:1px solid #008c8c;
  }
  button{ /* 设置按钮边框,还可以设置背景颜色和字体 */
    border: 1px solid #008c8c;
    border-radius: 2px;
  }
</style>

<p>
  <input type="text">
</p>

<p>
  <select name="" id="">
    <option value="">重庆</option>
    <option value="">北京</option>
    <option value="">哈尔滨</option>
  </select>
</p>

<p>
  <textarea name="" id="" cols="30" rows="10"></textarea>
</p>

<p>
  <button>按钮</button>
</p>


Ps:

text-agin:center 一开始说是文本居中,学了行盒后纠正一下,指的是行盒居中包括行块盒

input、select、textarea 都是 inline-block 行块盒,

图片是 inline 行盒

可以设置在 <body style="text-agin:center"> 上让这些元素在页面上居中


2. 设置 textarea 多行文本框是否允许调整尺寸


textarea 元素有一个 resize 属性,控制多行文本框是否允许调整尺寸

textarea{
  resize: vertical;
}


resize属性有这样一些取值

both  默认值,两个方向上(水平、垂直)都可以调整尺寸

none   两个方向上都不可以调整尺寸

horizontal  只能在在水平方向上调整尺寸

vertical   只能在垂直方向上调整尺寸


3. 文本框边缘到内容的距离


方式一

使用 padding-left:10px,

如果两边都需要距离使用 padding: 0 10px

<style>
  input{
    padding:0 10px;
  }
</style>

<input type="text" value="文本框边缘到内容的距离">


方式二

使用 text-indent 首行缩进

<style>

  input, textarea{
    text-indent:1em;
  }

</style>

<input type="text" value="文本框边缘 到 内容的距离">

<textarea name="" id="" cols="30" rows="10"></textarea>


4. 控制单选框和多选框的样式


多选框和单选框不能设置样式,我们要自己做出漂亮的单元框和多选框

<style>
  /* 没有选中时的样式 */
  .radio{
    width: 12px;
    height: 12px;
    border:1px solid #999;
    border-radius: 50%;
    cursor:pointer; 
    margin:20px;
  }

  /* 选中时的样式 */
  .radio.checked{
    border-color: #008c8c;
  }

  /* 用伪元素在里面加一个圈 */
  .radio.checked::after{
    content: "";
    display: block;
    width: 5px;
    height: 5px;
    background: #008c8c;
    border-radius: 50%;
    margin-top: 3.5px;
    margin-left: 3.5px;
  }
</style>

<div class="radio"></div>
<div class="radio checked"></div>


5. 实现单选框的切换效果


为什么不用div,因为在label里面不允许加div,可以加span

label可以关联一个单选框或多选框

<style>
  .radio-item .radio{
    width: 12px;
    height: 12px;
    border:1px solid #ccc;
    border-radius: 50%;
    cursor:pointer;
    display: inline-block;
  }

  /**
   * 选中的效果
   * span没有选中的效果,radio才有选中的效果
   * 1 这部分 ".radio-item input:checked" 找到"选中"的input单选框
   * 2 找到了之后,在找"选中单选框"的下一个兄弟元素
   * 3.+ 加号选择器,选中的是下一个兄弟元素,类名为.radio的元素
   *
   */
  .radio-item input:checked + .radio{
    border-color: #008c8c;
  }
  .radio-item input:checked + .radio::after{
    content: "";
    display: block;
    width: 8px;
    height: 8px;
    background: #008c8c;
    border-radius: 50%;
    margin-top: 2px;
    margin-left: 2px;
  }

  /**
   * 改文字颜色
   * 1 ~ 选中的是后面所有的兄弟元素
   * 2 找到选中的单选框,后面第二个span元素
   * 3 单选框后面两个都被选中了,第一个span设置文字颜色也没有什么意义
   */
  .radio-item input:checked ~ span{
    color: #008c8c;
  }

  /**
   * 最后精确隐藏input单选框
   * 使用属性选择器,尽量精确到选择
   */
  .radio-item input[type="radio"]{
    display: none;
  }
</style>

<p>
  请选择性别:
  <label class="radio-item">
    <input type="radio" name="gender" value="female" checked>
    <span class="radio"><!--label里面不能用div元素,所以用span--></span>
    <span>女</span>
  </label>
  <label class="radio-item">
    <input type="radio" name="gender" value="female">
    <span class="radio"></span>
    <span>男</span>
  </label>
</p>


FirstTime 20220129


四、表单练习

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="reg.css">
<title>注册页面</title>
</head>
<body>

  <div class="form">
    <h2>
      <span>注册</span>
    </h2>

    <div class="form-area">
      <!-- #form-item 登录名区域 -->
      <div class="form-item hasError">
        <input type="text" placeholder="账号">
        <div class="error">该昵称已被他人使用</div>
      </div>

      <!-- #form-item 密码区域 -->
      <div class="form-item">
        <input type="password" placeholder="密码(6-16个字符组成,区分大小写)">
      </div>

      <!-- #form-item选择区域,由两个部分组成,1.选择区域,2.可能还有错误提示区域-->
      <div class="form-item">
        <!-- 1.select下拉选择区域,里面分又两部分 -->
        <div class="select clearfix">
          <div class="select-item"> <!-- select选择区域,第一部分下拉列表左浮动 -->
            <div class="title">中国大陆</div>
            <div class="choose-wapper">
              <ul class="choose-items">
                <li class="active">中国大陆</li>
                <li>中国香港特别行政区</li>
                <li>中国澳门特别行政区</li>
                <li>中国台湾</li>
                <li>美国</li>
                <li>比利时</li>
                <li>澳大利亚</li>
                <li>法国</li>
              </ul>
            </div>
          </div>
          <div class="input"> <!-- select选择区域,第二部分手机号也是左浮动 -->
            <input type="text" placeholder="填写常用的手机号">
          </div>
        </div>
        <!-- 2.这里可能会有错误提示的区域,所以预留出来 -->
      </div>

      <!-- #form-item 这个表单项,里面又是两部分组成 -->
      <div class="form-item">
        <input type="text" placeholder="请输入短信验证码">
        <button type="button" class="btn-sncode">点击获取</button>
      </div>

      <!-- #readme 注册协议说明文字,该区域使用另外一个类样式 .readme -->
      <div class="readme">
        <label>
          <input type="checkbox">
          <span class="checkbox"></span>
          <span>
            我已同意
            <a href="javascript:void();">《哔哩哔哩弹幕网用户使用协议》</a>
            和
            <a href="javascript:;">《哔哩哔哩弹幕网账号中心规范》</a>
          </span>
        </label>
      </div>

      <!-- #form-item 按钮 -->
      <div class="form-item">
        <button class="fill" disabled>注册</button>
      </div>

      <!-- #readme 已有账号直接登录tip-->
      <div class="readme txtright">
        <a href="javascript:;">已有账号,直接登录 &gt;</a>
      </div>
    </div>
  </div>

</body>
</html>


每个文本框用 .form-item 包一下,

因为有一些功能,比如一些错误信息“昵称是否存在”等 


max-height: 256px

overflow-y: auto

最大高度的意思是

1. 如果内容不满 256,按照内容为准,

2. 如果内容超过了 256,那么最多只能 256

3. 由于默认溢出也显示,如果溢出使用滚动条


reg.css

.clearfix::after{content:"";display:block;clear:both;}
.form a{color:#00A1D6;}
.form{width:980px;margin:1em auto;}

/**
 * 虽然文字超出了h2元素到高度,但默认是显示的,
 * span 元素设置背景为白色
 * 用这种方式巧妙的h2把底边的放到文字中间
 *
 */
.form h2{
  text-align: center;
  font-size: 38px;
  border-bottom: 1px solid #ddd;
  height: 30px;
  margin-bottom: 60px;
}
.form h2 span{
  background-color: #fff;
  padding: 0 20px;
}
/**
 * 统一设置input文本框
 */
input[type="text"], input[type="password"]{
  width: 100%;
  border:1px solid #dcdfe6;
  box-sizing: border-box;/*文本框内容的区域宽100%,加上边框也计算在宽度范围之内*/
  border-radius:4px;
  height:40px;
  text-indent: 1em;
  font-size: 14px;
  color:#606266;
}
input[type="text"]:hover, input[type="password"]:hover{
  border-color:#c0c4cc;
}
input[type="text"]::placeholder, input[type="password"]::placeholder{
  color:#ccc;
}
input[type="text"]:focus, input[type="password"]:focus{
  border-color:#00a1d6;
}
/**
 * 统一设置button按钮样式
 */
button{
  height: 40px;
  background-color: #00a1d6;
  color: #fff;
  border-radius: 4px;
  font-size: 14px;
}
button:hover{
  background-color: #33b4de;
}

/**
 * 表单区域
 */
.form-area{
  width: 423px;
  margin: 0 auto;
}
.form-area .form-item{
  margin-bottom: 50px;
  position: relative;/*每个form-tiem都是相对定位*/
}
/**
 * select区域也是左右两部分组成
 */
.form-area .select .select-item,
.form-area .select .input{
  float: left;
  height: 40px;
}
.form-area .select .select-item{
  width: 140px;
  border:1px solid #DCDFE6;
  border-right: none; /*去掉右边到边框*/
  border-radius: 4px;
  box-sizing: border-box;
  border-radius: 4px 0 0 4px;
  position: relative;
}
.form-area .select .select-item .title{
  height: 40px;
  line-height: 40px;
  padding-left:20px;
  color: #909399;
  cursor:pointer;
}
.form-area .select .input{
  width: 283px;
}
.form-area .select .input input{
  border-radius: 0 4px 4px 0;/* 这里再一次单独的设置,把之前的覆盖掉 */ 
}
/**
 * 加一个外层,做鼠标移入.select-item:hover:hover时候滑出下面的.choose-wapper,显示菜单
 * 多加一层的原因是因为ul的top值太多
 */
.form-area .select .select-item .choose-wapper{
  position: absolute;
  top:0;
  left: 0;
  /* background-color: yellow; */
  width: 100%;
  /* height: 300px; */
  z-index: 1;
  padding-top: 50px;
  display: none;
}
.form-area .select .select-item:hover .choose-wapper{
  display: block;
}
.form-area .select .select-item ul{
  background-color: #fff;
  height: 250px;
  /*max-height: 256px; 最大高度,内容不满256,以内容为准。内容超过了256,那最多只能256*/
  overflow-y: auto;
  /* position: absolute; */
  /* z-index: 2; */
  /* top:50px; */
  /* left: 0; */
  /* width: 100%; */
  box-sizing: border-box;
  border:1px solid #DCDFE6;
  border-radius: 4px;
  color: #606266;
  padding: 10px 0;
  font-size: 14px;
  /* display: none; */
}
.form-area .select .select-item ul li{
  height: 34px;
  line-height: 34px;
  padding: 0 20px;
  cursor: pointer;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;/* 文字超出宽的截断后打三个点 */
}
.form-area .select .select-item ul li.active{
  color:#00A1D6;
  font-weight: 700;
}
.form-area .select .select-item ul li:hover{
  background-color: #f5f7fa;
}
.form-area .form-item .btn-sncode{
  width: 130px;
  height: 36px;
  position: absolute;
  right: 2px;
  top: 2px;
}
.form-area .readme{
  /* margin: -40px 0; 上下都需要缩进距离,左右为0 */
  margin-top: -40px; /*  直接设置margin负数 */
  margin-bottom: 20px;
  font-size: 12px;
}

/**
 * 用css写一个多选框的效果
 * 
 */
.form-area .readme .checkbox{
  display: inline-block;
  width: 14px;
  height: 14px;
  border: 1px solid #DCDFE6;
  /* border-radius: 4px; */
  box-sizing: border-box;
}
/* :checked伪类是多选框被选中,选择中后找到它后面的兄弟元素 */
.form-area .readme input:checked + .checkbox{
  border-color: #00A1D6;
}
.form-area .readme input:checked+.checkbox::after{
  content: "";
  display: block;
  height: 10px;
  width: 10px;
  margin: 1px;
  /* border-radius: 3px; */
  background: #00A1D6;
}
.form-area .readme input{
  display: none;
}

.form-area .form-item .error{
  position: absolute;
  width: 240px;
  height: 40px;
  line-height: 40px;
  right: -255px; /* 可以设置 right:-240px */
  top:0;
  color: #f45d90;
  font-size: 12px;
  display: none;
}
/*
 * 并列选择器
 *超级厉害到方法,只要有 .hasError 就显示错误
 */
.form-area .form-item.hasError .error{
  display: block;
}
.form-area .form-item.hasError input{
  border-color: #f45d90;
}
.txtright{
  text-align: right;
}
/**
 * 按钮样式
 */
button.fill{
  width: 100%;
}
/**
 * :disbled 伪类
 * 钮禁用状态下他的样式
 */
button:disabled{
  background-color: #f5f5f5;
  color:rgba(0,0,0, .25);
  border: 1px solid #d9d9d9;
  box-sizing: border-box;
  cursor:not-allowed; /* 表示不允许的鼠标样式 */
}


.form-item.hasError 下面的 .error

1.如果有错误就找到.form-item.hasError

2..form-item.hasError 下面的 .error 显示 display: block


reset.css

/* 
  http://meyerweb.com/eric/tools/css/reset/ 
  v2.0 | 20110126
  License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%; /* 可以理解为1em */
  font: inherit;
  vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
  display: block;
}
body {
  line-height: 1; /* 行高是1 */
}
ol, ul {
  list-style: none;
}
blockquote, q {
  quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}

/**
 * 初始化a元素
 */
a{
  text-decoration: none;
  color: inherit;
}

/**
 * 淘宝的字体设置
 */
body{
  font: 14px/1.5 "Helvetica Neue",Helvetica,Arial,"Microsoft Yahei","Hiragino Sans GB","HeitiSC","WenQuanYi Micro Hei",sans-serif;
}

/**
 * 重置表单元素
 */
input,
textarea,
button,
select{
  border: none;
}
input:focus,
textarea:focus,
button:focus,
select:focus{
  outline:none;
  outline-offset:0;
}


firstTime 20220130

firstTime 20251004


Leave a comment 0 Comments.

Leave a Reply

换一张