微信公众号css布局和SVG推文的一些坑

因为公众号网页的限制,不能写js,不能写css,只能在html标签里写内联样式,但是常常有需求要在推文上做一些交互和动画,这时候就需要SVG。

但是SVG在公众号上也有很多坑,总结一下遇到的一些坑,也有一些公众号其他的坑。

1,css的position属性全部失效,把代码上传到公众号之后,它会把position属性的代码删掉,所以公众号的布局不能用定位

 

2,ID全部失效,把代码上传到公众号之后,它会把ID删掉,包括写在HTML标签上的ID,还有SVG标签里面的ID

 

3,css的transform属性全部失效,把代码上传到公众号之后,它会把transform属性的代码删掉,(经测试现在的transform属性可以正常用了),SVG相关标签的transform属性有效,例如 <g transform="translate(10 10)"></g> 这样写是有效的

 

4,svg 里面不能嵌套 svg , 不能嵌套 image 标签, 经测试现在可以嵌套image标签了,但是href属性即图片的链接必须是素材库里的图片链接,外链或者base64均无法显示,如果是页面里普通的img标签则没有这个限制,width和height必须要写,不然在IOS上显示不了图片。

 

5,svg 尽量不要用渐变的颜色,因为代码会很多,体积太大,这个要跟设计师沟通

 

6,svg 相当于一张图了,全部放进去会文件体积很大,可以先压缩一下,在线SVG压缩:https://www.zhangxinxu.com/sp/svgo/

 

7,设计图 在使用AI设计时候,并不能使用复合路径、第二不能有任何超出画板外的元素在,第三文字使用扩展变为路径使用,并不能使用栅格化

 

8,IOS 上svg 动画的restart="never"没效,就是在苹果手机上再次点击的话,动画还是会执行,安卓没事,只做一次性的动画效果的话要留意下,目前无解,有解决方法欢迎留言。

(评论里有同学补充了解决方法,可以看看评论)

 

9,在公众号上是没办法通过媒体查询做屏幕适应的,所以遇到需要适应的元素,可以灵活使用VW或者VH作为单位来做适应

 

10,有的推文的交互一块内容然后向左滑动,但是之前遇到了要求向右滑动的,因为css横向滚动的容器默认滚动条是最左的,只能向左滑,如果想要右滑,我们需要在滚动的容器上加上dir="rtl"这个属性就行。这个属性原本用来规定文本的排列方向,用了这个属性文本就可以从右往左排,但是用在滚动容器上的时候,它就可以令滚动条一开始默认在最右,这样就可以一进来是往右滑的。(注意这个属性只适用于横向的排列和滚动,垂直方向是没效的)

 

11,做点击展开长图文,长图文里的元素不能有用float属性的,因为用了这个属性对应的元素会脱离文档流,在height为0的容器中也会显示出来,导致无法隐藏长图文。

 

12,在<g>标签里用style写内联样式,安卓跟PC端是有效的,在IOS上是失效的。例如我做一个旋转的动画,SVG是默认原点在左上角的,这时我们可以这样写<g style="transform-origin:50% 50%"></g>,这个g标签就会以中心为原点旋转,但是放到公众号推文上的时候,在IOS系统下<g style="transform-origin:50% 50%"></g>是不起作用的,它仍然以左上角为原点。做相关动画的时候要留意。

 

13,<svg>里可以通过<foreignObject>标签来嵌套其他的HTML元素,包括SVG,例如点击svg播放动效的时候同时播放音乐,先将音乐上传到公众号,再将代码复制过来,放到svg里用<foreignObject>包住,这样点击播放音乐的同时就会触发外层的SVG动画。

 

14,点击SVG后从头播放动图,需要先将动图放到页面之外,可以通过位移,点击触发之后再将动图移进来显示就可以从头播放动图,如果一进来就将动图显示在页面,他就会一直循环播放。

 

15,做点击展开长图文,可以将宽度写成固定值,现在大屏手机偏多,我一般写343px,这样在各种手机看起来高度就会一样,宽度的话在更大屏的手机上居中就行。

