在 Chrome 和 Safari 上一致地显示 SVG

问题描述 投票:0回答:1

我一直在尝试在我的 gatsby.js 应用程序中跨浏览器一致地显示 SVG。我尝试了两种不同的方法,但都没有完全起作用。

SVG 精灵

按照这个答案,我创建了一个图标精灵文件并制作了一个组件来显示信息。

import * as React from "react" import { useStaticQuery, graphql } from "gatsby" import PropTypes from "prop-types" import { StyledSocialList, StyledSocialLi } from "./social.styled" import IconsFile from "../../../static/images/icons.svg" const Icon = ({ name, color, size }) => ( <svg className={`icon icon-${name}`} fill={color} width={size} height={size}> <use xlinkHref={`${IconsFile}#icon-${name}`} /> </svg> ) const Icons = ({ size }) => { const data = useStaticQuery(graphql` query SocialQuery { site { siteMetadata { social { linkedin orcid github googlescholar } } } } `) const social = data.site.siteMetadata?.social let icons = [ { src: <Icon name="linkedin-square" color="#000" size={size} />, link: `https://www.linkedin.com/in/${social?.linkedin}`, alt: "Click to read my Linkedin profile", }, { src: <Icon name="github" color="#000" size={size} />, link: `https://www.github.com/${social?.github}`, alt: "Click to see my Github", }, { src: <Icon name="google-scholar" color="#000" size={size} />, link: `https://scholar.google.com/citations?user=${social?.googlescholar}`, alt: "Click to see my citations on Google Scholar", }, { src: <Icon name="orcid" color="#000" size={size} />, link: `https://www.orcid.org/${social?.orcid}`, alt: "Click to see my researcher profile on Orcid", }, ] return icons.map((icon, index) => ( <StyledSocialLi key={index}> <a href={icon.link} target="_blank" rel="noreferrer" alt={icon.alt} aria-label={icon.alt} > {icon.src} </a> </StyledSocialLi> )) } const Social = ({ size = 30 }) => { return ( <StyledSocialList> <Icons size={size}/> </StyledSocialList> ) } export default Social
这个在 Chrome 中有效,但 Safari 拒绝渲染 SVG,因为它认为 

use

 元素的 href 是 XSS 违规。

data:image/svg+xml;base64,PHN2Z...#icon-orcid 来自来源

https://kyleshores.com。域、协议和端口必须匹配。

嵌入路径

作为替代方案,我尝试通过保存路径来创建 SVG,这样数据就不会从看起来像 Safari 的 URI 加载。

