纯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-width
、min-width
、max-height
、min-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包裹性的主要内容,如果未能解决你的问题,请参考以下文章
vue.draggable拖拽组件中用transition-group包裹拖拽组件了,拖拽还是没有动画?