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 是浏览器设置的现默认样式了
分析一下浏览器默认给聚焦样式哪些设置(课程里不是 :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:;">已有账号,直接登录 ></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