import * as React from "react" import { useStaticQuery, graphql } from "gatsby" import { StyledSocialList, StyledSocialLi } from "./social.styled" const Svg = ({ path, color, size }) => { const viewBox = `0 0 ${size} ${size}`; return ( <svg xmlns="http://www.w3.org/2000/svg" viewBox={viewBox} width={size} height={size} fill={color}> <path d={path} /> </svg> ); }; const paths= { 'linkedin': "M29 0h-26c-1.65 0-3 1.35-3 3v26c0 1.65 1.35 3 3 3h26c1.65 0 3-1.35 3-3v-26c0-1.65-1.35-3-3-3zM12 26h-4v-14h4v14zM10 10c-1.106 0-2-0.894-2-2s0.894-2 2-2c1.106 0 2 0.894 2 2s-0.894 2-2 2zM26 26h-4v-8c0-1.106-0.894-2-2-2s-2 0.894-2 2v8h-4v-14h4v2.481c0.825-1.131 2.087-2.481 3.5-2.481 2.488 0 4.5 2.238 4.5 5v9z", 'google-scholar': "M21.485 6.666v-1.702l1.235-0.964h-13.368l-8.072 7.017h5.354c-0.010 0.133-0.014 0.253-0.014 0.389 0 1.303 0.451 2.38 1.354 3.241 0.903 0.862 2.016 1.29 3.333 1.29 0.308 0 0.609-0.023 0.902-0.064-0.182 0.406-0.273 0.783-0.273 1.134 0 0.617 0.281 1.277 0.842 1.978-2.452 0.167-4.254 0.608-5.402 1.323-0.658 0.406-1.188 0.919-1.587 1.533-0.399 0.619-0.599 1.282-0.599 1.998 0 0.603 0.129 1.146 0.389 1.629s0.599 0.879 1.019 1.186c0.42 0.311 0.904 0.569 1.451 0.779 0.546 0.209 1.088 0.357 1.629 0.441 0.539 0.084 1.075 0.125 1.607 0.125 0.842 0 1.685-0.108 2.534-0.324 0.848-0.218 1.643-0.54 2.386-0.968 0.741-0.425 1.345-1.005 1.808-1.732 0.462-0.73 0.693-1.55 0.693-2.459 0-0.689-0.141-1.315-0.422-1.884-0.279-0.567-0.621-1.034-1.028-1.396s-0.813-0.697-1.22-0.998c-0.406-0.303-0.75-0.609-1.029-0.926-0.28-0.315-0.421-0.628-0.421-0.936s0.108-0.604 0.326-0.892c0.216-0.288 0.48-0.566 0.788-0.832s0.617-0.56 0.925-0.883c0.308-0.322 0.571-0.739 0.788-1.251s0.325-1.090 0.325-1.735c0-0.841-0.159-1.529-0.472-2.082-0.037-0.064-0.076-0.113-0.117-0.189l3.557-2.917v1.070c-0.462 0.058-0.414 0.334-0.414 0.665v8.042c0 0.372 0.305 0.677 0.677 0.677h0.249c0.372 0 0.677-0.305 0.677-0.677v-8.042c0-0.33 0.049-0.606-0.41-0.664zM14.775 20.571c0.071 0.047 0.232 0.174 0.482 0.377 0.253 0.203 0.425 0.356 0.517 0.463 0.090 0.104 0.224 0.26 0.399 0.472s0.295 0.394 0.357 0.546c0.063 0.155 0.126 0.341 0.19 0.559 0.062 0.215 0.093 0.436 0.093 0.66 0 1.066-0.41 1.855-1.229 2.366-0.82 0.511-1.798 0.767-2.934 0.767-0.574 0-1.138-0.068-1.691-0.2-0.553-0.132-1.082-0.334-1.587-0.6s-0.911-0.638-1.219-1.112c-0.309-0.477-0.463-1.026-0.463-1.641 0-0.645 0.175-1.206 0.526-1.682 0.35-0.477 0.809-0.837 1.377-1.082 0.566-0.247 1.141-0.421 1.723-0.525 0.582-0.106 1.175-0.16 1.777-0.16 0.279 0 0.496 0.016 0.65 0.044 0.028 0.014 0.19 0.129 0.483 0.348 0.294 0.216 0.477 0.35 0.547 0.399zM14.565 14.285c-0.463 0.554-1.108 0.831-1.935 0.831-0.741 0-1.394-0.298-1.954-0.895-0.563-0.595-0.964-1.271-1.209-2.027-0.246-0.757-0.369-1.499-0.369-2.228 0-0.856 0.225-1.585 0.674-2.186 0.449-0.603 1.094-0.905 1.934-0.905 0.742 0 1.398 0.315 1.965 0.947 0.568 0.63 0.976 1.338 1.22 2.123 0.245 0.784 0.367 1.533 0.367 2.249 0 0.84-0.231 1.538-0.692 2.091z", 'orcid': "M21.039 12.159c-0.446-0.208-0.867-0.347-1.266-0.413-0.398-0.068-1.036-0.101-1.919-0.101h-2.294v9.547h2.352c0.917 0 1.63-0.063 2.139-0.189s0.933-0.283 1.272-0.477c0.34-0.192 0.651-0.429 0.934-0.712 0.905-0.92 1.359-2.080 1.359-3.482 0-1.378-0.465-2.503-1.396-3.374-0.344-0.323-0.739-0.59-1.181-0.8zM16 0.5c-8.561 0-15.5 6.94-15.5 15.5s6.939 15.5 15.5 15.5c8.561 0 15.5-6.94 15.5-15.5s-6.939-15.5-15.5-15.5zM10.854 22.845h-1.837v-12.835h1.837zM9.934 8.668c-0.696 0-1.263-0.563-1.263-1.263 0-0.695 0.566-1.262 1.263-1.262 0.699 0 1.265 0.566 1.265 1.262-0.001 0.701-0.566 1.263-1.265 1.263zM25.021 18.893c-0.331 0.784-0.802 1.474-1.416 2.068-0.624 0.615-1.35 1.075-2.178 1.387-0.484 0.189-0.927 0.316-1.332 0.382-0.406 0.063-1.177 0.094-2.317 0.094h-4.060v-12.816h4.327c1.748 0 3.127 0.26 4.145 0.784 1.017 0.523 1.824 1.296 2.424 2.311 0.601 1.017 0.902 2.126 0.902 3.325 0.001 0.86-0.167 1.682-0.496 2.465z", 'github': "M16 0.395c-8.836 0-16 7.163-16 16 0 7.069 4.585 13.067 10.942 15.182 0.8 0.148 1.094-0.347 1.094-0.77 0-0.381-0.015-1.642-0.022-2.979-4.452 0.968-5.391-1.888-5.391-1.888-0.728-1.849-1.776-2.341-1.776-2.341-1.452-0.993 0.11-0.973 0.11-0.973 1.606 0.113 2.452 1.649 2.452 1.649 1.427 2.446 3.743 1.739 4.656 1.33 0.143-1.034 0.558-1.74 1.016-2.14-3.554-0.404-7.29-1.777-7.29-7.907 0-1.747 0.625-3.174 1.649-4.295-0.166-0.403-0.714-2.030 0.155-4.234 0 0 1.344-0.43 4.401 1.64 1.276-0.355 2.645-0.532 4.005-0.539 1.359 0.006 2.729 0.184 4.008 0.539 3.054-2.070 4.395-1.64 4.395-1.64 0.871 2.204 0.323 3.831 0.157 4.234 1.026 1.12 1.647 2.548 1.647 4.295 0 6.145-3.743 7.498-7.306 7.895 0.574 0.497 1.085 1.47 1.085 2.963 0 2.141-0.019 3.864-0.019 4.391 0 0.426 0.288 0.925 1.099 0.768 6.354-2.118 10.933-8.113 10.933-15.18 0-8.837-7.164-16-16-16z", } const Icons = props => { const data = useStaticQuery(graphql` query SocialQuery { site { siteMetadata { social { linkedin orcid github googlescholar } } } } `) const social = data.site.siteMetadata?.social let icons = [ { src: <Svg path={paths['linkedin']} {...props}/>, link: `https://www.linkedin.com/in/${social?.linkedin}`, }, { src: <Svg path={paths['github']} {...props}/>, link: `https://www.github.com/${social?.github}`, }, { src: <Svg path={paths['google-scholar']} {...props}/>, link: `https://scholar.google.com/citations?user=${social?.googlescholar}`, }, { src: <Svg path={paths['orcid']} {...props}/>, link: `https://www.orcid.org/${social?.orcid}`, }, ] return icons.map((icon, index) => ( <StyledSocialLi key={index}> <a href={icon.link} target="_blank" rel="noreferrer"> {icon.src} </a> </StyledSocialLi> )) } const Social = ({ size = 10, color = "black" }) => { return ( <StyledSocialList> <Icons size={size} color={color} /> </StyledSocialList> ) } export default Social
在这种情况下,图标会在两个浏览器中呈现,但不考虑大小。 