21/6/24 长图文展开有新的方法了,新的可以实现宽度全屏,之前的只能写死宽度,大宽屏手机下两边留白太多,例子如下:

<section style="overflow: hidden;" label="展开">
    <section style="text-align: center;height: 0;line-height: 0;">
     
      /**这里面放展开后的内容,不能用float*/
    
    </section>
    <section style="transform: rotateZ(0deg);text-align: center;line-height: 0;pointer-events: none;" label="">
      <svg viewBox="0 0 750 1295" style="max-width: none !important;pointer-events: none;">  /**外层SVG做展开,利用width撑开 values 500% 的值可根据展开后的内容调整*/
        <animate attributeName="width" fill="freeze" restart="never" keyTimes="0;.2;1" values="100%;0%;500%" dur="6s" begin="click">
        </animate>
       

        <g>
          <foreignObject x="0" width="100%" height="100%">  /**内层SVG做展开前的内容展示,一般放点击展开前的图*/
 <svg viewBox="0 0 750 1295"  display: block; pointer-events: auto;"> </svg> </foreignObject> </g> </svg> </section> </section>

 

 

16,做自动展开长图文,如果在微信编辑器已经展开了图文再生成预览,它会给SVG自动加上高度height,所以我们要给svg一个一进来就执行的高度动画,例如

  <animate attributeName="height" fill="freeze" restart="never" values="3730;340" dur="0.01s" >
            </animate>

这样就可以把微信强加的高度覆盖回去。

 

17,直接用img放单次循环的图片是没有效果的,推文那里会强制无限次循环动图,但是把图片放在SVG里面,用SVG做背景图或者套个image标签就可以实现单次循环

 

18,SVG双次点击,一般SVG只会触发一次动画,多次的话要用g标签包裹,在g标签里写动画,但是如果动画要作用于svg标签上的话,就只能触发一次了,这时可以通过设置不用的动画触发方式来两次触发动画,写一个touchstart动画触发的动画,然后再写一个click触发的动画,这样第一次点击svg的时候就会执行touchstart的动画,click的要在第二次点击的时候才会触发

 

19,svg随机结果,就是在公众号的SVG里长按,然后不停切换图片,松手就会停止。应用场景例如抽签和扭蛋之类的,但是公众号推文里有一个BUG就是在安卓上没有办法停在松手时的位置,无论你长按多久,它只会在第一张图停下,ios系统则可以做到什么时候松手就停在什么地方。

解决方法就是增加一个有循环动画的元素来当触发媒介,之前长按是直接按在SVG本身或者里面的g标签、图片标签,现在需要增加一个有循环动画的元素覆盖长按触发的互动区域,这样长按就会按在这个元素上,再通过这个元素触发父级切换图片的动画,这样安卓就可以随松随停,原理我也不清楚,公众号SVG的坑太多了。。。

示例:

