一直使用 Vue/React ,习惯了用组件,偶尔想用原生三剑客写点 Demo 发现样式丑的不忍直视。最近看 掘金小册《玩转CSS的艺术之美》看到 CSS 相关的内容,发现原生 CSS 也可以把表单处理的很好看。

效果:

完整代码:

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.form-box {
width: 500px;
} .form-item {
display: flex;
align-items: center;
margin-bottom: 10px;
} label {
display: block;
font-size: 16px;
flex: 90px 0 0;
} label::after {
content: ":";
margin-right: 6px;
display: inline-block;
vertical-align: middle;
} input.text-input {
display: block;
padding: 0 10px;
border: 1px solid #ccc;
width: 100%;
height: 40px;
outline: none;
caret-color: #09f;
/*光标颜色*/
transition: all 300ms;
border-left-width: 5px;
} input.text-input:valid {
border-color: #3c9;
} input.text-input:invalid {
border-color: #f66;
}
input[type=checkbox] {
position: relative;
appearance: none;/*去除系统默认appearance的样式引发的问题*/
cursor: pointer;
transition: all 100ms;
border-radius: 31px;
width: 70px;
height: 40px;
background-color: #e9e9eb;
outline: none;
margin: 0;
display: inline-block;
}
input[type=checkbox]::before {
position: absolute;
content: "";
transition: all 300ms cubic-bezier(.45, 1, .4, 1);
border-radius: 31px;
width: 70px;
height: 40px;
background-color: #e9e9eb;
}
input[type=checkbox]::after {
position: absolute;
left: 4px;
top: 4px;
border-radius: 27px;
width: 32px;
height: 32px;
background-color: #fff;
box-shadow: 1px 1px 5px rgba(#000, .3);
content: "";
transition: all 300ms cubic-bezier(.4, .4, .25, 1.35);
}
input[type=checkbox]:checked {
background-color: #3c9;
}
input[type=checkbox]:checked::before {
transform: scale(0);
}
input[type=checkbox]:checked::after {
transform: translateX(30px);
}
button {
width: 48%;
height: 40px;
padding: 0;
margin: 0;
border: none;
outline: none;
cursor: pointer;
border-radius: 5px;
overflow: hidden;
position: relative;
background: #63c3ff;
color: #fff;
}
button::before {
--size: 0;
position: absolute;
left: var(--x);
top: var(--y);
width: var(--size);
height: var(--size);
background-image: radial-gradient(circle closest-side, #09f, transparent);
content: "";
transform: translate3d(-50%, -50%, 0);
transition: width 200ms ease, height 200ms ease;
}
button[type=reset] {
background: #6fcc6f;
}
button[type=reset]::before {
background-image: radial-gradient(circle closest-side, #4abf4a, transparent);
}
button:hover::before {
--size: 400px;
}
button:first-child {
margin-right: 4%;
}
span {
position: relative;
pointer-events: none;
}
</style>
</head> <body>
<form class="form-box" id="form" onsubmit=onSubmit(event)>
<div class="form-item">
<label>昵称</label>
<input type="text"
name="name"
class="text-input"
placeholder="请输入昵称(3-20个字符,仅限英文字母,数字和下划线)"
pattern="^[\w]{3,20}$"
oninput="setCustomValidity('')"
oninvalid="setCustomValidity('请输入合法的昵称>_<')"
required>
</div>
<div class="form-item">
<label>邮箱</label>
<input type="email"
class="text-input"
placeholder="请输入邮箱地址"
required>
</div>
<div class="form-item">
<label>密码</label>
<input type="password"
name="password"
class="text-input"
placeholder="请输入密码"
oninput="onPwdInput(event)"
required>
</div>
<div class="form-item">
<label>确认密码</label>
<input type="password"
name="password"
id="confirmPwd"
class="text-input"
placeholder="请输入密码"
required>
</div>
<div class="form-item">
<label>VIP</label>
<input name="isAdult" type="checkbox" />
</div>
<div class="form-item">
<button type="reset" onmousemove="move(event)">
<span>重 置</span>
</button>
<button type="submit" value="提 交" onmousemove="move(event)">
<span>提 交</span>
</button>
</div>
</form> <script>
function move(e) {
const x = e.pageX - e.target.offsetLeft;
const y = e.pageY - e.target.offsetTop;
e.target.style.setProperty("--x", `${x}px`);
e.target.style.setProperty("--y", `${y}px`);
}
function onSubmit(e) {
e.preventDefault(); // 阻止表单提交
const form = e.target;
console.log(params);
}
function onPwdInput(e) {
confirmPwd.pattern = e.target.value;
}
</script>
</body> </html>

顺便说一下代码里涉及的知识点

1、属性选择器

一般用的较多 CSS 选择器的是ID、类、和标签选择器。属性选择器也有各种灵活的使用方式。语法是中括号。

[attr] 表示带有以 attr 命名的属性的元素。

[attr=value] 表示带有以 attr 命名的属性,且属性值为 value 的元素。

还有其他限制开头、结尾、包含等规则,可以自己查找。

2、表单状态选择器

 :valid 和  :invalid  分别对应合法的表单元素和不合法的表单元素。
 
3、appearance: none

appearance 主要有两种用途,要将平台特定的样式应用于默认情况下不包含该样式的元素,删除默认情况下具有特定于平台的样式的元素。

上面代码中的  appearance: none  就是删除  checkbox  原有的样式。

<div style="appearance: button;">button</div> 可以让你一个 div 显示原生按钮样式。(不过兼容性不大好,我试了下Chrome并没有生效, -webkit-appearance 在Safari中生效了)

4、pointer-events: none

指定  pointer-events: none; 的元素永远不会成为鼠标事件的 target。禁用其鼠标事件和鼠标相关样式。

但是,当其后代元素的pointer-events属性指定其他值时,鼠标事件可以指向后代元素,在这种情况下,鼠标事件将在捕获或冒泡阶段触发父元素的事件侦听器。

5、表单验证

required:任何带有 required 属性的字段都必须有值,否则无法提交表单。

input type:  HTML5 为  <input>  元素增加了几个新的 type 值。这些类型属性不仅表明了字段期待的数据类型,而且也提供了一些默认验证,其中两个新的输入类型是已经得到广泛支持的 "email" 和 "url"。

pattern:文本字段  pattern  属性,用于指定一个正则表达式,用户输入的文本必须与之匹配。在重复输入密码的时候,把第一次的密码作为重复密码的 pattern  以保证两次输入密码一致性验证。

setCustomValidity: 自定义表单不合法时的提示信息。

表单 reset(): 把表单字段重置为各自的默认值。

6、CSS 变量

在 JavaScript 接受鼠标事件参数并将鼠标位置赋值给 CSS 变量,就可以根据设置跟随鼠标移动的样式了。

原生CSS、HTML 和 JavaScript 实现酷炫表单的更多相关文章

  1. WTF Forms – 使用 CSS 实现用户体验更好的表单

    WTF forms 借助 CSS 提供友好的 HTML 表单控件,专为 IE9+ 以及最新的 Chrome.Safari 和 Firefox 浏览器.以文件输入控件的改进,使用 label 包裹在 i ...

  2. ajax+FormData+javascript实现无刷新表单信息提交

    ajax+FormData+javascript实现无刷新表单信息提交 原理: dom收集表单信息,利用FormData快速收集表单信息  ,实例化表单数据对象 同时收集fm的表单域信息. var f ...

  3. Javascript中的Form表单知识点总结

    Javascript中的Form表单知识点总结 在HTML中,表单是由form元素来表示的,但是在javascript中,表单则由HTMLFormElement类型,此元素继承了HTMLElement ...

  4. ajax+FormData+javascript 实现无刷新表单注册

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  5. JavaScript 创建一个 form 表单并提交

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  6. 每天一个JavaScript实例-防止反复表单提交

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  7. 精通CSS+DIV网页样式与布局--设置表单和表格

    表格和表单是网页中非常重要的两个元素,在上篇博客中,我们简单的介绍了CSS的页面背景设置,今天小编继续来介绍CSS的相关知识,在我们的CSS中如何设置表格和表单,首先,来看一张思维导图,通过图简单的预 ...

  8. javascript中的常用表单事件用法

    下面介绍几种javascript中常用的表单事件: 一,onsubmit:表单中的确认按钮被点击时发生的事件,如下案例. 案例解析:弹出表单中提交的内容 <form name="tes ...

  9. 第一百六十节,封装库--JavaScript,ajax注册表单到数据库

    封装库--JavaScript,ajax注册表单到数据库 效果图 前台js var biaodan = $().xu_lie_biao_dan($('form').sh_jd()); //序列化获取表 ...

  10. 纯原生javascript下拉框表单美化实例教程

    html的表单有很强大的功能,在web早期的时候,表单是页面向服务器发起通信的主要渠道.但有些表单元素的样式没办法通过添加css样式来达到满意的效果,而且不同的浏览器之间设置的样式还存在兼容问题,比如 ...

随机推荐

  1. 周末玩一下云技术,kvm 相关笔记

    由于需要将企业的很贵的显卡和主机装在一个虚拟主机,用来跑  ue5 和 sd3  用来给用户临时使用,但是怎么将主机虚拟出来成多个主机呢,自己没有有钱请不起人,只能自己学一下虚拟化技术,第一步主机开启 ...

  2. springboot 3.x MultipartFile 参数总是为空 参数传递不进来

    场景: 在写一个统一文件上传的时候,MultipartFile参数一直传递不进来,一直为空. 排错方法: 我先是将业务简化,使用api文档进行测试,测试是前端问题还是后端问题. 简化后业务: 用api ...

  3. python lambda 三元表达式

    python lambda 三元表达式 python中的lambda函数用法 通常定义的函数 def sum(x,y): return x+y print(sum(4,6)) 用lambda来实现: ...

  4. Win11不在C盘安装WSL2(Linux环境),安装Nvidia驱动和默认使用Win11的网络代理服务

    众所周知,WSL 2 为 Windows 用户提供了一个强大.高效且灵活的 Linux 环境,特别适合开发者使用.它结合了 Windows 和 Linux 的优点,为用户提供了更加全面和高效的工作环境 ...

  5. 【Hibernate】Re08 加载策略配置

    一.关联查询的问题: 使用关联查询,例如简单的一对多关系查询,查出一个部门对象和对应的N个员工对象. 如果一般情况下,我们只是需要部门对象,并不关系关联的员工对象,那么Hibernate关联查询出来的 ...

  6. 怎么在Ubuntu系统云服务器搭建自己的幻兽帕鲁服务器?幻兽帕鲁搭建教程

    <幻兽帕鲁>是一款备受瞩目的开放世界生存建造游戏,近期在游戏界非常火爆.玩家可以在游戏世界中收集神奇的生物"帕鲁",并利用它们进行战斗.建造.农耕.工业生产等各种活动. ...

  7. 树莓派3B+ 安装开源软路由 openwrt 并设置 无线网桥

    在openwrt官网上找到最新版的下载地址: https://openwrt.org/releases/19.07/start 注:   本文中使用的openwrt 系统为最新的稳定版系统,自带web ...

  8. 【转载】 python之理解super及MRO列表

    原文地址:   https://www.jianshu.com/p/de7d38c84443 ----------------------------------------------------- ...

  9. 7月30日CSP-S模拟赛赛后总结

    7月30日模拟赛赛后总结 \[7月30日 \ \ 模拟赛 \ \ 赛后总结 \\ 2024年7月30日 \\ by \ \ \ hcy \] 洛谷同步:点我 一.做题情况 第一题比赛 \(100pts ...

  10. MySQL 5.7 DDL 与 GH-OST 对比分析

    作者:来自 vivo 互联网存储研发团队- Xia Qianyong 本文首先介绍MySQL 5.7 DDL以及GH-OST的原理,然后从效率.空间占用.锁阻塞.binlog日志产生量.主备延时等方面 ...