Shapes布局-文字环绕动画

简介: Shapes布局-文字环绕动画

说明

Shapes也有形状、图形的意思,我们可以在页面中创建图形,并让内容环绕在定义的图形边上。

Shapes的官方文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Shapes/From_box_values

我们经常在一些宣传手册上看到文字环绕图形的海报效果,这种海报效果通过css也可以实现,shapes布局可以实现不规则的图文环绕效果。

注意:它需要和float属性配合使用。


实现以及语法

我们先来实现一个文字环绕图形的效果:

<div class="container">
        <div class="shape"></div>
        <p>
        这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字
        </p>
    </div>
.container{
   width: 400px;
   height: 200px;
   border: 1px solid red;
   .shape{
    width: 100px;
    height: 100px;
    border: 1px solid gold;
    background: #ccc;
    float: left;  /* shape必须配合float */
    shape-outside: border-box; /* 围绕box边框环绕 */
   }
}

上图就是一个基本的文字环绕效果,float是必需的,它定义了元素浮动的位置,shape-outside: border-box;表示内容以盒子的边框为基准环绕。

这里是左浮动,所以盒子定位在左边,文字围绕左边的盒子排列。如果float:right;那么文字会围绕右边的盒子环绕。

上面的shape-outside: border-box;是其中一个环绕模式,shape-outside有多种环绕模式,如下:

属性 说明
shape-box 根据浮动元素的边缘(通过 CSS box model 来定义)形状计算出浮动的区域。
margin-box 以浮动元素的外边距边界进行围绕
border-box 以浮动元素的边框为基准环绕
padding-box 从浮动元素的padding位置开始环绕
content-box 从浮动元素的content位置开始环绕

margin-box

margin: 10px;
shape-outside: margin-box; /* 以margin的范围开始 */
• 1
• 2

content-box

border: 10px solid red;
    padding: 10px;
    shape-outside: content-box; /* 以元素的实际大小为起点,去掉border、margin */

此外还可以定义不规则的图形,让文字环绕这些不规则的图形。这里我们用ellipse()定义一个椭圆,让文字环绕椭圆

.shape{
    width: 100px;
    height: 100px;
    background: #ccc;
  float: right;
  clip-path: ellipse(50px 20px at 50% 50%); /* 裁切图形 */
  shape-outside: ellipse(50px 20px at 50% 50%); /* 环绕的实际图形 */
}

这里需要明白一点,clip-path裁切不是必须的(这里只是为了显示形状而已),真正的shapes布局是根据shape-outside而来,shape-outsid才是实际环绕的图形,如下:

.shape{
    width: 100px;
    height: 100px;
    background: #ccc;
  float: right;
    /* clip-path: ellipse(50px 20px at 50% 50%);  */
    shape-outside: ellipse(50px 20px at 50% 50%); /* 环绕的实际图形 */
}

关于形状裁切的几个属性:

属性 说明
circle() 定义一个圆形, 语法:circle(x轴(大小) at x轴坐标 y轴坐标); at后为剪切的位置,第一个参数左右,第二个参数上下
ellipse() 定义一个椭圆(使用两个半径和一个圆心位置)。语法:ellipse(x轴偏移 y轴偏移 at x轴坐标 y轴坐标)
inset() 四个参数,上右下左, 定义一个 inset 矩形。
polygon() 定义一个多边形(使用一个 SVG 填充规则和一组顶点)。四个参数,上右下左,每个位置的第一个参数代表左右偏移,第二个参数代表上下偏移
path() 定义一个任意形状(使用一个可选的 SVG 填充规则和一个 SVG 路径定义)。

裁切的具体用法可以去mdn上查询


动画

Shapes布局可以配合动画使用,动态的更改裁切的形状实现文字的动态变换:

<div class="container2">
     <div class="variant"></div>   <!-- 左侧的形状 -->
      <div class="variant2"></div>  <!-- 右侧的形状 -->
      <p>
        这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字这是一行文字这是一行文字
        这是一行文字这是一行文字
      </p>
