Safari浏览器对SVG中的<foreignObject>标签支持不友好,渲染容易错位
在 svg 中需要写一个 markdown 编辑器,需要用到 <foreignObject> 绘制来html,编辑器选择了 simplemde。大致html部分结构如下,<markdown-editor> 组件为定制封装好的 simplemde 编辑器。
<template>
<svg>
<g>
<foreignObject :width="XXX" :height="XXX">
<div xmlns="http://www.w3.org/1999/xhtml">
<markdown-editor></markdown-editor>
</div>
</foreignObject>
</g>
</svg>
</template>
在 Chrome 浏览器开发完成,测试上线都符合预期,但是最后收到用户反馈:她用的是 mac 自带的 Safari 浏览器,在 Safari 里markdown编辑器会出现错位等各种问题。于是我先打开我的 Firefox 浏览器,自测正常,那估计就是 Safari 浏览器的兼容问题了。我看了下 Safari 浏览器的表现:markdown 编辑器每次一打开检查本身的 dom 占位是正确的,但是可视的编辑器界面却会被渲染到最顶部 <svg> 标签的左上角原点(0,0)。最后排查到是因为 safari 对 SVG 中的 <foreignObject> 标签支持不友好,渲染容易错位,特别是遇到 position 属性的时候,而我在引入simplemde 编辑器的同时也引入了 simplemde.min.css,其中大量使用了 position 属性我也在 StackOverflow 和 Github 找到了几篇关于这个bug的讨论帖作为参考:
StackOverflow:SVG foreignObject not working properly on Safari
Github:Safari + foreignobject render issue

