前言
我们实现一个拖拽留言板卡片,通常会使用js的方式去实现拖拽。这一次我们用纯CSS方式去实现,会带给你另一个思路,让你眼前一亮。
1. 基础知识
在说实现思路之前,我们先认识下一个css属性resize,用于设置元素是否可调整尺寸,以及可调整的方向。需要与overflow属性搭配使用。
resize 不适用于下列元素:
- 内联元素
overflow属性设置为visible的块元素
具体使用代码如下:
<style>
div {
position: relative;
width: 100px;
height: 100px;
/* border: 5px solid deeppink; */
/* 必须配合使用才能变化大小 */
resize: both;
/* 不可以是visible */
overflow: auto;
}
</style>
<div></div>
效果如下:
通过上述代码可以点击右下角拖动,可以变化大小。我们接下来可以通过这个属性就可以一步一步实现纯CSS拖动。
2. 实现思路
说实现思路之前,我们可以通过一张图就可以看出来实现,看下图所示:
通过基础知识我们可以知道,元素设置了resize即可进行拖拽大小,在此基础上,我们将留言板定位到resize元素的右下角,这样resize元素变化大小会将留言板的定位改变,就巧妙实现了拖拽的效果。
整体实现流程是:
- 利用resize属性进行拖动:
- 通过
resize: both使元素可调整大小 - 配合
overflow: hidden(不能是visible)使resize生效
- 定位技巧:
- 主容器设为
position: absolute作为定位基准 - 可调整元素(.resize)设为
position: relative - 内容区域(.content)通过
position: absolute和负值偏移定位到右下角
- 联动效果:
- 当拖动.resize元素改变大小时
- 由于.content的位置是相对于主容器的负值定位
- 自然实现了内容区域随拖动而移动的效果
3. 具体实现
通过上面思路的讲解,我们直接写一下具体的代码。具体步骤是:
3.1 创建基本的HTML
<div class="main">
<div class="resize"></div>
<div class="content" contenteditable="true">hello guys, drag me</div>
</div>
基本结构是:
resize:可调整大小的蓝色方块content:黄色内容区域,设置contenteditable="true"即可编辑
3.2 css实现逻辑
- 主容器设置为
position为absolute.
.main {
position: absolute;
display: inline-block;
}
- 可调整元素(resize)的样式
设置初始宽高为200px,启用调整大小功能(resize: both)配合(overflow: hidden)生效,相对定位并设置z-index。
.resize {
content: '';
width: 200px;
height: 200px;
border: 50%;
resize: both;
overflow: hidden;
position: relative;
background-color: lightblue;
z-index: 1;
}
.resize::-webkit-resizer {
background-color: transparent;
}
- 内容区域(content)的样式
设置固定宽高(400x500px),黄色背景,设置绝对定位,相对于主容器向右下方偏移,设置为right: -380px;bottom: -480px;,需要减去左上角拖动的大小。可编辑属性设置为(contenteditable="true"),则可以进行编辑。
.content {
box-sizing: border-box;
width: 400px;
height: 500px;
background-color: yellow;
padding: 30px;
font-size: 24px;
position: absolute;
right: -380px;
bottom: -480px;
&::before {
content: "";
width: 20px;
height: 20px;
border-radius: 50%;
background-color: red;
position: absolute;
top: 0;
left: 0;
}
}
效果如下:
将背景色去除:
4. 完整代码
完整代码如下:
<!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>
.main {
position: absolute;
display: inline-block;
}
.resize {
cursor: pointer;
content: '';
width: 200px;
height: 200px;
border: 50%;
resize: both;
overflow: hidden;
position: relative;
/* background-color: lightblue; */
z-index: 1;
}
.resize::-webkit-resizer {
background-color: transparent;
}
.content {
box-sizing: border-box;
width: 400px;
height: 500px;
background-color: yellow;
padding: 30px;
font-size: 24px;
position: absolute;
right: -380px;
bottom: -480px;
&::before {
content: "";
width: 20px;
height: 20px;
border-radius: 50%;
background-color: red;
position: absolute;
top: 0;
left: 0;
}
}
</style>
</head>
<body>
<div class="main">
<div class="resize"></div>
<div class="content" contenteditable="true">hello guys, drag me</div>
</div>
</body>
</html>
5. 总结
最后总结一下:这种实现方式展示了CSS的另一面,通过CSS的resize属性巧妙地组合现有属性,可以实现通常需要JavaScript才能完成的功能。
仅仅提供一种思路,实际应用谨慎使用,如有错误,请指正O^O!