</div>
.container2{
    width: 400px;
    height: 200px;
    border: 1px solid green;
    .variant{
        width: 200px;
        height: 200px;
        background: #ccc;
        clip-path: polygon(0 0, 0% 100%, 40% 50%); /*形状裁切*/
        float: left;  /*左浮动*/
        shape-outside: polygon(0 0, 0% 100%, 40% 50%);  /*实际环绕的形状*/
        animation: square 5s infinite linear;
    }
    .variant2{
        width: 200px;
        height: 200px;
        background: #ccc;
        clip-path: polygon(100% 0, 100% 100%, 60% 50%); /*形状裁切*/
        float: right; /*右浮动*/
        shape-outside: polygon(100% 0, 100% 100%, 60% 50%); /*实际环绕的形状*/
        animation: square2 5s infinite linear;
    }
    >p{
        text-align: center;
    }
     /* 利用动画,动态更改裁切的形状 */
    @keyframes square {
        0%,100%{
            clip-path: polygon(0 0, 0% 100%, 40% 50%);
            shape-outside: polygon(0 0, 0% 100%, 40% 50%);
        }
       25%{
            clip-path: polygon(0 0, 0% 100%, 40% 25%);
            shape-outside: polygon(0 0, 0% 100%, 40% 25%);
       }
       75%{
            clip-path: polygon(0 0, 0% 100%, 40% 75%);
            shape-outside: polygon(0 0, 0% 100%, 40% 75%);
       }
    }
    @keyframes square2 {
        0%,100%{
            clip-path: polygon(100% 0, 100% 100%, 60% 50%);
            shape-outside: polygon(100% 0, 100% 100%, 60% 50%);
        }
       25%{
            clip-path: polygon(100% 0, 100% 100%, 60% 25%);
            shape-outside: polygon(100% 0, 100% 100%, 60% 25%);
       }
       75%{
            clip-path: polygon(100% 0, 100% 100%, 60% 75%);
            shape-outside: polygon(100% 0, 100% 100%, 60% 75%);
       }
    }
}

渐变裁切

Shapes布局是可以使用渐变的,如果渐变的颜色完全透明就相当于不占位,那么shape就会占据并围绕透明的位置:

<div class="container3">
     <div class="pngs"></div>
     <p>
     这是一行文字这是一行文字这是一行文字这是一行文字
     这是一行文字这是一行文字这是一行文字这是一行文字
     这是一行文字这是一行文字这是一行文字这是一行文字
     这是一行文字这是一行文字这是一行文字这是一行文字
     这是一行文字这是一行文字
     </p>