最后Github一位程序员ankero一锤定音,原文大意如下:
这不是一个问题,但是可以添加到 README 中。我将在这里添加它,以便如果有人面临类似的问题,可以在这个仓库中找到一个解决方案。在使用这个库(指的是react-d3-tree库,但是遇到的问题是一样的)进行开发时,如果使用 foreignObject 呈现节点,请检查它在 Safari (Mac + iOS)中的显示方式。我们遇到了一个问题,节点内容呈现为父 SVG 的坐标0,0(左上角)。这是由于 Safari 中的一个 bug,它影响 foreignObject 根据顶部 SVG 而不是 foreignObject 本身计算呈现位置。通过检查节点并查看基于浏览器的节点是否在应该在的位置,您可以非常清楚地看到这种效果,但是呈现在了错误的位置。(这段描述和我当时排查的结果一模一样)
那么,如果你看到这个问题,解决方案是什么?
据我所知,如果您使用以下任何 CSS 选项,dom 元素将呈现在错误的位置。所以解决办法就是不要用这些。对我们来说,我们需要检查浏览器是否是 Safari,然后删除一些需要一个或多个这样的样式的功能。
所以不要在 Safari + foreignObject 中使用以下样式:
- position(您可以使用 position: fixed,但这将导致溢出问题)
- webkit-transform-style
- webkit-backface-visibility
- transition
- transform
如何检测 Safari?
我们使用以下片段:
export const IS_SAFARI = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor);
这里提一下 position: fixed 导致的溢出问题,这个在上一个StackOverflow链接中被很多程序员提为解决,方案,这个办法确实能解决一些简单的需求和页面,但是需要注意的一点是,使用这种办法会导致页面缩放出现问题。具体来说就是svg所绘制元素的缩放比例与<foreignObject>所绘制元素的缩放比例不是一致的,这也会带来位置错乱问题。不过可以根据自己的具体情况进行抉择。
各大浏览器之间的兼容问题是各位前端er心中永远的痛,一方面希望谷歌或火狐浏览器能一统江湖,但是另一方面又希望百家齐放能促进前端技术的发展。但是话说又说回来,最重要的还是遵守标准,既然标准都设立在那了,为啥各家不跟上标准呢。
Safari浏览器对SVG中的<foreignObject>标签支持不友好,渲染容易错位的更多相关文章
- WebKit策略:<foreignObject>可用于绘制svg中的html标签,但与<use>搭配不生效
在<svg>里面可以利用<foreignObject>绘制html标签,原本是我在iconfont采用Font class方式引入svg的无奈之举. 起初的设计是所有icon先 ...
- html页面在苹果手机内,safari浏览器,微信中滑动不流畅问题解决方案
1. -webkit-overflow-scrolling:touch是什么? MDN上是这样定义的: -webkit-overflow-scrolling 属性控制元素在移动设备上是否使用滚动回弹效 ...
- Dedecms中{dede:type}标签支持调用父级栏目名称
需求: 我们用{dede:type}标签调用栏目相关内容时,同时需要调用该栏目的父级栏目的名称. {dede:type}标签的代码做了一下开发,支持这个调用了. 开发方法: 1.打开include/t ...
- eclipse中添加jstl标签支持(引入头)
https://blog.csdn.net/wangyuxuan_java/article/details/8580318
- d3.js svg中 g 标签问题一览
svg 中的g标签, 算是比较特殊 1 没有x y属性 2 没有width height 属性 3 不能fill 4 .... g标签基本只管分组问题, 其他功能一概不提供 要解决这些问题, 直接在g ...
- iOS中Safari浏览器select下拉列表文字太长被截断的处理方法
网页中的select下拉列表,文字太长的话在iOS的Safari浏览器里会被自动截断,显示成下面这种: 安卓版的浏览器则没有这个问题. 如何让下拉列表中的文字在iOS的Safari浏览器里显示完整呢? ...
- 利用iOS中Safari浏览器创建伪Web App
在safari浏览器里有一个“添加到主屏幕”选项,我们可以用来创建伪Web App,下面来了解一下iOS中Safari的私有属性 第一步设置Web App的主屏幕图标: 有两种属性值apple-tou ...
- 获取SVG中g标签的宽度高度及位置坐标
1. 问题的出现 对于普通的HTML元素,有很多获得其宽度width.高度height.距左left.距顶top等属性的方法: 类似offsetWidth,clientWidth,width之类的,通 ...
- 发布时一键添加html中的css标签和script标签版本号来防止浏览器缓存
AppendFileVersion 是一个VSIX插件支持vs2015意以上版本 是我用来发布时一键添加html中的css标签和script标签版本号来防止浏览器缓存 分享给大家! download ...
- 解决java web中safari浏览器下载后文件中文乱码问题
解决java web中safari浏览器下载后文件中文乱码问题 String fileName = "测试文件.doc"; String userAgent = request.g ...
随机推荐
- [题解] Codeforces 1349 D Slime and Biscuits 概率,推式子,DP,解方程
题目 神题.很多东西都不知道是怎么凑出来的,随意设置几个变量,之间就产生了密切的关系.下次碰到这种题应该还是不会做罢. 令\(E_x\)为最后结束时所有的饼干都在第x个人手中的概率*时间的和.\(an ...
- NOI2015 洛谷P1955 程序自动分析(并查集+离散化)
这可能是我目前做过的最简单的一道noi题目了...... 先对e=1的处理,用并查集:再对e=0查询,如果这两个在同一集合中,则为""NO",最后都满足的话输出" ...
- MFC-创建MFC图形界面dll
创建MFC图形界面dll 概述: 利用MFC的DLL框架,制作带有图形界面的dll,可以实现很多功能. 流程: 选择静态链接MFC DLL:以免有的库没有. 采用该框架创建的MFC,会自动生产一个MF ...
- Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2020-02-06'; nested exception is java.lang.IllegalArgumentException]解决
今天做springbook项目前端输入日期传到数据库保存报了一下错误 Whitelabel Error Page This application has no explicit mapping fo ...
- GO编译时不避免引入外部动态库的解决方法
简介 最近碰到一个问题,有一个流量采集的组件中使用到了github.com/google/gopacket 这个库,这个库使用一切正常,但是唯独有一个缺点,编译后的二进制文件依赖于libpcap.so ...
- PHP配置负载均衡
我项目是用宝塔面板.所以这次用宝塔面板演示. 环境: LNMP 代码:2套.2套代码除了配置其他都是一样 域名:1个.2级域名.其实一级二级都没关系 /************************ ...
- C语言编译环境中的 调试功能及常见错误提示
文章目录 1 .调试功能 2 . 编译中的常见错误例析 3 .常见错误信息语句索引 1 .调试功能 1.常用健 <F10> : 激活系统菜单 <F6> : 将光标在编辑窗口和. ...
- springboot+mybatis+shiro项目中使用shiro实现登录用户的权限验证。权限表、角色表、用户表。从不同的表中收集用户的权限、
要实现的目的:根据登录用户.查询出当前用户具有的所有权限.然后登录系统后.根据查询到的权限信息进行不同的操作. 以下的代码是在搭好的框架之下进行的编码. 文章目录 核心实现部分. 第一种是将用户表和角 ...
- Netty学习记录-入门篇
你如果,缓缓把手举起来,举到顶,再突然张开五指,那恭喜你,你刚刚给自己放了个烟花. 模块介绍 netty-bio: 阻塞型网络通信demo. netty-nio: 引入channel(通道).buff ...
- Linux---配置新服务器的常见操作(CentOS7)
修改 Centos7为字符界面 Centos7取消了之前的 inittab文件的作用,改用命令实现, systemctl get-default : 获得默认启动方式 systemctl set-de ...