HtmlandCss基础4
Forms
Introduction
- Build forms
- Style forms
- Text fields
- Data lists
- Drop-down lists
- Check boxes
- Radio buttons
- Sliders
- File inputs
- Hidden fields
Creating a Basic Form
现在我们来创建一个基本的表单。
首先表单的标签是<form>
,在一个表单里面还可以有多个 <input>
1 | <form> |
我们这里之所以使用label
是因为lable
是行内块,而用<p>
元素是段落块,导致Name会出现在文本框上面,不美观。
此外,这里将label与input联系起来了,for='name',id='name'
匹配之后,直接点击label就可以将光标锁定到文本框,如下所示
此外还有email
类型的,这样,当提交表单的时候如果输入的不是email,就会报错,能提供一定程度上的数值验证。
最后我们写两个button,很简单:
1 | <button type="submit" >Register</button> |
Styling Forms
我们发现这个表单太丑了,怎么美化一下呢?
1 | body{ |
但是如果所有css都我们自己写,这未免也太过繁琐了。因此接下来我们来学CSS Framework
CSS Frameworks
CSS 框架其实就是一个已经写好了的CSS代码库。我们常用的CSS库如下:
- Bootstrap
- Foundation
- UI Kit
- Semantic UI
- Materialize
- Miligram
这里我们要使用Bootstrap来美化表单。要下载Bootstrap,访问:https://getbootstrap.com/docs/5.1/getting-started/download/即可。我们采用CDN这种下载方式,只要在html文件中引入一个连接即可:
1 | <link |
然后我们就可以使用Bootstrap了。
比如说我要用Bootstrap中的 Email 文本框,就可以模仿bootstrap的写法来修改我们的html页面。因为Bootstrap中对于email有其特殊的class名字,Bootstrap内置的CSS文件就会渲染这些类。
1 | <div class="form-group"> |
对于按钮,Bootstrap也有自己的一套代码库:
我们发现文本框太长了,而且间距也不是很好,我们可以这样来调整
1 | <form class="w-50"> |
w-50
就是说,这个表单占据页面宽度的一半
mb-3
就是说 margin bottom,第三档次的间隙(一共5档,越大越宽)
此外bootstrap还有很多组件,我们可以自行调用。
然而当我们使用CDN方法时,可能会导致下载css文件的时间过长从而对用户体验造成影响。因此我们再介绍一个CSS框架:Milligram
milligram不需要我们记下很多class(像bootstrap一样),只要引入一个链接,其他照常写html即可,如下:
1 |
|
而且这个css是很轻量级的,下载只需要2.5KB. 只是文本框长度啥的还需要自己调一下
Text Fields
现在我们来研究文本框。文本框有很多类型,比如说最简单的就是
<input type ="text" />
如果我们想限制填入文本的类型,比如我们只想输入的是数字,可以这么写:
<input type = "number" />
比如我希望输入的是密码,需要隐藏,可以这么写:
<input type = "password" />
如果需要填写日期,可以这么写:
<input type="date"/>
以及之前我们介绍过的: <input type = "email" />
如果我们不想要文本框,而是一个文本块。可以这么写:
<textarea cols="30" row="10"></textarea>
说明这个文本块可以容纳十行三十列的文本:
我们还可以为每一个文本框(块)设置占位符。设置placeholder
属性即可
此外我们可以设置文本框只读,只要设置readonly
或者disable
即可。readonly是可以选中文本框,但是disable连选中都不可以。<input type="email" readonly value="111">
如果我们要设置文本框的最大输入个数,可以设置maxlength
属性。比如<input type="email" maxvalue="5">
如果我们要设置自动选中,可以设置autofocus
属性。<input type="email" autofocus>
这样当刷新页面时会自动选中该文本框。
需要注意的是,textarea
并没有value这个属性,若要设置占位符,可以直接在标签内写 <textarea cols="30" row="10">Comment...</textarea>
这节课我们主要学了这几种属性:
type : text | email | password | date | number
cols, rows
placeholder
maxlength
布尔属性,不需要为其设置值: readonly | disable | autofoucus
Data Lists
现在我们来学习如何做一个下拉式选择表单:
1 | <form> |
首先我们要放一个文本框,让其list属性等于datalist的id属性。然后再在datalist下设置<option>
<option data-value="1">Austria</option>
此外我们最好设置一下data-value
属性以便后台知道我们提交时到底选中的是几号选项。
需要注意的是,这个下拉列表的样式并不是我们说了算的,而是chrome的默认样式,我们可以通过自己写css来修改这个样式。
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist
访问上面的网站我们可以找到一些样式。
Drop-down Lists
因为虽然我们有选择列表,但是用户还是可以填入它们想写的任何文本。因此我们还需要对其做一定的限制。这就要用到 Drop-down List了
1 | <form> |
Drop-down List 是不能自行填写其他内容的。和Data List 的区别在于将<datalist>
替换成<select>
即可。
此外我们还可以设置布尔属性:selected
即自动选中。
1 | <form> |
只要我们给select标签设置multiple属性,那么就没有弹出式表单了。直接可以在文本框里选,就是比较丑。
最后,select标签里面还可以以组为单位设置选项。组标签为<optgroup>
1 | <form> |
Check Boxes
1 | <form> |
这个类型的表单叫做复选框。类型为 checkbox
但是单独的<input type="checkbox" id="">
仅仅是一个可以打钩的框框。如果我们想在旁边加上文字,需要写一个label元素。且class属性需要填写label-inline
。这样milligram就会将这个label渲染成行内呈现而不是块呈现。
此外,checkbox也有disable
、checked
这类布尔属性
Radio Buttons
说完了复选框,现在我们来说单选按钮。
1 | <form> |
和checkbox 大差不差。
当然,Radio Buttons也有disable
、checked
这类布尔属性
Sliders
现在我们来创建滑动条- 类型是range
。
1 | <form> |
但是现在无法将滑动条的数值显示出来,这是JavaScript需要做的事情。
File Inputs
现在我们来看文件选择按钮。
最基础的是这样的:<input type = "file" />
此外还可以加上 multiple
这个布尔属性,允许选择多个文件
也可以设置accept=""
属性,用来指定选择文件的类型。
.jpg
只能选择jpg.jpg, .png
可以选择jpg或者pngimage/*
可以选择所有类型的图片,还有audio/*
和video/*
Grouping Related Fields
fieldset 元素可将表单内的相关元素分组。
<fieldset>
标签将表单内容的一部分打包,生成一组相关表单的字段。当一组表单元素放到 <fieldset>
标签内时,浏览器会以特殊方式来显示它们,它们可能有特殊的边界、3D 效果,或者甚至可创建一个子表单来处理这些元素。
比如:
1 | <form> |
Hidden Fields
HiddenField控件顾名思义就是隐藏输入框的服务器控件,它能让你保存那些不需要显示在页面上的且对安全性要求不高的数据。
1 | <form> |
Data Validation
数据验证其实是一项很重要的功能,否则会带来千奇百怪的bug。那么怎么保证客户输入的数据符合规范呢?
数据验证既可以在后端做(Mongo - Data Validation) 也可在前端用 html完成一些简单的数据验证。
最基本的,就是规定某个文本框一定要填写:
1 | <form> |
<input type="text" required minlength="3" maxlength="10" />
还可以设置最少填入字数以及最大填入字数
Submitting the Form
1 | <form> |
这是最简单的一张表单。对于提交按钮有两种写法:
1 | <button type="submit">Submit</button> |
但是第二种不能给其另外添加icon了
设计完表单之后我们就要提交了。一般来说提交到我们自己写的后台,如Node、Django之类的。但是这里为了方便起见,我们用一个网站来实现后台功能:https://formspree.io/forms
注册以后,我们创建一个新的 Form,与此同时该网站会自动生成一个后台。我们只需要复制一个连接到我们的HTML文件中即可:
1 | <form action="https://formspree.io/f/xzbykqky" method = "POST"> |
注意,这边要成功提交,需要设置 name属性以及method属性
现在我们来解释一下 GET和POST有什么区别:
当我们设置Method为POST的时候,数据是放在请求体里的。
而当我们设置Method为GET的时候,数据是放在URL中的
Google搜索都是用GET方式的。
Transformations,Transitions,and Animation
这一章我们要学习一些关于变形、过渡动画的内容。
Transformations
CSS中有一个专门的属性叫 transform
里面有很多方法,最基本的有:
rotate(angle)
: 定义 2D 旋转,在参数中规定角度。skew(x-angle,y-angle)
: 定义沿着 X 和 Y 轴的 2D 倾斜转换。scale(x[,y]?)
定义 2D 缩放转换。translate(x,y)
定义 2D 转换。
比如说我设置了一个Box,然后设置了CSS格式:
1 | .box:hover{ |
这样当我的鼠标移动到box上去,box就会正向旋转60°。当这个变化是瞬时的,并不是一个动画。如果是-60deg
,那么就是反向旋转60°
scale是放缩,可大可小,括号内写的是放大或缩小的倍数
1 | .box:hover{ |
如果是skew
那么就是斜线变换, 若是负数就是反向变换:
1 | .box:hover{ |
如果是translate(10px)
那么就会让box沿着水平线正向移动10px,如果是translate(10px,10px)
,那么就会在水平移动的时候同时在垂直方向移动。
1 | .box:hover{ |
此外,还可以安排多个转变。比如先移动,然后旋转:
1 | .box:hover{ |
需要注意的是,变形的顺序不同对最终的结果影响也是很大的,比如我把 rotate 和 translate 交换位置:
1 | .box:hover{ |
3D Transformations
上面我们说的都是关于x、y轴的变换,其实每一种变换都是可以在3维空间中进行的
translateX(x) | 定义 3D 转化,仅使用用于 X 轴的值。 |
---|---|
translateY(y) |
定义 3D 转化,仅使用用于 Y 轴的值。 |
translateZ(z) |
定义 3D 转化,仅使用用于 Z 轴的值。 |
scale3d(x,y,z) |
定义 3D 缩放转换。 |
scaleX(x) |
定义 3D 缩放转换,通过给定一个 X 轴的值。 |
scaleY(y) |
定义 3D 缩放转换,通过给定一个 Y 轴的值。 |
scaleZ(z) |
定义 3D 缩放转换,通过给定一个 Z 轴的值。 |
rotate3d(x,y,z,angle) |
定义 3D 旋转。 |
rotateX(angle) |
定义沿 X 轴的 3D 旋转。 |
rotateY(angle) |
定义沿 Y 轴的 3D 旋转。 |
rotateZ(angle) |
定义沿 Z 轴的 3D 旋转。 |
perspective(n) |
定义 3D 转换元素的透视视图。 |
- translate
1 | .box :hover { |
perspective()
规定 3D 元素的透视效果。
- rotate
1 | .box :hover { |
其中transform-Origin
属性允许我更改转换元素的位置。其中两参数分别代表视图被放在x轴、y轴的何处。
Transitions
上面我们展示的都是“突变”,那么是时候在它们之间加点过渡了。
transition 属性设置元素当过渡效果,四个简写属性为:
- transition-property
- transition-duration
- transition-timing-function
- transition-delay
语法:transition: property duration timing-function delay;
值 | 描述 |
---|---|
transition-property | 指定CSS属性的name,transition效果 |
transition-duration | transition效果需要指定多少秒或毫秒才能完成 |
transition-timing-function | 指定transition效果的转速曲线 |
transition-delay | 定义transition效果开始的时候 |
比如我要对一个旋转做过渡效果:
1 | .box { |
此外我们可以设置运动的快慢:
1 | transition: transform 0.5s ease-in; //先快后慢 |
还可以设置cubic-bezier()
函数,来自定义变换速度:到这里去定制
我设置 transition-delay
为1s,那么就说嘛我鼠标移动到box后一秒才出发过渡。
此外我们还可以设置颜色渐变:
Animation
- 语法
1 | animation: name duration timing-function delay iteration-count direction fill-mode play-state; |
值 | 说明 |
---|---|
animation-name | 指定要绑定到选择器的关键帧的名称 |
animation-duration | 动画指定需要多少秒或毫秒完成 |
animation-timing-function | 设置动画将如何完成一个周期 |
animation-delay | 设置动画在启动前的延迟间隔。 |
animation-iteration-count | 定义动画的播放次数。 |
animation-direction | 指定是否应该轮流反向播放动画。 |
animation-fill-mode | 规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式。 |
animation-play-state | 指定动画是否正在运行或已暂停。 |
initial | 设置属性为其默认值。 阅读关于 initial的介绍。 |
inherit | 从父元素继承属性。 阅读关于 initinherital的介绍。 |
首先,我们创建了一个animation,叫做pop。在pop中我们要定义一些关键帧,比如这里我设置了在一开始是不懂得,到了四分之一的时候会变大,到了一半的时候会旋转,到了最后会变回原样。
1 |
|
Reusable Animations
如果我写了一个很好地动画,想给很多的元素用,但是又不想写这么多的重复代码,怎么办?
我们可以直接对一个类进行渲染,比如:
1 | .animation-pop { |
这样,当某个元素要用这套动画的时候,只要在class中加上animation-pop
即可。
最后来介绍一下Animate网站,它有很多现成的动画供我们使用。只要在HTTP文件中引入一个链接即可
然后,只要给想要动画的元素加一个类,就可以获得该动画了
Writing Clean,Maintainable CSS
CSS Best Practices
接下来我们来介绍几个能让CSS简洁、可维护的好习惯
- Follw a naming convention 命名要符合规范
通常有这样几种CSS命名规范:
- .nav-bar {} Kebab case 词与词之间用
-
隔开 - .navBar {} Camel case
- .NavBar {} Pascal case
- .nav_bar{} Snake case
- .nav-bar {} Kebab case 词与词之间用
- Create logical section in your stylesheet
写一个CSS文件需要组织得富有逻辑。比如说:
1 | /* Basic styles */ |
- Avoid over-specific selectors : 不要写特别具体的选择器
比如说有一个列表:
1 | <div class="nav"> |
理想的选择器是这样的:.nav .item
我们不要搞得很复杂比如:div.nav > ul.items > li
,这样耦合度太高了
- 合理的类命名。
我们同样举这个例子,如果有一个针对 .item
的一般性的css样式,那么很可能其样式会覆盖我们上面指定的.nav .item
.因此,我们可以将 <li class = "item">Link 1</li>
改为<li class = "nav-item">Link 1</li>
。用来表明该item是在nav中的。
不要使用
!important
Sort CSS properties : 对于乱糟糟的CSS属性,我们最好按照一定顺序排列一下(可以使字母表顺序)
比如:
1 | .nav-item { |
可以shift+command+p 呼唤出控制面板,搜索sort后排序。
- Take advantage of style inheritance
对于字体这类的作用范围比较广的样式,我们可以对总体设置,这样细枝末节的字体就会自动继承其父元素的字体,就不需要我们再去设置了。
- Extract repetitive patterns
- Keep code DRY(Don’t repeat your code)
Variables
对于一些常用的样式,比如说常见的颜色,我们不需要一遍一遍得打rbg,而是可以用变量将它们存储起来:
1 | :root{ |
注意变量书写和引用的格式
Object-oriented CSS
BEM
BEM的全称是:Block Element Modifier
BEM是一个非常有用,强大,简单的命名约定,可以让你的前端代码更容易阅读和理解,更容易协作,更容易控制。
当然,通常人们会认为BEM写法难看,但是他的好处远远超过它外观上的那点瑕疵。
- BEM命名约定
BEM:块(block)、元素(element)、修饰符(modifier)下面是命名约定的模式
1 | .block{} |
其中块可以用单个连字符来界定:如
1 | .site-search{} //块 |
- 如何使用BEM
Block:一个独立的,可以复用而不依赖其他组件的部分,可作为一个块
Element:属于块的某部分,可作为一个元素
Modifier:用于修饰块或元素,体现出外形行为状态等特征的,可作为一个修饰器
规范:
1)保证各个部分只有一级B__E–M
,修饰器需要和对应的块或元素一起使用,避免单独使用。
2)仅以类名作为选择器,不使用ID或标签名来约束选择器,且css中的选择器嵌套不超过2层
3)避免 .block__el1__el2
的格式