<section label="第一部分" style="user-select: none;margin-top: -1px;display: inline-block;width: 100%;vertical-align: top;-webkit-tap-highlight-color: transparent;background-attachment: scroll;"><svg style="margin-top: 0px;display: block;width: 100%;" version="1.1" viewBox="0 0 750 932" xlink="http://www.w3.org/1999/xlink" xml="" xmlns="http://www.w3.org/2000/svg"><g><animateTransform attributeName="transform" type="translate" values="0 0;-1000 0;-2000 0;-3000 0;" repeatCount="indefinite" fill="freeze" begin="touchstart" end="touchend" dur="2s" calcMode="discrete"></animateTransform><g label="静态图片1"><image y="0" width="750" height="700" href="https://mmbiz.qpic.cn/mmbiz_jpg/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgaziakP3meT6dWtvs8fFHf2bv97EppxAKm3fQKgpp6YX2XdgB4Wbv2DTQ/0?wx_fmt=jpeg" x="0"></image><g label="下方的动态"><image width="750" height="232" href="https://mmbiz.qpic.cn/mmbiz_gif/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgazzuIQI4NXFXnKpsEu4iapeGKQOqjqtLkOkKhzXNaHn8QCcN52KAh2eQ/0?wx_fmt=gif" x="0" y="700"></image></g><g label="点击区域" opacity="0"><rect width="300" height="80" x="350" y="600" opacity="0" fill="red"><animate attributeName="opacity" values="1;0;1" fill="freeze" dur=".8s" repeatCount="indefinite"></animate></rect></g></g><g label="静态图片2" transform="translate(1000 0)"><image y="0" width="750" height="700" href="https://mmbiz.qpic.cn/mmbiz_jpg/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzga1DiciaDVH2GBTy8cMSLg1UekMZXYvvocUrH5xnpSGr6hnA68zJtaT8Vw/0?wx_fmt=jpeg" x="0"></image><g label="下方的动态"><image width="750" height="232" href="https://mmbiz.qpic.cn/mmbiz_gif/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgazzuIQI4NXFXnKpsEu4iapeGKQOqjqtLkOkKhzXNaHn8QCcN52KAh2eQ/0?wx_fmt=gif" x="0" y="700"></image></g><g label="点击区域" opacity="0"><rect width="300" height="80" x="350" y="600" opacity="0" fill="red"><animate attributeName="opacity" values="1;0;1" fill="freeze" dur=".8s" repeatCount="indefinite"></animate></rect></g></g><g label="静态图片3" transform="translate(2000 0)"><image y="0" width="750" height="700" href="https://mmbiz.qpic.cn/mmbiz_jpg/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgaLoyzFoUbbIw0ic79UWGGO8TCia8X8WpP59hiaDdBxnWr8IgsN7EEGJgMg/0?wx_fmt=jpeg" x="0"></image><g label="下方的动态"><image width="750" height="232" href="https://mmbiz.qpic.cn/mmbiz_gif/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgazzuIQI4NXFXnKpsEu4iapeGKQOqjqtLkOkKhzXNaHn8QCcN52KAh2eQ/0?wx_fmt=gif" x="0" y="700"></image></g><g label="点击区域" opacity="0"><rect width="300" height="80" x="350" y="600" opacity="0" fill="red"><animate attributeName="opacity" values="1;0;1" fill="freeze" dur=".8s" repeatCount="indefinite"></animate></rect></g></g><g label="静态图片4" transform="translate(3000 0)"><image y="0" width="750" height="700" href="https://mmbiz.qpic.cn/mmbiz_jpg/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzga84bBybu5YtzjiaeXP36j4XKicUD9qhrdaxib8BbiaCFrYDpaS66wTmUd4g/0?wx_fmt=jpeg" x="0"></image><g label="下方的动态"><image width="750" height="232" href="https://mmbiz.qpic.cn/mmbiz_gif/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgazzuIQI4NXFXnKpsEu4iapeGKQOqjqtLkOkKhzXNaHn8QCcN52KAh2eQ/0?wx_fmt=gif" x="0" y="700"></image></g><g label="点击区域" opacity="0"><rect width="300" height="80" x="350" y="600" opacity="0" fill="red"><animate attributeName="opacity" values="1;0;1" fill="freeze" dur=".8s" repeatCount="indefinite"></animate></rect></g></g><g><set attributeName="visibility" from="visible" to="hidden" begin="touchstart"></set><image width="750" height="700" href="https://mmbiz.qpic.cn/mmbiz_gif/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzga8dGUjDnohVicT4Du4vMPb5ia3XyZ0obUIEpdKkAStibjJ3pwl9ghN0icog/0?wx_fmt=gif" x="0"></image><g xmlns="http://www.w3.org/2000/svg"><g><image width="750" height="232" href="https://mmbiz.qpic.cn/mmbiz_gif/bPHvQl9gGrMOzA0cxw0GvwibGreYZAzgazzuIQI4NXFXnKpsEu4iapeGKQOqjqtLkOkKhzXNaHn8QCcN52KAh2eQ/0?wx_fmt=gif" x="0" y="701"></image></g></g></g></g><g transform="translate(-80 -1100) scale(1.5)"><path d="M1,0L0,1395.766h800L801,0H1z M400.945,1229.013c-36.02,0-64.955-28.935-64.955-64.955c0-36.02,28.935-64.955,64.955-64.955  s64.955,28.935,64.955,64.955C465.903,1200.078,436.965,1229.013,400.945,1229.013z" style="opacity: 0;fill: red;"></path></g></svg></section>

 

