巧妙实现,用CSS实现的拖拽留言板卡片功能

561 阅读3分钟

前言

我们实现一个拖拽留言板卡片,通常会使用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>

效果如下:

image.png

通过上述代码可以点击右下角拖动,可以变化大小。我们接下来可以通过这个属性就可以一步一步实现纯CSS拖动。

2. 实现思路

说实现思路之前,我们可以通过一张图就可以看出来实现,看下图所示:

image.png

通过基础知识我们可以知道,元素设置了resize即可进行拖拽大小,在此基础上,我们将留言板定位到resize元素的右下角,这样resize元素变化大小会将留言板的定位改变,就巧妙实现了拖拽的效果。

整体实现流程是:

  1. ​利用resize属性进行拖动​​:
  • 通过resize: both使元素可调整大小
  • 配合overflow: hidden(不能是visible)使resize生效
  1. ​定位技巧​​:
  • 主容器设为position: absolute作为定位基准
  • 可调整元素(.resize)设为position: relative
  • 内容区域(.content)通过position: absolute和负值偏移定位到右下角
  1. ​联动效果​​:
  • 当拖动.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实现逻辑

  1. 主容器设置为positionabsolute.
.main {
    position: absolute;
    display: inline-block;
}

  1. 可调整元素(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;
}

  1. 内容区域(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;
    }
}

效果如下:

image.png

将背景色去除:

image.png

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!