>  기사  >  웹 프론트엔드  >  순수 CSS를 영리하게 사용하여 마우스 클릭 및 드래그 효과를 구현하여 상호 작용을 더욱 생생하게 만듭니다!

순수 CSS를 영리하게 사용하여 마우스 클릭 및 드래그 효과를 구현하여 상호 작용을 더욱 생생하게 만듭니다!

青灯夜游
青灯夜游앞으로
2022-11-08 20:08:123243검색

이 기사에서는 순수한 CSS를 사용하여 마우스 클릭 및 드래그 효과를 구현하여 상호 작용을 더욱 생생하게 만드는 방법을 소개합니다. 모든 사람에게 도움이 되기를 바랍니다.

순수 CSS를 영리하게 사용하여 마우스 클릭 및 드래그 효과를 구현하여 상호 작용을 더욱 생생하게 만듭니다!

Background

요소를 이동하려면 마우스를 드래그하세요. 이는 약간 복잡한 상호작용입니다.

이 기사에서는 규칙을 깨고 순수한 CSS를 사용하여 얻을 수 있는 매우 강력한 마우스 클릭 및 드래그 효과를 소개합니다. [추천 학습: css 비디오 튜토리얼]

이전 기사 - 믿을 수 없는 순수 CSS 마우스 팔로우에서 우리는 다음과 같이 많은 흥미로운 순수 CSS 마우스 팔로우 효과를 소개했습니다.

그러나 보시다시피 위의 효과에서는 요소의 움직임이 그다지 부드럽지 않습니다. 위의 구현을 이해한다면 비교적 큰 한계가 있다는 것을 알게 될 것입니다.

이 기사에서는 여전히 CSS만 사용하여 매끄럽고 부드러운 마우스 클릭 및 드래그 요소 이동 효과를 구현합니다.

효과를 따라가려면 마우스를 클릭하고 드래그하세요

알겠습니다. 무슨 뜻인가요? 먼저 요소를 클릭하고 요소를 끌어서 이동할 수 있는 효과를 얻기 위한 가장 간단한 회로도를 살펴보겠습니다.

자, 계속 읽기 전에 여기서 잠시 멈춰도 됩니다. 일반적으로 이 효과는 JavaScript의 도움을 받아 달성되어야 합니다. 성능 관점에서:

  • 먼저 요소를 드래그하면 요소를 임의로 이동할 수 있습니다

  • 그런 다음 요소를 배치하고 다른 위치에 그대로 두세요

생각해 보세요. 그렇지 않으면 JavaScript를 사용하면 요소 공을 A 지점에서 B 지점으로 이동할 수 있는 방법이 있나요? 이 효과는 순수 CSS가 얻을 수 있는 효과와 완전히 다릅니다.

대답은 '예'여야 합니다! 전체 프로세스도 매우 영리합니다. 여기서는 강력한 resize 속성을 ​​사용해야 합니다. 그리고 독창적인 레이아웃을 구축함으로써 발생할 수 있는 다양한 문제를 해결할 수 있습니다. resize 属性。以及,配合通过构建一种巧妙的布局,去解决可能会遇到的各种难题。

使用 resize,构建可拖拽改变大小的元素

首先,我们利用 resize 属性来实现一个可改变大小的元素。

什么是 resize 呢?根据 MDN -- resize:该 CSS 属性允许你控制一个元素的可调整大小性。

其 CSS 语法如下所示:

{
/* Keyword values */
  resize: none;
  resize: both;
  resize: horizontal;
  resize: vertical;
  resize: block;
  resize: inline;
}

简单解释一下:

  • resize: none:元素不能被用户缩放
  • resize: both:允许用户在水平和垂直方向上调整元素的大小
  • resize: horizontal:允许用户在水平方向上调整元素的大小
  • resize: vertical:允许用户在垂直方向上调整元素的大小
  • resize: block:根据书写模式(writing-mode)和方向值(direction),元素显示允许用户在块方向上(block)水平或垂直调整元素大小的机制。
  • resize: inline:根据书写模式(writing-mode)和方向值(direction),元素显示一种机制,允许用户在内联方向上(inline)水平方向或垂直方向调整元素的大小。

