java web之html和css
web: 万维网,world wide web, 能够通过浏览器访问的网站。
前端三要素:html(文档结构)+css(样式)+javascript(方法)
- HTML: HTML是超文本标记语言,是一种用于创建网页并设计网页结构的标记语言。HTML元素包括标题,段落,链接,图像,列表等,用于表达文本和多媒体内容,超文本指链接、图像、视频、音频等;标记就是一组标签,比如
<a></a>
表示超链接 - CSS:CSS是层叠样式表,它是一种用于描述HTML文档呈现方式的语言。通过CSS,我们可以控制网页中文字,元素和背景的颜色、大小、位置和形状等展现效果,从而呈现出美观,易读和有效率的网页。
<!doctype html> 声明为html
<html lang="zh-CN"> 指定html的开始以及语言设置为中文(英文是en)
<head>
<meta charset="utf-8"> 用于指定网页的字符集编码(utf-8能识别所有语言)
<title>html演示</title>
<style> # css设置
#d1{
font-size: large;
color: aqua;
}
</style>
</head>
<body> 需要展示的信息
<h1>hello world</h1>
<h2 style="color: red">hello world</h2>
<div id="d1"></div>
</body>
<script type="application/javascript">
document.getElementById('d1').append('你好')
</script>
</html>
常用html标签
Meta 元素可提供有关页面的元信息(meta-information),针对搜索引擎和更新频度的描述和关键词。
meta标签提供了元数据,元数据也不显示在页面上,但会被浏览器解析。
META元素通常用于指定网页的描述,关键词,文件的最后修改时间、作者,和其他元数据。
元数据可使用于浏览器(如何显示内容或重新加载页面),搜索引擎(关键词),或其他web服务。
meta标签的组成:meta标签有两个属性,它们分别是http-equiv属性和name属性,不同的属性又有不同的参数值,这些不同的参数值就实现了不同的网页功能。
标题使用<h1>至<h6>标签进行定义。<h1>定义最大的标题,<h6>定义最小的标题。
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>html演示</title>
</head>
<body>
<h1>hello world</h1>
<h4 style="color: red">hello world</h4>
<i>i你好</i> <!-- 斜体 -->
<em>em你好</em> <!-- 斜体 -->
<s>s你好</s> <!-- 删除线标签 -->
<u>u你好</u> <!--下划线标签-->
<b>b你好</b> <!-- 加粗标签 -->
<strong>strong你好</strong> <!--加粗标签-->
<br> <!--换行符-->
<hr> <!--水平线标签-->
<pre> <!--预处理标签(预格式化文本)-->
<span>上标 x<sup>2</sup>
下标x<sub>i</sub></span>
</pre>
<p>段落paragraph标签(块级元素)</p>
</body>
</html>
块级元素和行内元素:
div标签
<div> 用来布局 </div>
div标签是用来布局的,并没有语义,只是一个区块。
块级元素:以块的方式呈现,会占据整行的空间,在块级元素后添加元素会换行。
span标签
<span> 包裹文字 </span>
span标签,没有语义,一般用来包裹文字,让文字更好被选中。
行内元素:不会独占一行,它是自左向右排列,一行排满再换行。
块级元素如何转行内元素?需要在块级元素的css属性添加
display:inline-block
超链接标签
1、外部链接(链接到外部文件)
<a href="a.html">跳转到a.html页面</a>
<a href="./a.html">跳转到a.html页面</a> 与上面等同
<a href="../a.html"></a> 指向上一级的a.html
<a href="http://www.baidu.com" target="_blank">进入百度</a>
注意:a.html页面位置与当前页面在同一目录下;这里也可以使用绝对路径。
2、锚点链接
<a href="a.html">跳转到a.html页面</a>
<div style="height: 600px"></div>
<span id="m1">中部</span> <!--定义锚点,使用id/name属性-->
<div style="height: 600px"></div>
<div style="height: 600px"></div>
<div style="height: 600px"></div>
你好v法国v夫i还是低哦哦法国无人机
<a href="#">返回顶部</a> <!-- #锚点,回到顶部, 特殊锚点-->
<a href="#m1">返回中部</a> <!--跳转到指定锚点-->
<a href="a.html#out">跳转到a.html的锚点</a><!--跳转到其他页面的锚点-->
特殊的几个链接:
a、返回页面顶部的位置:<a href="#">跳转到顶部</a>
b、与js有关:
(1) javascript:;
表示什么都不执行,这样点击<a>
时就没有任何反应,例如:
<a href="javascript:;">内容</a>
<a href="javascript:void(0);">内容</a>
超链接的属性
href:目标URL;
title:悬停文本;
name:主要用于设置一个锚点的名称;
target:告诉浏览器用什么方式来打开目标页面;target属性有以下几个值:
- _self:在同一个网页中显示(默认)
- _blank:在新的窗口中打开
- _parent:在父窗口中显示
- _top:在顶级窗口中显示
超链接相关的伪类元素
a:link - 正常,未访问过的链接
a:visited - 用户已访问过的链接
a:hover - 当用户鼠标放在链接上时
a:active - 链接被点击的那一刻
多媒体
img标签:img代表的就是一张图片。是自封闭标签,也称为单标签。
<img src="图片路径" alt="图片未显示成功时的提示说明" />
video视频标签:
<video src="a.mp4" width="300" controls></video>
必须要设置controls属性才能播放
audio音频标签:
<audio src="b.mp3" controls></audio>
列表、表单、表格
列表标签分为 有序列表和 无序列表
ol 有序列表(order list)
属性:type:1、A、a、I、i(数字、字母、罗马数字),start表示从几开始
<ol type="1" start="3">
<li>java</li>
<li>python</li>
<li>go</li>
</ol>
ul 无序列表(unorder list)
属性:type :三个值,分别为 circle(空心圆) ,disc(默认,实心圆),square(黑色方块)
<ul type="square">
<li>java</li>
<li>python</li>
<li>go</li>
</ul>
列表css属性:list-style-type:none
表格:border默认是0,无边框,cellspacing=0表示单元格之间间距是0,cellpadding表示单元格内容和单元格的外边距
<table border="1" cellspacing="0" cellpadding="3">
<caption>成绩表</caption> 表格的标题
<thead>
<tr>
<th>姓名</th>
<th>语文</th>
<th>数学</th>
</tr>
</thead>
<tbody>
<tr>
<td>张三</td>
<td>109</td>
<td>111</td>
</tr>
<tr>
<td>李四<a href="a.html#out">跳转</a></td>
<td>121</td>
<td>141</td>
</tr>
</tbody>
</table>
结果如下:
姓名 | 语文 | 数学 |
---|---|---|
张三 | 109 | 111 |
李四 | 121 | 141 |
单元格的合并
横向合并:colspan,例如colspan=”2” 表示当前单元格在水平方向上要占据两个单元格的位置。
纵向合并:rowspan,例如rowspan=”2” 表示当前单元格在垂直方向上占据两个单元格的位置。
<table border="1" cellspacing="0" cellpadding="3">
<thead>
<tr>
<th>姓名</th>
<th colspan="2">成绩</th>
</tr>
</thead>
<tbody>
<tr>
<td>张三</td>
<td rowspan="2">109</td> <!--说明两者的成绩都是109-->
<td>111</td>
</tr>
<tr>
<td>李四<a href="a.html#out">跳转</a></td>
<td>141</td>
</tr>
</tbody>
</table>
结果:
姓名 | 成绩 | |
---|---|---|
张三 | 109 | 111 |
李四 | 141 |
表单标签
表单标签用<form>
表示,用于与服务器的交互。表单就是用来收集数据并提交到服务器。
属性:action 指定表单提交的地址
method 表单数据的提交方式,一般取值:get(默认)和post(较安全)方法。
<input>输入标签(文本框),需要添加type属性 name属性(后端获取数据时需要根据name属性获取)
input 的type有:text(默认)文本框,password密码框
radio: 单选按钮,name相同的一组元素进行单选
checkbox:复选框,name相同的一组元素进行选择
checked:单选/多选按钮默认选中
hidden:隐藏框,在表单中包含不希望用户看见的信息
button:普通按钮, 结合js进行使用
submit:提交按钮,将表单数据提交给服务器
reset:重置按钮,清空当前表单的数据,恢复到默认状态
image: 图片按钮,和提交按钮完全一致,只不过按钮可以显示图片
number: 数字框,可以设定最大最小值
<input type="number" min="1" max="10" />
file:文件选择框(注:file选择框需要设置form提交方式为post提交, 设置enctype='mutlipart/form-data'
)
date: 日期选择框
<form action="http://localhost:8888/test/form_submit" method="post" enctype="multipart/form-data">
<label for="t1" title="普通文本框">用户名:</label>
label标签用于定义某些标签文本,使得用户点击标签文本就可以聚焦到对应的标签,加强用户的体验效果
<input id="t1" type="text" name="username" /><br><br>
<label for="t2" title="密码框">密码:</label>
<input id="t2" type="password" name="password" required /><br>
<input type="hidden" name="id" value="187" /><br>
<label for="t3">生日:</label>
<input id="t3" type="date" name="birthday" /><br><br>
性别:<br>
<label>
男<input type="radio" name="sex" value="男" checked />
</label>
<label>
女<input type="radio" name="sex" value="女">
</label><br><br>
兴趣爱好:
<label>
乒乓球<input type="checkbox" name="hobby" value="乒乓球" />
</label>
<label>
下棋<input type="checkbox" name="hobby" value="下棋" />
</label>
<label>
瑜伽<input type="checkbox" name="hobby" value="瑜伽" />
</label><br><br>
上传头像:<input type="file" name="avatar" /><br><br>
<input type="submit" />
</form>
使用springboot创建后端服务程序
@Controller
@RequestMapping("test")
public class TestController {
@PostMapping(value = "form_submit")
@ResponseBody
public String getDataFromForm(User user, MultipartFile avatar){
// MultipartFile 文件变量名(input文件上传必须要用MultipartFile类来接受,
// 而且名字要和input标签的name一致)
System.out.println(user);
System.out.println(avatar.getOriginalFilename());
AtomicReference<String> result = new AtomicReference<>("提交失败!");
Optional.ofNullable(user).ifPresent(user1 -> result.set("提交成功!"));
return result.get();
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class User{
private String username;
private String password;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate birthday;
private String sex;
private String[] hobby;
}
<details>
标签用于创建一个可展开或可折叠的内容区域,通常与<summary>
标签一起使用,其中<summary>
标签中的文本是可点击的标题。
<abbr>
标签用于表示缩写词或简称,通常用于显示那些需要解释的全称或较长版本的文本。
结果:
<nav>
导航标签,用于标识网页中的导航链接
<nav>
<ul>
<li><a href="/home">首页</a></li>
<li><a href="/about">关于我们</a></li>
<li><a href="/contact">联系我们</a></li>
</ul>
</nav>
<nav>标签只是表示这些链接是导航链接,它并没有提供任何额外的样式或行为。
下拉菜单
<select>
标签是 HTML 中用于创建下拉菜单的元素。它通常包含一个或多个 元素,每个选项都有一个文本值和一个可选的自定义值。
<select name="fruits">
<option value="apple">苹果</option>
<option value="banana" selected>香蕉</option>
<option value="cherry">樱桃</option>
</select>
css使用
使用CSS的三种方式:
- 内联样式,直接在标签内添加style属性,style里面编写css
<p style="color:green;font-size:20px;"></p>
- 嵌入样式,在head标签编写css
<head>
<style>
p { /* 元素选择器 */
color:green;
font-size:20px;
}
</style>
</head>
- 外部引入,外部编写css文件,在html head中引入
<head>
<link rel="stylesheet" href="a.css"> <!--引用a.css文件-->
</head>
css常见属性
width:设置元素的宽度。
height:设置元素的高度。
letter-spacing: 文字之间的间距。
color:设置文本的颜色。
background-color:设置元素的背景颜色。
font-size:设置文本字体的大小。
font-width: 设置字体的粗细。
font-family:设置文本字体的样式。
margin:设置元素的外边距。
padding:设置元素的内边距。
border:设置元素的边框样式。
display:设置元素的显示方式。
position:设置元素的定位方式。
float:设置元素的浮动方式。
text-align:设置文本的对齐方式。
line-height:设置行高。
opacity:设置元素的透明度。
box-shadow:设置阴影效果。
background-position :属性接受两个参数,水平位置 和垂直位置,设置背景相对于原始位置的偏移。
CSS选择器
SS选择器是一种模式,用于选择想要样式化的HTML元素。 以下是一些常用的CSS选择器:
标签选择器:它选择所有使用特定HTML元素的元素。例如,p选择器将选择所有的
元素。
p {
color: red;
}
类选择器:它选择具有特定类属性的所有元素。例如,.example
选择器将选择所有具有class="example"的元素。
.example {
color: blue;
}
ID选择器:它选择具有特定ID属性的单个元素。例如,#unique
选择器将选择具有id="unique"的单个元素。
#unique {
color: green;
}
属性选择器:它选择具有特定属性的所有元素。例如,[target=“_blank”]选择器将选择所有具有target="_blank"属性的元素。
[target="_blank"] {
color: purple;
}
后代选择器:它选择特定元素的后代。例如,div p选择器将选择所有<div>
元素中的<p>
元素。
div p {
color: orange;
}
子元素选择器:它选择特定元素的直接子元素。例如,div > p选择器将选择所有<div>
元素的直接<p>
子元素。
div > p {
color: pink;
}
相邻兄弟选择器:它选择特定元素后面的第一个兄弟元素。例如,h1 + p选择器将选择所有紧接在<h1>
元素后面的<p>
元素。
h1 + p {
color: gray;
}
通用选择器:它匹配文档中的任何元素。例如,*选择器将匹配文档中的所有元素。
* {
color: black;
}
伪类选择器
:first-child:选择父元素的第一个子元素。
:last-child:选择父元素的最后一个子元素。
:nth-child(n):选择父元素的第n个子元素。
:nth-last-child(n):选择父元素的倒数第n个子元素。
:not(selector):选择非指定选择器的元素。
:hover:选择鼠标悬停在元素上的状态。
:active:选择被激活(被点击)的元素。
:focus:选择获得焦点的元素。
:checked:选择被选中的表单元素(如复选框、单选按钮)。
:disabled:选择被禁用的表单元素。
:empty:选择没有子元素的元素。
:first-of-type:选择父元素中具有相同类型的第一个元素。
:last-of-type:选择父元素中具有相同类型的最后一个元素。
:nth-of-type(n):选择父元素中具有相同类型的第n个元素。
:after 在元素后面添加内容(显示内容,必须添加content:'')
:before 在元素之前添加内容
css三大特征
- 层叠性:多个css属性设置时,采用最后一个样式设置
- 继承性:子标签会继承父标签的某些样式
- 优先级:当多个CSS样式同时作用于一个元素时,通过优先级大小决定元素样式
- 内联样式的优先级最高
<style> * { color: 'green' } </style> <p style='color: red'>hello</p> 这里会展示红色
- id选择器 > class选择器 > 标签选择器
<style> #id1 { color: blue; } .class1 { color: red; } div { color: green; } </style> <div id="id2" class="class1"> This text will be blue because the ID selector has higher priority. </div>
CSS单位
浏览器默认字体大小是16px
px(像素)是一种绝对单位,可以根据设备的屏幕分辨率精确地指定元素的大小。例如,如果一个元素的宽度被设置为100px,那么它在任何设备上都会显示为100个像素宽。
em是相对单位,它是基于父元素的字体大小进行测量的。如果一个元素的字体大小被设置为16px,那么1em就等于16px。如果一个元素的字体大小被设置为2em,那么它的大小就是32px。
rem是相对于根元素(即html元素)的字体大小进行测量的。如果根元素的字体大小被设置为16px,那么1rem就等于16px。如果一个元素的字体大小被设置为2rem,那么它的大小就是32px。
CSS盒子模型
CSS盒子模型(Box Model)是CSS布局的基础,它描述了元素在页面上的布局方式。在CSS盒子模型中,每个元素被视为一个矩形盒子,这个盒子包含元素的内容、内边距、边框和外边距。
css属性允许指定盒子边框的样式和颜色
边框样式属性指定要显示什么样的边界。
border-style属性用来定义边框的样式
none: 默认无边框
dotted: 定义一个点线边框
dashed: 定义一个虚线边框
solid: 定义实线边框
double: 定义两个边框。 两个边框的宽度和 border-width 的值相同
groove: 定义3D沟槽边框。效果取决于边框的颜色值
ridge: 定义3D脊边框。效果取决于边框的颜色值
inset:定义一个3D的嵌入边框。效果取决于边框的颜色值
outset: 定义一个3D突出边框。 效果取决于边框的颜色值
使用border-width指定边框大小,border-color指定边框颜色(border-color单独使用是不起作用的,必须得先使用border-style来设置边框样式。)
边框简写属性:也可以在一个属性中设置边框。
border : border-width border-style(required) border-color
border-style:属性1,属性2,属性3,属性4
上->右->下->左
border-style:属性1,属性2,属性3
上->左右->下
border-style:属性1,属性2
上下->左右
border-style:属性1
上下左右属性相同
边框圆角:border-radius:2px; 也可以设置具体方向的圆角: border-bottom-left-radius: 2px;(左下圆角)
边框的box-sizing属性
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<style>
#example1 {
box-sizing: content-box;
width: 300px;
height: 100px;
padding: 30px;
border: 10px solid blue;
}
#example2 {
box-sizing: border-box;
width: 300px;
height: 100px;
padding: 30px;
border: 10px solid blue;
}
</style>
</head>
<body>
<h6>box-sizing 属性</h6>
<p>定义如何计算一个元素的总宽度和总高度,是否包含内边距和边框。</p>
<h2>box-sizing: content-box (默认):</h2>
<p>高度和宽度只应用于元素的内容:</p>
<div id="example1">这个 div 的宽度为 300px。但完整宽度为 300px + 20px (左边框和右边框) + 60px (左边距和右边距) = 380px!</div>
<h2>box-sizing: border-box:</h2>
<p>高度和宽度应用于元素的所有部分: 内容、内边距和边框:</p>
<div id="example2">不管如何这里的完整宽度为300px!</div>
</body>
</html>
CSS定位
文档流:在网页中将窗口自上而下分成一行行,每一行从左至右排列元素的排列方式即为文档流。
Position:定位
- static 文档流定位,默认的
- absolute 绝对定位,相对父元素绝对定位
- relative 相对定位,相对正常位置进行定位
- fixed 固定定位,相对于浏览器窗口是固定定位(窗口滚动他也不会移动)
- sticky 粘性定位,它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed;,它会固定在目标位置。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
h1.r1{
left: -30px;
}
h1.r2{
left: 30px;
}
</style>
</head>
<body>
<h1>这是正常位置</h1>
<h1 class="r1">相对正常位置左</h1>
<h1 class="r2">相对正常位置右</h1>
</body>
</html>
这个代码有什么问题?设置的left位置将不会生效,因为默认的排列方式是static,如果需要生效必须设置position为absolute/relative
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
h1.r1{
position: relative;
left: -30px;
}
h1.r2{
position: relative;
left: 30px;
}
</style>
</head>
<body>
<h1>这是正常位置</h1>
<h1 class="r1">相对正常位置左</h1>
<h1 class="r2">相对正常位置右</h1>
</body>
</html>
<h1 style="position:absolute">这是正常位置</h1>
<h1 style="position:absolute">相对正常位置左</h1>
<h1 style="position:absolute">相对正常位置右</h1>
这三个元素将会重叠在一行
相对定位不会使元素脱离文档流,绝对定位会使元素脱离文档流。
比如:<div>下面有3个相对定位元素(没有设置位置),他们会按照文档流从上至下,从左至右排列
而如果三个元素是绝对定位,这3个元素会在<div>下重叠在一起
-------------------------------
在进行元素定位时,如果要元素针对父元素定位而不针对body定位,使用“父相子绝”
“父相子绝”是指,如果一个元素的子元素使用了绝对定位,那么这个父元素必须使用相对定位。
这样可以让子元素以其父元素为标准来定位。如果不这么做,子元素就会相对于body或浏览器
定位产生不好的效果 。
sticky
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>sticky粘性布局</title>
<style>
div.sticky {
position: -webkit-sticky;
position: sticky;
top: 0;
padding: 5px;
background-color: #cae8ca;
border: 2px solid #4CAF50;
}
</style>
</head>
<body>
<p>尝试滚动页面。</p>
<p>注意: IE/Edge 15 及更早 IE 版本不支持 sticky 属性。</p>
<div class="sticky">我是粘性定位!</div>
<div style="padding-bottom:2000px">
<p>滚动我</p>
<p>来回滚动我</p>
<p>滚动我</p>
<p>来回滚动我</p>
<p>滚动我</p>
<p>来回滚动我</p>
</div>
</body>
</html>
文本溢出–滚动条
当一段文本超出容器的范围时可以使用overflow控制显示方式。
使用方式 overflow:scroll(x,y方向添加滚动条显示)
还可以其他值 overflow:hidden(超出部分不显示), overflow:auto(自动内容设置是否滚动)
还可以进一步设置x,y方向的滚动,比如overflow-y:auto; overflow-x:auto等
设置不显示滚动条
选择器::-webkit-scrollbar{
display:none;
}
css浮动
CSS浮动是一种布局技术,它可以使元素向左或向右移动,其他元素则会围绕它。这个特性常用于实现文字环绕图像的效果,或者创建整个页面的布局。
使用方式:float:right;(向右浮动)
要多个div按行排列:
<div style="background-color:red">
<div class="f"></div>
<div class="f"></div>
<div class="f"></div>
<div class="f"></div>
</div>
- 浮动
<style>
.f{
float:left
}
</style>
- 设置行内块元素
<style>
.f{
display:inline-block
}
</style>
由于浮动脱离文档流,不占文档空间,所以如果父元素没有设置高度会导致父元素高度为0坍塌,此时就必须设置清除浮动。
清除浮动
- 1.在父级元素最后添加一个元素,设置属性
<div style="clear:both"></div>
- 2.使用 overflow ,将父级元素的 overflow 属性设置为 auto 可以使父级元素自动清除浮动。
- 3.使用伪类选择器after
选择器::after{
content: "";
display: table;
clear: both;
}
渐变
渐变:在两个或多个指定的颜色之间显示平稳的过渡。
菜鸟/渐变工具
background-image:linear-gradient(direction,color1,color2,...)
- 线性渐变:从上到下(默认)
<div style="height:200px;background-image: linear-gradient(#e66465,#9198e5)"></div>
- 线性渐变:从左到右
<div style="height:200px;background-image: linear-gradient(to right,#e66465,#9198e5)"></div>
- 线性渐变:对角,从左上角开始(到右下角)的线性渐变
<div style="height:200px;background-image: linear-gradient(to bottom right,#e66465,#9198e5)"></div>
径向渐变:从圆/椭圆中心向四周渐变
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<style>
#grad1 {
height: 150px;
width: 200px;
background-color: red; /* 浏览器不支持的时候显示 */
background-image: radial-gradient(red, yellow, green); /* 标准的语法(必须放在最后) */
}
#grad2 {
height: 150px;
width: 200px;
background-color: red; /* 浏览器不支持的时候显示 */
background-image: radial-gradient(circle, red, yellow, green); /* 标准的语法(必须放在最后) */
}
</style>
</head>
<body>
<p><strong>椭圆形 Ellipse(默认):</strong></p>
<div id="grad1"></div>
<p><strong>圆形 Circle:</strong></p>
<div id="grad2"></div>
</body>
</html>
阴影
在CSS中,box-shadow是一种常用的属性,用于给元素添加阴影效果。这个属性接收5个参数,分别是:
h-offset:水平偏移量,表示阴影在水平方向上的位置。
v-offset:垂直偏移量,表示阴影在垂直方向上的位置。
blur-radius:模糊半径,控制阴影的模糊程度。
扩展:阴影的扩展大小是指阴影从元素向外延伸的距离。
color:阴影的颜色和透明度。
例如,以下代码将给元素添加一个向右下方偏移2像素、模糊半径为5像素的黑色阴影:
box-shadow: 2px 2px 5px 0px rgba(0, 0, 0, 0.5);
你也可以添加多个阴影,只需要用逗号分隔每个阴影的值即可。例如:
box-shadow: 2px 2px 5px 0px rgba(0, 0, 0, 0.5), -2px -2px 5px 0px rgba(0, 0, 0, 0.2);
这个代码将在元素上添加两个阴影,一个在右侧和下方偏移2像素,另一个在左侧和上方偏移2像素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>阴影</title>
<style>
div.card{
width: 250px;
box-shadow: 4px 6px 8px 0 rgba(0, 0, 0, 0.5);
text-align: center;
}
div.header {
background-color: #4CAF50;
color: white;
padding: 10px;
font-size: 40px;
}
div.container{
padding: 15px;
}
</style>
</head>
<body>
<h2>卡片</h2>
<div class="card">
<div class="header">
<h1>你好</h1>
</div>
<div class="container">
<p>2023年8月1日</p>
</div>
</div>
</body>
</html>
calc函数
calculate计算的缩写,用于在声明css属性值时执行一些计算。
比如需求:要求父盒子永远比子盒子的宽度小80px
width:calc(100%-80px);
括号里进行加减乘除操作
var()函数
在CSS中,var() 是一个函数,用于在属性值中引用一个变量。这是一种使用CSS变量的方式,可以使你的样式表更灵活、可维护,也能更好地保持一致性。
例如,你可以定义一个变量,然后在使用该变量的地方使用 var() 函数:
:root {
--main-color: #06c;
}
p {
color: var(--main-color);
}
在这个例子中,所有的 <p>
元素都将使用 --main-color 变量指定的颜色。如果你想改变这个颜色,你只需要在根元素中改变 --main-color 的值即可。
var() 函数还可以接收一个可选的默认值,以防变量未定义或不支持 var() 函数的情况下使用。例如:
p {
color: var(--main-color, red);
}
在这个例子中,如果 --main-color 未定义,那么<p>
元素将默认使用红色。
动画
优点:
- 增强网页交互体验
- 减少代码量(不需要js代码也可以写动画),让网页运行更快
- 成为一名全栈工程师必备基础
过渡动画
transition: property duration time-function delay;
property:设置过渡效果的css属性的名称(all:针对所有元素,none:默认,确定的元素)
duration:过渡花费的时间(ms/s)
time-function:过渡的速度函数(linear匀速,ease慢快慢,ease-in慢开始,ease-out慢结束)
delay:定义过渡延迟多少时间开始(默认0)
transform变换动画
transform是CSS中的一个重要属性,它可以对元素进行2D或3D转换。这包括旋转、缩放、倾斜和移动等操作。
perspective(xxxpx)用以展示3d立体效果,在父元素中设置
- translate(X,Y) 移动
div{
transform: translate(100px,100px);
}
# 将div向水平、垂直方向各上移动100px
x>0向右平移 y>0向下平移
css div水平垂直居中
常见的方式是将父级元素添加如下样式:
display:flex;
justify-content:center;
align-items:center;
使用transform居中:
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%); #translate() 里面的百分比指的是当前元素的宽高百分比
- rotate旋转(9-360)
transform: rotate(45deg);
rotateY() # 按照Y轴旋转
rotateX(),rotateZ()等
- skew 倾斜
可以用来画平行四边形,菱形(时针)等 - scale() 使元素放大缩小
transform: scale(2); # 是元素放大2倍
perspective
是一个CSS属性,用于指定一个3D视图的透视效果。它通常与"transform"属性一起使用,以创建更复杂的3D变换效果。
设置转换中心点
transform-origin
transform-origin: x-value y-value; (默认是50%和50%中心)
还可以设置x,y方向上的像素大小,以及top left bottom right center等方位
比如:transform-origin: left bottom (以左下角为中心点)
animation动画
通过设置多个节点来精确控制一组复杂的动画效果。
动画可以通过使用@keyframes规则和animation属性来创建。
- 定义动画
@keyframes 动画名{
0% {
background-color:red
}
100% {
background-color:green
}
}
# 0%是动画的开始,100%是动画的结束,(这里可以用from(0%) to(100%))这样的规则称为动画序列
- 使用动画
div {
animation: 动画名 duration(持续时间) timing-function(运动时间曲线,默认ease) delay(延迟开始时间) iteration-count(播放次数,默认1次,infinite无穷次)
}
animation-timing-function属性
用于指定CSS动画的时间函数,决定动画中关键帧之间的过渡效果。下面列举了一些常用的animation-timing-function属性值:
- linear:匀速过渡。
- ease:默认值,具有缓慢开始和结束的过渡效果,中间部分加速。
- steps(n): 将动画分割成等距的步骤,按照指定步长分段显示。
animation-fill-mode属性
,指定CSS3动画停留在指定状态
- none: 默认值,动画结束后会立即返回起始状态。
- forwards: 动画结束后将保持在结束状态。
- backwards: 动画在等待延迟之前将应用第一个关键帧的样式。
- both: 动画将根据指定的关键帧样式在开始和结束时保留。
transform-style: 3D呈现设置
- flat 不开启3D空间
- preserve-3d 子元素开启立体空间
- 代码写给父元素
flex弹性布局
flex弹性布局是一种强大且灵活的布局模型,通过使用使用弹性容器可以轻松创建复杂的布局。
要创建一个弹性布局,首先要将容器元素设置为弹性容器。
display: flex;
弹性容器的两条轴:
主轴: 弹性项目的排列方向,默认是水平
交叉轴:与主轴垂直的轴
以下是一些常见的弹性容器属性:
flex-direction
定义弹性项目的排列方向,有row(默认值,水平方向排列),column(垂直方向排列),row-reverse(水平方向上反向排列),column-reverse(垂直方向上反向排列)flex-wrap
定义当弹性布局在一行中放不下时是否换行。nowrap(默认值,不换行),wrap(换行)justify-content
定义弹性项目在主轴上的对齐方式。flex-start(默认值,左对齐),flex-end(右对齐),center(居中对齐),space-between(两端对齐)align-items
定义弹性项目在交叉轴上的对齐方式。flex-start(上对齐),flex-end(右对齐),center(居中对齐)
设置 flex-direction: row-reverse
弹性项目属性:
- order 用于决定项目排列顺序,数值越小项目排列越靠前(默认是0)
- flex 项目元素所占的比值
div1{
flex: 1;
}
div2{
flex: 2;
}
div3{
flex: 1;
}
# 3个div会将1行分成4份,div1占1份,div2占2份,div3占3份
- align-self
此属性允许单个项目有与其他项目不一样的对齐方式,可覆盖aign-items属性。默认值为auto,表示继承父元素的align-items)属性
css案例
进度条
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.bar{
width: 150px;
height: 15px;
border: 1px solid red;
border-radius: 7px;
padding: 1px;
}
.bar_in{
width: 50%;
height: 100%;
background-color: red;
transition:all 2s linear;
}
.bar:hover .bar_in{
width: 100%;
}
img:nth-of-type(2){
margin-left: -4px;
}
.logo_rotate::-webkit-scrollbar{
display: none;
}
.logo{
transition: all 500ms;
}
.logo:hover{
margin-left: -100px;
}
</style>
</head>
<body>
<div class="bar">
<div class="bar_in"></div>
</div>
<hr>
<div class="logo_rotate" style="width: 100px;overflow-x:hidden ">
<div class="logo" style="width: 204px;height: 100px;">
<img src="s.jpg" alt="" width="100px" height="100px" />
<img src="e.jpg" alt="" width="100px" height="100px" />
</div>
</div>
</body>
</html>
小熊奔跑案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
/* 定义动画关键帧 */
@keyframes bear_run {
0% {background-position: 0 0}
100% {background-position: -1269px 0;}
}
@keyframes move {
0% { left: 0 }
100%{ left: 50%;margin-left: -41px }
}
/* 应用动画 */
div{
position: absolute;
width: 158px;
height: 82px;
background: url(bear.png) no-repeat;
animation: bear_run 1s steps(8) infinite, move 3s forwards;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
两面翻转盒子
- 创建两个盒子,注意旋转的是box
<div class="box">
<div class="front"></div>
<div class="back"></div>
</div>
- 给定宽高,因为两个盒子重叠在一起,所以要进行绝对定位
.box{
position: relative;
width: 300px;
height: 300px;
margin: 100px auto;
}
.front, .back{
position: absolute;
width: 100%;
height: 100%;
}
- 两个盒子都是正面,翻转的时候都是背面,所以应该将其中一个沿y轴旋转形成背靠背的形式
.back{
background-color: pink;
transform: rotateY(180deg);
}
- 旋转box(所有代码)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>两面翻转盒子</title>
<style>
body{
perspective: 460px;
}
.box{
position: relative;
width: 300px;
height: 300px;
margin: 100px auto;
transition: all 0.4s;
transform-style: preserve-3d;
}
.front, .back{
position: absolute;
width: 100%;
height: 100%;
font-size: 30px;
color: #fff;
/* 水平/垂直居中 */
text-align: center;
line-height: 300px;
}
.front{
background-color: purple;
z-index: 1; /* 正面优先显示 */
/* 必须添加 */
backface-visibility: hidden;
}
.back{
background-color: pink;
transform: rotateY(180deg);
}
.box:hover{
transform: rotateY(180deg);
}
</style>
</head>
<body>
<div class="box">
<div class="front">黑马程序员</div>
<div class="back">pink老师在这里等你</div>
</div>
</body>
</html>
注意:父元素必须添加transform-style:perserve-3d显示3d效果;并:backface-visibility: hidden;是CSS的一个属性,它控制当一个元素被旋转或者翻转的时候,其背面对其他元素的可见性。
旋转木马案例
以下图为例,六张图片绕Y旋转。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>旋转木马</title>
<style>
section{
position: relative;
width: 312px;
height: 212px;
margin: 160px auto;
}
section div{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url("dog.jpg") no-repeat;
/* 确保图片完全显示 */
background-size: 100% 100%;
}
</style>
</head>
<body>
<section>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
</body>
</html>
这个时候六张图片通过绝对定位会重叠在一起(如下图红色部分),现在需要将第一张图向z轴正方向平移,以及向其他方向旋转平移(一定是先旋转在移动,如果先移动,在60度等方位时不知道移动的x,y是多少
),注意旋转移动之后,xyz轴会根据元素自身变化,而不是原来的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>旋转木马</title>
<style>
body{
perspective: 900px;
}
section{
position: relative;
width: 312px;
height: 212px;
margin: 160px auto;
transform-style: preserve-3d;
animation: carousel 6s linear infinite;
}
@keyframes carousel {
from{ transform: rotateY(0) }
to{ transform: rotateY(360deg) }
}
section:hover{
/* 鼠标放入动画,动画暂停 */
animation-play-state: paused;
}
section div{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url("dog.jpg") no-repeat;
/* 确保图片完全显示 */
background-size: 100% 100%;
}
section div:nth-child(1){
transform: translateZ(300px);
}
section div:nth-child(2){
/* 先旋转在平移 */
transform: rotateY(60deg) translateZ(300px);
}
section div:nth-child(3){
transform: rotateY(120deg) translateZ(300px);
}
section div:nth-child(4){
transform: rotateY(180deg) translateZ(300px);
}
section div:nth-child(5){
transform: rotateY(240deg) translateZ(300px);
}
section div:nth-child(6){
transform: rotateY(300deg) translateZ(300px);
}
</style>
</head>
<body>
<section>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
</body>
</html>
Canvas
是HTML5的一个新标签,它创建了一个固定大小的画布
,提供了多个上下文(这个上下文可以理解为画笔),我们可以用上下文去绘制或者处理要展示的内容,可以绘制各种图形,包括路径、矩形、圆形、字符以及添加图像等
。这个上下文有2D的和3D的。
它自带了两个属性,height和width,可以通过这两个来控制大小。
可以通过如下代码获取canvas画布容器:
let canvas = document.querySelector('canvas')
let ctx = canvas.getContext('2d') //获取2d的上下文
判断浏览器的支持性:
if (canvas.getContext){
// 正常逻辑
}else{
// 不支持的兼容处理
}
在获取到canvas上下文以后就可以利用上下文来进行绘画,绘画区域如下(x,y轴以像素点为基本单位):
绘画路径
直线
- beginPath():新建一个路径
- moveTo(x,y) : 将笔画移动到(x,y)点
- lineTo(x,y) : 笔画下一点的位置
- stroke() :通过线条描绘图形轮廓
- closePath() : 关闭当前路径,将终点自动连接到起点形成一个闭合的形状
- fill() : 通过填充当前路径的区域来生成实心的图形
- rect(x,y,width,height): 画布上形成一个矩形,该矩形的左上角坐标是(x,y),宽高分别是width和height
- fillRect(x,y,width,height) : 跟rect()一样,不过会自动填充实心区域
- strokeRect(x, y, width, height):是rect()和stroke()的结合
- clearRect(x, y, width, height):清除画布上指定的矩形区域
- rotate() 方法是用于旋转绘图环境的。这个方法接受一个参数,表示旋转的角度,以弧度为单位。旋转的中心点是整个画布的左上角(0,0)。【注意旋转的是轴而不是图】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>canvas基本使用</title>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<script>
// 获取canvas上下文
let canvas = document.querySelector('#canvas')
let ctx = canvas.getContext('2d')
// 创建一个画笔
ctx.beginPath()
// 将画笔移动到(50,50)
ctx.moveTo(50,50)
ctx.lineTo(100,100)
ctx.lineTo(130,50)
// 通过线条描绘图形轮廓
// 关闭当前路径,形成一个封闭的形状
// ctx.closePath()
// ctx.stroke()
ctx.fill()
</script>
</body>
</html>
圆形/圆弧
arc(x, y, r, startAngle, endAngle, anticlockwise)
:在画布上绘制一个圆弧或部分圆。其中,(x,y)是圆心的坐标,r是圆的半径,startAngle和endAngle是圆弧的起始角度和结束角度(以弧度为单位),anticlockwise是一个布尔值,anticlockwise为true,那么圆弧逆时针绘制;false或省略,则顺时针绘制。arcTo(x1, y1, x2, y2, radius)
:根据给定的控制点和半径画一段圆弧,最后再以直线连接两个控制点。ellipse(x,y,radiusX,radiusY,rotation,startAngle,endAngle,anticlockwise)
; x,y椭圆圆心坐标;radiusX水平半径,radiusY垂直半径;rotation旋转度数;startAngle开始度数,endAngle终止度数bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
:绘制一条贝塞尔曲线(非标准圆弧)。cp1x和cp1y是第一个贝塞尔控制点的坐标,cp2x和cp2y是第二个贝塞尔控制点的坐标,x和y是曲线的结束坐标(起点坐标已经通过moveTo()方法设置好了)
//直接画一个圆形
ctx.arc(100,100,50,0,360) // 或者 ctx.arc(100,100,50,0,2*Math.PI)
ctx.fill() // 填充圆形为实心
ctx.stroke()
// 半圆
ctx.arc(100,100,50,0,180) // 0-180deg 即就是半圆
// 注意圆弧也是可以接lineTo() 直线的
//椭圆
ctx.ellipse(300,200,200,100,0,0,2*Math.PI)
ctx.stroke()
绘制贝塞尔图的地址:http://wx.karlew.com/canvas/bezier/
利用贝塞尔曲线画一个爱心图形:
// 获取canvas上下文
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d")
ctx.strokeStyle = "#1572b5";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(161, 195);
ctx.bezierCurveTo(188, 116, 400, 100, 160, 358);
ctx.moveTo(161, 195);
ctx.bezierCurveTo(92, 70, -10, 169, 160, 358);
ctx.stroke();
ctx.closePath();
canvas设置样式
- 设置线条样式
ctx.lineWidth = 10 // 设置线条宽度
ctx.lineCap = 'butt' // 设置线条端点样式(butt(平接) round(圆点) square(正方形))
- 设置颜色
ctx.fillStyle = 'red' // 设置图形的填充颜色
ctx.strokeStyle = 'blue' // 设置图形轮廓的颜色
- 添加文字
ctx.fillText(text,x,y[,maxWidth])
ctx.strokeText(text,x,y[,maxWidth])
maxWidth 设置文字的最大宽度,如果文字超过这个宽度则会被压缩
- 文字样式
ctx.font = 1 //设置文字大小
ctx.textAlign = [Left,right,center,start,end] //设置文字对齐方式
- 添加图片
// 创建一个Image对象
let img = new Image()
//设置图片给的地址
img.src = 'a.jpg'
//绘制图片
ctx.drawImage(img,x,y,width,height)
//如果静态资源没有及时加载可以通过onload()函数
img.onload = function(){
ctx.drawImage(img,0,0)
}
img.src='a.jpg'
- save() 对当前样式状态存档, restore() 恢复之前的状态
使用canvas创建一个画布功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>canvas基本使用</title>
<style>
canvas{
border-radius: 4px;
box-shadow: 10px 10px 15px 0 rgba(0,0,0,.2);
}
</style>
</head>
<body>
<div>
<button class="button" id="clear" onclick="clearCanvas()">画板重置</button>
<button class="button" id="save" onclick="save()">保存</button>
</div>
<br>
<canvas id="canvas" width="500" height="500"></canvas>
<script>
let painting = false //设置鼠标的按下与否状态
let startPoint = {x:undefined,y:undefined}
// 获取canvas上下文
let canvas = document.getElementById('canvas')
let ctx = canvas.getContext('2d')
// 设置鼠标移动的监听事件
canvas.onmousedown = (e) => { //按下鼠标:表示要进行画了
startPoint = { //鼠标移动的最新位置
x:e.offsetX,y:e.offsetY
}
painting = true
}
// 将新位置和老位置相连
canvas.onmousemove = (e) =>{ //在鼠标还未释放时,如果移动就进行画画
let newPoint = {
x:e.offsetX,y:e.offsetY
}
if (painting){
drawLine(startPoint.x,startPoint.y,newPoint.x,newPoint.y)
startPoint = newPoint
}
}
canvas.onmouseup = ()=>{ //如果鼠标释放就不画
painting = false
}
function drawLine(xstart,ystart,xend,yend){
ctx.beginPath()
ctx.lineWidth = 3
ctx.moveTo(xstart,ystart)
ctx.lineTo(xend,yend)
ctx.stroke()
ctx.closePath()
}
function clearCanvas(){
ctx.clearRect(0,0,canvas.offsetWidth,canvas.offsetWidth)
}
function save(){
let url = canvas.toDataURL('img/jpg')
let a = document.createElement("a")
a.href = url
a.download = '画板'
a.target = '_blank'
a.click()
}
</script>
</body>
</html>
使用canvas创建时钟表
- requestAnimationFrame()是一个函数,它告诉浏览器你希望执行一个动画,并请求浏览器在下次重绘之前调用指定的函数来更新动画。这个函数的主要目的是优化动画的性能。
以下是requestAnimationFrame的一些重要特点:
- 同步渲染:requestAnimationFrame()将确保你的动画与浏览器的六帧渲染速率同步。这意味着,如果你在1秒内对屏幕进行多次绘制,你的动画将平滑且一致。
- 节省CPU:使用requestAnimationFrame()可以更高效地使用CPU,因为浏览器会在屏幕刷新的瞬间执行你的动画函数,这意味着你的代码将在屏幕刷新的前后得到执行,而不是在浏览器的空闲时间。
使用方法:
function animate() {
// 在这里执行动画代码
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表</title>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
<script>
//开始动画循环
window.requestAnimationFrame(animate)
function animate(time){
// 获取当前时间
let date = new Date()
let hours = date.getHours()
hours = hours>=12? hours-12:hours
let minutes = date.getMinutes()
let seconds = date.getSeconds()
let canvas = document.getElementById("canvas")
let ctx = canvas.getContext('2d')
ctx.save()
ctx.clearRect(0,0,600,600)
ctx.beginPath()
ctx.lineCap = 'round'
ctx.translate(300,300) //移动表的中心
ctx.strokeStyle="black"
ctx.lineWidth=3
ctx.rotate(-Math.PI/2)
ctx.save()
for (let i=0;i<12;i++){
ctx.beginPath()
ctx.moveTo(100,0)
ctx.lineTo(120,0)
ctx.rotate(Math.PI/6)
ctx.stroke()
}
ctx.restore()
ctx.save()
ctx.lineWidth = 2
ctx.strokeStyle = 'green'
for (let i=0;i<60;i++){
ctx.beginPath()
ctx.moveTo(110,0)
ctx.lineTo(120,0)
ctx.rotate(Math.PI/30)
ctx.stroke()
}
ctx.restore()
// 画时针
ctx.save()
ctx.lineWidth=10
ctx.lineCap='round'
ctx.rotate(hours*(Math.PI/6) + minutes*(Math.PI/360) + seconds*(Math.PI/21600))
ctx.beginPath()
ctx.moveTo(-20,0)
ctx.lineTo(70,0)
ctx.stroke()
ctx.restore()
// 画分针
ctx.save()
ctx.lineWidth=7
ctx.lineCap='round'
ctx.rotate(minutes*(Math.PI/30) + seconds*(Math.PI/1800))
ctx.beginPath()
ctx.moveTo(-20,0)
ctx.lineTo(80,0)
ctx.stroke()
ctx.restore()
// 画秒针
ctx.save()
ctx.rotate(Math.PI/30*seconds)
ctx.lineWidth=4
ctx.beginPath()
ctx.moveTo(-22,0)
ctx.lineTo(90,0)
ctx.arc(0,0,6,0,2*Math.PI,true)
ctx.strokeStyle='red'
ctx.lineCap='round'
ctx.fillStyle='red'
ctx.fill()
ctx.stroke()
ctx.restore()
ctx.restore()
//循环调用
window.requestAnimationFrame(animate)
}
</script>
</body>
</html>