</div>
.container3{
    width: 400px;
    height: 200px;
    border: 1px solid gold;
    margin: 30px;
    .pngs{
        width: 200px;
        height: 200px;
        float: left;
        /* 如果渐变的透明度为完全透明,那么shape就会占据并围绕透明的位置 */
        /* 建立一个变量 */
        --gradient : linear-gradient(to right bottom , #80c342 40% , transparent 50% , transparent 70%  , #4d90fe 80%);
        shape-outside: var(--gradient);
        background: var(--gradient);
        animation: gradients 5s infinite linear;
    }
    /* 动态更改渐变的颜色占比 */
    @keyframes gradients {
        0%,100%{
            --gradient : linear-gradient(to right bottom , #80c342 40% , transparent 50% , transparent 70%  , #4d90fe 80%);
        }
        25%{
            --gradient : linear-gradient(to right bottom , #80c342 20% , transparent 30% , transparent 60%  , #4d90fe 70%);
        }
        75%{
            --gradient : linear-gradient(to right bottom , #80c342 60% , transparent 70% , transparent 80%  , #4d90fe 90%);
        }
    }
}

图形变换的动画效果

效果如下:

利用动画动态更改裁切元素的图形,文字根据裁切形状动态的进行排版变化

<div class="container">
     <div class="left"></div>
     <div class="right"></div>
     <p>
     这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。
     这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。
     这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。
     这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。
     这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。
     这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。
     这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。这是一段文字。
     这是一段文字。这是一段文字。这是一段文字。这是一段文字。
     </p>
</div>
.container{
    width: 500px;
    height: 254px;
    border: 1px solid red;
    background: black;
    overflow: hidden;
    margin: 20px;
    padding-top: 40px; /* 设置头部内距,留出文字间隙 */
    >p{
        color: #fff;
        margin-top: -40px; /* 与父级padding数值相等,抵消padding */
    }
    .left{
        width: 200px;
        height: 200px;
        /* margin-top: 60px; */ /* 如果使用裁切动画则不能设置margin,这个margin是给元素展示的本体用的,并不是给shape-outside裁切的形图形用的 */
        float: left;
        background: #ccc;
        animation: variants 4s infinite linear;
        background: linear-gradient(to right , #4ac6ff , #bd34fe);
    }
    .right{
        width: 200px;
        height: 200px;
        // margin-top: 60px;  
        float: right;
        background: #ccc;
        animation: variants 4s infinite linear;
        background: linear-gradient(to left , #4ac6ff , #bd34fe);
    }
    @keyframes variants {
        0%,5%,95%,100%{
            /* polygon的参数数量必须一致,否则动画会失效 */
            clip-path: polygon(50% 0%, 62% 38%, 100% 50%, 62% 56%, 50% 100%, 37% 56%, 0 50%, 38% 38%);
            shape-outside: polygon(50% 0%, 62% 38%, 100% 50%, 62% 56%, 50% 100%, 37% 56%, 0 50%, 38% 38%);
        }
        45%{
            clip-path: polygon(50% 30%, 100% 0, 70% 50%, 100% 100%, 50% 70%, 0 100%, 30% 50%, 0 0);
            shape-outside: polygon(50% 30%, 100% 0, 70% 50%, 100% 100%, 50% 70%, 0 100%, 30% 50%, 0 0);
        }
        55%{
            clip-path: polygon(50% 30%, 100% 0, 70% 50%, 100% 100%, 50% 70%, 0 100%, 30% 50%, 0 0);
            shape-outside: polygon(50% 30%, 100% 0, 70% 50%, 100% 100%, 50% 70%, 0 100%, 30% 50%, 0 0);
        }
    }
}

这里有几个需要注意的地方:

1、给元素添加shape-outside后不能使用margin,因为margin是给元素展示的本体使用的,并不是给shape-outside裁切的形图形用的,否者会出现下图的效果:

2、动画中shape-outsidepolygon的参数和clip-path的参数需要一致,否则动画无法对应页面效果

3、由于shape-outside不能使用margin,如果我们想要移动裁切的位置,为上面留两行文字的空间,给父级添加padding即可,父级的内容使用 -margin 抵消padding即可。


案例源码:https://gitee.com/wang_fan_w/css-diary

如果觉得这篇文章对你有帮助,欢迎点赞👍、收藏💖、转发✨哦~

目录
相关文章
|
5月前
|
前端开发
Canvas背景色绘画样式设计
Canvas背景色绘画样式设计
|
前端开发
前端 SVG 与 Canvas 框架案例 (画线、矩形、箭头、文字 ....)
前端 SVG 与 Canvas 框架案例 (画线、矩形、箭头、文字 ....)
146 0
CSS3文本居中显示、圆形圆角绘制、立体阴影效果设置实例演示
CSS3文本居中显示、圆形圆角绘制、立体阴影效果设置实例演示
147 0
|
前端开发 JavaScript
NaiveUI中看起来没啥用的组件(文字渐变)实现原来这么简单
用不到80行代码复原了NaiveUI中的渐变文字组件,内容不多,非常简单,小小娱乐一次。。。。。。。
395 0
|
前端开发
基于canvas绘制边框环绕进度条
基于canvas绘制边框环绕进度条
260 0
基于canvas绘制边框环绕进度条
|
C++
duilib corner属性的贴图技巧——让图片自动贴到控件的的某一边或者一角并自适应控件的大小
转载请说明原出处,谢谢~~          Duilib给控件贴图功能可以附带多个属性,各个属性的配合可以达到许多效果。以下是duilib支持的所有贴图属性: 贴图描述:          Duilib的表现力丰富很大程度上得益于贴图描述的简单强大。
1830 0
|
前端开发
CSS高级技巧——鼠标样式,轮廓,文本域防拖拽,vertical-align 垂直对齐,文字溢出问题
CSS高级技巧——鼠标样式,轮廓,文本域防拖拽,vertical-align 垂直对齐,文字溢出问题
242 0
CSS高级技巧——鼠标样式,轮廓,文本域防拖拽,vertical-align 垂直对齐,文字溢出问题
UITableViewCell布局里面文字的自适应
UITableViewCell布局里面文字的自适应
169 0
UITableViewCell布局里面文字的自适应
|
Web App开发 移动开发 前端开发
H5:画布Canvas基础知识讲解(三)之文字、阴影、颜色渐变
​上一节介绍了H5:画布Canvas基础知识讲解(二)之插入图像、像素级操作,接下来继续讲解H5:画布Canvas基础。
如何让QComboBox控件下拉框自适应文字宽度?
如何让QComboBox控件下拉框自适应文字宽度?
1172 0