看一个最简单的 DEMO:

<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. A aut qui labore rerum placeat similique hic consequatur tempore doloribus aliquid alias, nobis voluptates. Perferendis, voluptate placeat esse soluta deleniti id!</p>
p {
    width: 200px;
    height: 200px;
    resize: horizontal;
    overflow: scroll;
}

这里,我们设置了一个长宽为 200px<p></p>

resize를 사용하여 드래그하여 크기를 변경할 수 있는 요소를 만듭니다

먼저 크기 조정을 사용합니다. code> 속성을 ​​사용하여 크기 조정 가능한 A 요소를 구현합니다. <p></p> 크기 조정이란 무엇인가요? MDN -- resize🎜에 따르면: 이 CSS 속성을 사용하면 크기 조정을 제어할 수 있습니다. 요소의 크기 조정. 🎜🎜CSS 구문은 다음과 같습니다: 🎜
<div></div>
🎜간단한 설명: 🎜
    🎜resize: none: 요소는 사용자가 크기를 조정할 수 없습니다🎜🎜resize: 둘 다 code>: 사용자가 요소의 크기를 가로 및 세로로 조정할 수 있도록 허용🎜🎜resize: 가로: 사용자가 요소의 크기를 가로로 조정할 수 있도록 허용🎜🎜resize: 세로: 사용자가 세로로 요소의 크기를 조정할 수 있음 방향🎜🎜resize: block: 쓰기 모드(writing-mode)와 방향 값(direction)에 따라 요소 표시를 통해 사용자는 블록 방향(block)에서 가로 또는 세로로 크기를 조정할 수 있습니다. 요소의 크기를 조정하는 메커니즘입니다. 🎜🎜resize: inline: 쓰기 모드(writing-mode)와 방향 값(direction)에 따라 요소는 사용자가 인라인 방향( 인라인) 요소의 크기입니다. 🎜🎜🎜가장 간단한 데모를 보세요: 🎜
.g-resize {
    width: 100px;
    height: 100px;
    border: 1px solid deeppink;
}
.g-resize {
    width: 100px;
    height: 100px;
    border: 1px solid deeppink;
    resize: both;
    overflow: scroll;
}
🎜여기서 가로로 드래그할 수 있도록 길이와 너비가 200px<p></p>를 설정했습니다. 너비를 변경하십시오. 효과는 다음과 같습니다: 🎜🎜🎜🎜🎜몇 가지 팁에 대한 간략한 요약: 🎜
  • resize 的生效,需要配合 overflow: scroll,当然,准确的说法是,overflow 不是 visible,或者可以直接作用于替换元素譬如图像、<video></video><iframe></iframe><textarea></textarea>
  • 我们可以通过 resizehorizontalverticalboth 来设置横向拖动、纵向拖动、横向纵向皆可拖动。
  • 可以配合容器的 max-widthmin-widthmax-heightmin-height 限制可拖拽改变的一个范围

这里,如果你的对 resize 还有所疑惑,或者想了解更多 resize 的有趣用法,可以看看我的这篇文章:CSS 奇思妙想 | 使用 resize 实现强大的图片拖拽切换预览功能

将 resize 应用到本文实例中

OK,接下来,我们将 resize 实际运用到我们本文的例子中去,首先,我们先简单实现一个 DIV:

<div></div>
.g-resize {
    width: 100px;
    height: 100px;
    border: 1px solid deeppink;
}

如下,非常普通,没有什么特别的:

但是,通过给这个元素加上 resize: both 以及 overflow: scroll,此时,这个元素的大小就通过元素右下角的 ICON 进行拖动改变。

简单修改下我们的 CSS 代码:

.g-resize {
    width: 100px;
    height: 100px;
    border: 1px solid deeppink;
    resize: both;
    overflow: scroll;
}

这样,我们就得到了一个灵活可以拖动的元素:

是的,我们的整个效果,就需要借助这个特性进行实现。

在此基础上,我们可以尝试将一个元素定位到上面这个可拖动放大缩小的元素的右下角,看着能不能实现上述的效果。

简单加一点代码:

<div></div>
.g-resize {
    position: relative;
    width: 20px;
    height: 20px;
    resize: both;
    overflow: scroll;
}
.g-resize::before {
    content: "";
    position: absolute;
    bottom: 0;
    right: 0;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: deeppink;
}

我们利用元素的伪元素实现了一个小球,放置在容器的右下角看看效果:

如果我们再把整个设置了 resize: both 的边框隐藏呢?那么效果就会是这样:

Wow,整个效果已经非常的接近了!只是,认真看的话,能够看到一些瑕疵,就是还是能够看到设置了 resize 的元素的这个 ICON:

这个也好解决,在 Chrome 中,我们可以通过另外一个伪元素 ::-webkit-resizer ,设置这个 ICON 的隐藏。

根据 MDN - ::-webkit-resizer,它属于整体的滚动条伪类样式家族中的一员。

其中 ::-webkit-resizer 可以控制出现在某些元素底角的可拖动调整大小的滑块的样式。

所以,这里我就利用这个伪类:

.g-resize {
    position: relative;
    width: 20px;
    height: 20px;
    resize: both;
    overflow: scroll;
}
.g-resize::before {
    content: "";
    position: absolute;
    bottom: 0;
    right: 0;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: deeppink;
}
.g-resize::-webkit-resizer {
    background-color: transparent;
}

这样,这里的核心在于利用了 .g-resize::-webkit-resizer 中的 background-color: transparent,将滑块的颜色设置为了透明色。我们就得到了与文章一开始,一模一样的效果:

解决溢出被裁剪问题

当然,这里有个很致命的问题,如果需要移动的内容,远比设置了 resize 的容器要大,或者其初始位置不在该容器内,超出了的部分因为设置了 overflow: scroll,将无法看到。

因此上述方案存在比较大的缺陷。

举个例子,假设我们需要被拖动的元素不再是一个有这样一个简单的结构:

<div></div>
.g-content {
    width: 100px;
    height: 100px;
    background: black;
    pointer-event: none;
    
    &::before {
        content: "";
        position: absolute;
        width: 20px;
        height: 20px;
        background: yellow;
        border-radius: 50%;    
}

而像是这样,是一个更为复杂的布局内容展示(当然下面展示的也比较简单,实际中可以想象成任意复杂结构内容):

如果将这个结构,扔到上面的 g-resize 中:

    <div></div>

那么就会因为设置了 overflow: scroll 的原因,将完全看不到,只剩下一小块:

为了解决这个问题,我们得修改原本的 DOM 结构,另辟蹊径。

方法有很多,譬如可以利用 Grid  布局的一些特性。当然,这里我们只需要巧妙的加多一层,就可以完全解决这个问题。

我们来实现这样一个布局:

    <div></div>     <div></div>

解释一下上述代码,其中:

  • g-container 设置为绝对定位加上 display: inline-block,这样其盒子大小就可以由内部正常流式布局盒子的大小撑开

  • g-resize 设置为 position: relative 并且设置 resize,负责提供一个可拖动大小元素,在这个元素的变化过程中,就能动态改变父容器的高宽

  • g-content 实际内容盒子,通过 position: absolute 定位到容器的右下角即可

看看完整的 CSS 代码:

.g-container {
    position: absolute;
    display: inline-block;
}
.g-resize { 
    content: "";
    position: relative;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    resize: both;
    overflow: scroll;
    z-index: 1;
}
.g-content {
    position: absolute;
    bottom: -80px;
    right: -80px;
    width: 100px;
    height: 100px;
    background: black;
    pointer-event: none;
    
    &::before {
        content: "";
        position: absolute;
        width: 20px;
        height: 20px;
        background: yellow;
        border-radius: 50%;
        transition: .3s;
    }
}
.g-container:hover .g-content::before {
    transform: scale(1.1);
    box-shadow: -2px 2px 4px -4px #333, -4px 4px 8px -4px #333;
}
.g-resize::-webkit-resizer {
    background-color: transparent;
}

下图中,你看到的所有元素,都只是 g-content 呈现出来的元素,整个效果就是这样:

是的,可能你会有所疑惑,下面我用简单不同颜色,标识不同不同的 DOM 结构,方便你去理解。

  • 红色边框表示整个 g-container 的大小

  • 用蓝色矩形表示设置了 g-resize 元素的大小

  • 关掉 ::-webkit-resizer 的透明设置,展示出 resize 框的可拖拽 ICON

.g-container {
    border: 3px solid red;
}
.g-resize { 
    content: "";
    background: blue;
    resize: both;
    overflow: scroll;
}
.g-resize::-webkit-resizer {
    // background-color: transparent;
}

看看这个图,整个原理基本就比较清晰的浮现了出来:

完整的原理代码,你可以戳这里:CodePen Demo -- Pure CSS Auto Drag Demo

实际应用

OK,用了比较大篇幅对原理进行了描述。下面我们举一个实际的应用场景。使用上述技巧制作的可拖动便签贴。灵感来自 -- scottkellum

代码也不多,如果你了解了上面的内容,下面的代码将非常好理解:

    <div></div>     
 Lorem ipsum dolor sit amet consectetur?

完整的 CSS 代码如下:

body {
    position: relative;
    padding: 10px;
    background: url("背景图");
    background-size: cover;
}
.g-container {
    position: absolute;
    display: inline-block;
}
.g-resize {
    content: "";
    position: relative;
    width: 20px;
    height: 20px;
    resize: both;
    overflow: scroll;
    z-index: 1;
}
.g-content {
    position: absolute;
    bottom: -160px;
    right: -180px;
    color: rgba(#000, 0.8);
    background-image: linear-gradient(
        160deg,
        rgb(255, 222, 30) 50%,
        rgb(255, 250, 80)
    );
    width: 200px;
    height: 180px;
    pointer-event: none;
    text-align: center;
    font-family: "marker felt", "comic sans ms", sans-serif;
    font-size: 24px;
    line-height: 1.3;
    padding: 1em;
    box-sizing: border-box;
    &:before {
        content: "";
        position: absolute;
        width: 20px;
        height: 20px;
        top: 0;
        left: 0;
        border-radius: 50%;
        background-image: radial-gradient(
            at 60% 30%,
            #f99,
            red 20%,
            rgb(180, 8, 0)
        );
        background-position: 20% 10%;
        cursor: pointer;
        pointer-events: none;
        transform: scale(0.8);
        box-shadow: -5px 10px 3px -8.5px #000, -1px 7px 12px -5px #000;
        transition: all 0.3s ease;
        transform: scale(0.8);
    }
}
.g-container:hover .g-content::before {
    transform: scale(0.9);
    box-shadow: -5px 10px 6px -8.5px #000, -1px 7px 16px -4px #000;
}
.g-resize::-webkit-resizer {
    background-color: transparent;
}

我们通过上述的技巧,实现了一个仅仅使用 CSS 实现的自由拖拽的便签贴。我们可以自由的将其拖拽到任意地方。看看效果:

순수 CSS를 영리하게 사용하여 마우스 클릭 및 드래그 효과를 구현하여 상호 작용을 더욱 생생하게 만듭니다!

当然,我们可以再配合上另外一个有意思是 HTML 属性 -- contenteditable

contenteditable 是一个 HTML TAG 的属性,表示元素是否可被用户编辑。如果可以,浏览器会修改元素的部件以允许编辑。

简单修改一下 DOM 结构:

    <div></div>     
 Lorem ipsum dolor sit amet consectetur?

此时,元素不仅可以被拖动,甚至可以被重写,感受一下:

纯 CSS 实现的效果,非常的有意思,完整的代码,你可以戳这里:Pure CSS Auto Drag Demo

最后

基于 resize 这个 CSS 属性,其实还有很多有意思的用法。譬如我之前使用了 Resize 实现了一个图片切换预览的功能:CSS 奇思妙想 | 使用 resize 实现强大的图片拖拽切换预览功能 可以一并看看,相信能碰撞出更多火花。

原文地址:https://www.cnblogs.com/coco1s/p/16774696.html

作者:ChokCoco

(学习视频分享:web前端

위 내용은 순수 CSS를 영리하게 사용하여 마우스 클릭 및 드래그 효과를 구현하여 상호 작용을 더욱 생생하게 만듭니다!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제