svg

 元素的大小适当,但封闭路径始终为 32 x 32。

它的外观如下:

我对这两种方法都没有偏好,但我希望得到一些关于如何纠正这个问题的建议。

款式

在这两种情况下,样式组件都是这样的:

import styled from 'styled-components'; const StyledSocialList = styled.ul` list-style-type: none; margin: 0; padding: 0; ` const StyledSocialLi = styled.li` display: inline; padding: 0 var(--spacing-1); ` export { StyledSocialList, StyledSocialLi, }
    
javascript css reactjs svg gatsby
1个回答
0
投票
另一种适用于两种浏览器的解决方案是将 SVG 数据嵌入到组件中,以便 Safari 不会认为某些内容是从另一个 URL 加载的。

import * as React from "react" import { useStaticQuery, graphql } from "gatsby" import { StyledSocialList, StyledSocialLi } from "./social.styled" since it thought the data was from some other place const Icon = ({ name, color, size }) => ( <svg className={`icon icon-${name}`} fill={color} width={size} height={size}> <use xlinkHref={`#icon-${name}`} /> <symbol id="icon-google-scholar" viewBox="0 0 512 512"> <path d="m408 107l0-28 20-15-214 0-130 112 86 0c0 2 0 4 0 7 0 20 7 38 22 51 14 14 32 21 53 21 5 0 10 0 14-1-3 6-4 13-4 18 0 10 4 21 13 32-39 2-68 10-86 21-11 6-19 15-25 24-7 10-10 21-10 32 0 10 2 19 6 26 4 8 10 15 17 19 6 5 14 10 23 13 9 3 17 6 26 7 8 1 17 2 26 2 13 0 27-2 40-5 14-4 26-9 38-16 12-6 22-16 29-27 8-12 11-25 11-40 0-11-2-21-6-30-5-9-10-16-17-22-6-6-13-11-19-16-7-5-12-10-17-15-4-5-7-10-7-15 0-5 2-10 6-14 3-5 7-9 12-14 5-4 10-9 15-14 5-5 9-12 13-20 3-8 5-17 5-27 0-14-3-25-8-34 0-1-1-2-2-3l57-46 0 17c-7 1-6 5-6 10l0 129c0 6 5 11 10 11l4 0c6 0 11-5 11-11l0-129c0-5 1-9-6-10z m-108 222c2 1 4 3 8 6 4 3 7 6 8 8 2 1 4 4 7 7 3 4 4 6 5 9 1 2 2 5 4 9 1 3 1 7 1 10 0 17-7 30-20 38-13 8-28 13-47 13-9 0-18-2-27-4-8-2-17-5-25-9-8-5-15-10-20-18-4-8-7-16-7-26 0-11 3-20 8-27 6-8 13-14 23-18 9-3 18-6 27-8 9-2 19-3 29-3 4 0 7 1 10 1 0 0 3 2 8 6 4 3 7 5 8 6z m-3-100c-7 8-18 13-31 13-12 0-22-5-31-14-9-10-16-21-20-33-3-12-5-24-5-36 0-13 3-25 10-35 8-9 18-14 31-14 12 0 23 5 32 15 9 10 15 22 19 34 4 13 6 25 6 36 0 14-4 25-11 34z" /> </symbol> <symbol id="icon-orcid" viewBox="0 0 512 512"> <path d="m337 195c-8-4-14-6-21-7-6-1-16-2-30-2l-37 0 0 153 38 0c14 0 26-1 34-3 8-2 15-4 20-8 6-3 11-6 15-11 15-15 22-33 22-56 0-22-8-40-22-54-6-5-12-9-19-12z m-81-187c-137 0-248 111-248 248 0 137 111 248 248 248 137 0 248-111 248-248 0-137-111-248-248-248z m-82 358l-30 0 0-206 30 0z m-15-227c-11 0-20-9-20-21 0-11 9-20 20-20 11 0 20 9 20 20 0 12-9 21-20 21z m241 163c-5 13-12 24-22 33-10 10-22 18-35 23-8 3-15 5-21 6-7 1-19 1-38 1l-64 0 0-205 69 0c28 0 50 4 66 13 16 8 29 20 39 37 9 16 14 34 14 53 0 14-2 27-8 39z" /> </symbol> <symbol id="icon-linkedin-square" viewBox="0 0 512 512"> <path d="m104 404l66 0 0-198-66 0z m71-259c-1-10-4-19-11-25-6-6-15-10-26-10-11 0-20 4-27 10-7 6-11 15-11 25 0 9 4 17 10 24 7 7 16 10 27 10l0 0c11 0 20-3 27-10 7-7 11-15 11-24z m167 259l66 0 0-114c0-29-7-51-21-66-14-15-32-23-55-23-26 0-46 11-60 34l1 0 0-29-66 0c0 12 0 78 0 198l66 0 0-111c0-7 0-12 2-16 2-7 7-12 12-17 6-5 13-7 22-7 22 0 33 15 33 45z m133-285l0 274c0 23-8 42-24 58-16 16-35 24-58 24l-274 0c-23 0-42-8-58-24-16-16-24-35-24-58l0-274c0-23 8-42 24-58 16-16 35-24 58-24l274 0c23 0 42 8 58 24 16 16 24 35 24 58z" /> </symbol> <symbol id="icon-github" viewBox="0 0 512 512"> <path d="m475 256c0 48-14 91-41 129-28 38-64 65-109 79-5 1-8 1-11-2-2-2-3-5-3-8l0-61c0-18-5-32-15-40 11-1 20-3 29-5 9-3 18-6 27-11 9-6 17-12 23-19 6-8 11-18 15-30 4-13 6-27 6-43 0-23-8-43-23-59 7-18 7-37-2-59-5-1-13 0-23 4-10 3-19 8-26 12l-11 7c-18-5-36-7-55-7-19 0-37 2-55 7-3-2-7-5-12-8-5-3-13-6-24-11-11-4-19-5-24-4-9 22-9 41-2 59-15 16-23 36-23 59 0 16 2 30 6 42 4 13 9 23 15 30 6 8 14 14 23 20 9 5 18 8 27 11 8 2 18 4 29 5-8 7-12 17-14 29-4 2-8 4-13 5-4 1-10 1-16 1-6 0-13-2-19-6-6-4-11-10-16-18-3-6-8-11-14-15-5-4-10-6-14-7l-5-1c-4 0-7 1-9 2-1 1-2 2-1 3 0 1 1 3 2 4 2 1 3 2 4 3l2 2c4 2 8 5 13 11 4 5 7 10 9 14l2 7c3 7 7 13 13 17 6 5 12 8 19 9 7 1 14 2 20 2 6 0 12 0 16-1l6-1c0 7 0 16 1 25 0 10 0 15 0 16 0 3-2 6-4 8-2 3-6 3-11 2-45-14-81-41-109-79-27-38-41-81-41-129 0-40 9-77 29-110 20-34 46-60 80-80 33-20 70-29 110-29 40 0 77 9 110 29 34 20 60 46 80 80 20 33 29 70 29 110z" /> </symbol> </svg> ) const Icons = props => { const data = useStaticQuery(graphql` query SocialQuery { site { siteMetadata { social { linkedin orcid github googlescholar } } } } `) const social = data.site.siteMetadata?.social let icons = [ { src: <Icon name="linkedin-square" {...props} />, link: `https://www.linkedin.com/in/${social?.linkedin}`, alt: "Click to read my Linkedin profile", }, { src: <Icon name="github" {...props} />, link: `https://www.github.com/${social?.github}`, alt: "Click to see my Github", }, { src: <Icon name="google-scholar" {...props} />, link: `https://scholar.google.com/citations?user=${social?.googlescholar}`, alt: "Click to see my citations on Google Scholar", }, { src: <Icon name="orcid" {...props} />, link: `https://www.orcid.org/${social?.orcid}`, alt: "Click to see my researcher profile on Orcid", }, ] return icons.map((icon, index) => ( <StyledSocialLi key={index}> <a href={icon.link} target="_blank" rel="noreferrer" alt={icon.alt} aria-label={icon.alt} > {icon.src} </a> </StyledSocialLi> )) } const Social = ({ size = 30, color = "black" }) => { return ( <StyledSocialList> <Icons size={size} color={color} /> </StyledSocialList> ) } export default Social
    
© www.soinside.com 2019 - 2024. All rights reserved.