纯CSS实现拖拽--resizescale包裹性

Posted 奋飛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了纯CSS实现拖拽--resizescale包裹性相关的知识,希望对你有一定的参考价值。

Thinking系列,旨在利用10分钟的时间传达一种可落地的编程思想或解决方案。

今天看了一篇关于 CSS 的文章,文章用到的几个点,想和大家聊聊。 附「原文地址」大家可自己查阅。

原文题目:CSS 奇思妙想 | 使用 resize 实现强大的图片拖拽切换预览功能
原文地址:https://www.cnblogs.com/coco1s/p/15151338.html
示例源码:https://codepen.io/Chokcoco/pen/bGqWJZL

<div class='picA'>
    <div class='picB'>
        <div readonly class='resizeElement'></div>
    </div>
</div>

该示例,通过纯 css 实现了图片拖拽切换功能,没有涉及任何的 javascript 代码,着实有些“奇思妙想”。

resize

提到的第一个点,一定是 resize 属性,这个属性在平时开发中很少用到。其可由用户调整元素的尺寸大小。配合容器的 max-widthmin-widthmax-heightmin-height 限制可拖拽改变的范围。

属性值说明
none不可以缩放
both水平和垂直方向上均可调整元素的大小
horizontal在水平方向上调整元素的大小
vertical在垂直方向上调整元素的大小

注意: 块元素 overflow 属性不能设置为 visible。

overflow 指定除 visible (默认值)以外的值(hidden/scroll/auto)将创建一个新的 块级格式化上下文(BFC)。这在技术层面上是必须的——如果一个浮动元素和滚动条相交,它会在每个滚动步骤后强行重新包装内容,从而导致慢滚动体验。

.resizable 
  resize: both;
  overflow: scroll;

<div class="resizable"></div>
<textarea class="resizable"></textarea>

开头示例中用到的地方:

.resizeElement 
  resize: horizontal;
  overflow: scroll;
  /* 控制可拖拽的范围 */
  min-width: 15px;
  max-width: 650px;  

scale


对相关元素设置 resize 后,会在元素右下角添加操作柄,但整体操作区域比较小,非常不方便。像上述示例gif图中所展示,需要增大整个展示区域该如何操作?

.resizeElement 
  position: relative;
  top: 50%;
  left: 0;
  height: 15px;


元素居于 picB 的中间位置,高度15(操作柄在右侧),通过 scaleY() 来放大操作区域

scaleY() 函数定义了一个沿 y 轴(垂直)调整元素大小的变换。

.resizeElement 
  opacity: 0;
	transform: scaleY(25);
  transform-origin: center center;

通过上述操作,操作区域变成整个区域的右侧。

显示拖拽条

由于完全隐藏了滚动条,用户也就不知道可以拖拽了,所以我们还需要绘制一个更为好看的拖拽条。通过伪元素实现:

.picB:before 
    content: "↔";
    position: absolute;
    background: rgba(0, 0, 0, 0.5);
    font-size: 16px;
    color: white;
    top: 0;
    right: 0;
    height: 100%;
    line-height: 340px;

操作区域的的透明度为0,实际还是操作的 resizeElement

收缩与包裹

width 默认值为 auto,其有4种不同的表现:

  • 充分利用空间:<div> 的宽度默认是100%于父级容器的;
  • 收缩与包裹:浮动、绝对定位(absolute、fixed)、inline-block 元素或 table 元素;
  • 收缩到最小:table-layout 为 auto 的表格中。中文是随便断的,英文单词不能断;
  • 超出容器限制:内容很长的连续英文和数字,或者元素被设置了white-space: nowrap

格式化宽度: 绝对定位(absolute、fixed)的元素,默认情况下宽度表现是“包裹性”,宽度由内部尺寸决定。当 left/right、top/bottom 对立方位的属性同时存在时,宽度表现是“格式化宽度”,宽度大小相对于最近的具有定位特性(非static)的祖先元素计算。格式化宽度具有完全的流体性。

包裹性: 元素尺寸由内部元素决定,但永远小于“包含块”容器的尺寸。inline-block元素、浮动元素以及绝对定位元素都具有包裹性!

示例:文字少居中显示;文字超过一行居左展示。

<style>
  .box 
    width: 300px;
    height: 100px;
    border: 1px solid red;
    text-align: center;
  
  .content 
    display: inline-block;
    text-align: left;
  
</style>
<div class="box">
	<div class="content">纸上得来终觉浅,绝知此事要躬行</div>
</div>

.boxtext-align: center; 决定了 $('.content')的水平对齐方式为居中对齐;
.contenttext-align: left;决定了文字的水平对齐方式为居左。

利用 inline-block 的包裹特性即可实现:内容少,宽度自适应(文字left–撑满元素,元素center);超过一行,$('.content') 的宽度为父容器宽度300px(文字left,元素center–撑满父元素)。

开头示例中用到的地方:

.picB 
  position: absolute;

这里充分利用了包裹性,子元素 $('.resizeElement') 的变化会影响父元素 $('.picB') 的改变。从而实现操作子元素来实现父元素的切换。

以上是关于纯CSS实现拖拽--resizescale包裹性的主要内容,如果未能解决你的问题,请参考以下文章

纯 CSS 也能实现拖拽效果?

纯 CSS 也能实现拖拽效果?(学到了!)

vue.draggable拖拽组件中用transition-group包裹拖拽组件了,拖拽还是没有动画?

CSS 奇思妙想 | 使用 resize 实现强大的图片拖拽切换预览功能

纯js实现DIV拖拽

原生拖拽太拉跨了,纯JS自己手写一个拖拽效果,纵享丝滑