20,GIF 图片不能超过300帧,大小不能超过10M,普通图片总像素不能超过600万(就是尺寸不能太高,一般的750设计稿的图就够用了,宽度最好也不要超过1080,不然太大传上去也会被压缩的)

 

21,有时候图片与图片之间会有白缝,可以将img转为 display:block; 解决 , 可以用 float:left; ,如果想清楚浮动可以给父级元素设置overflow:hidden;

如果上面的设置了还有白缝可以用margin-top:-1px;来微调。

 

22,在可滚动的容器上加上dir属性可以定义滚动内容的方向,比如设置了overflow-x横向滚动,默认是从左往右开始滚动的,但是加上dir=“rtl”后,就是设置成默认从右向左滚动,注意:如果overflow-y垂直滚动,那么dir属行改变的是里面内容的排列方向,不是改变滚动方向,比如有一句123的话在左边,设置了之后123就变到右边了;

关于滚动还有一些有趣的属性,比如 scroll-snap-type , 至于怎么用上就看项目需求,靠大家发挥下想像力了。

 

23,翻页的效果可以参考css3的transform:scale(-1)来实现 ,在svg里的animationTransform的scale设置为-1即可

参考案例:https://mp.weixin.qq.com/s/n4fBuV850mwjG6FT-thLiw

这条更新一个很奇葩的BUG,我做的推文跟上面的案例基本一样,除了最后的点击跳转小程序改为长按图片识别二维码,因为长按必须用图片,所以我在svg的foreignObject里放了一个img标签来做长按识别,

平常的安卓和苹果手机都没有问题,但是如果IOS系统的手机调成深色模式,里面包裹的img就会变得很大超出屏幕,这个BUG只出现在IOS的深色模式,原因不明,我估计跟IOS系统或者微信APP有关,解决方法就是奖识别的图片拿出来不放在svg里。

21/11/30

原因找到了,因为深色模式会给页面上的元素都加上了transform属性,导致层级乱了,解决方法可以参考这篇文章:你的交互图文翻车了吗|深色模式适配方案

24,深色模式适配:

你的交互图文翻车了吗|深色模式适配方案

深色模式下的图片变暗问题,解决了!

 

25,固定一屏滑动 滑动容器: scroll-snap-type: x mandatory;  里面的元素:scroll-snap-align: start;

 

26,推文里position是失效的,所以不能通过定位的层级来设置,之前可以通过设置tranfrom属性调整层级,但是在手机暗黑模式下,所有元素都会被添加上transform属性,所以在有些情况下transform不是那么实用了,

现在最新的层级设置是通过在父容器添加display:flex; 属性,在子元素上添加z-index属性来调整层级,通过z-index设置的层级甚至比transform设置的层级更高。

 

 

 

 P.S.:

· 单位不能用百分比。例如transform:translateY(-100%) ; margin-top:-100%; 在公众号上会失效,建议用px或者vw/vh

· pointer-events:none; 这个属性可以让所有交互事件失效,在一些场景会需要,可自行探索

· 给SVG设置背景图,图片路径尽量不用单引号包括

例如:url(img) ---- 复制到公众号可以显示,url('img') ---- 复制到公众号有时不可以显示

 

 

 

 

 

一些参考链接:https://www.cnblogs.com/haqiao/p/11731064.html  , https://zhuanlan.zhihu.com/p/52973079

 

posted @ 2020-08-05 11:21  哈哈敲敲  阅读(7752)  评论(4编辑  收藏  举报