Material UI 3.9.3 未在 IE 中设置复选框样式

Material UI 3.9.3 Checkbox Styles not being set in IE

我正在尝试使用 Material-UI v3.9.3's Checkbox 创建自定义同意复选框。

原因:自定义coz,要求是有特定的背景(Checkbox区域为白色)和前景(check icon为橙色)颜色。

到目前为止的实现: 我已经使用自定义实现了它 CSS。

index.js:

import React, { useState } from "react";
import { render } from "react-dom";
import Hello from "./Hello";
import Checkbox from "@material-ui/core/Checkbox";
import { withStyles, makeStyles } from "@material-ui/styles";

import "./style.css";

const useStyles =  makeStyles({
  checkbox: {
    padding: 0,
    width: 24,
    height: 24
  },
  icon: {
    borderRadius: 3,
    width: 24,
    height: 24,
    boxShadow: "inset 0 0 0 1px rgba(16,22,26,.2), inset 0 -1px 0 rgba(16,22,26,.1)",
    backgroundColor: "#ffffff",
    "input:hover ~ &": {
      backgroundColor: "#f5f8fa"
    },
    "input:disabled ~ &": {
      boxShadow: "none",
      background: "rgba(206,217,224,.5)"
    }
  },
  root: {
    background: "linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)",
    border: 0,
    borderRadius: 3,
    boxShadow: "0 3px 5px 2px rgba(255, 105, 135, .3)",
    color: "white",
    height: 48,
    padding: "0 30px"
  },
  checkedIcon: {
    borderRadius: 2,
    "&:before": {
      display: "block",
      width: 24,
      height: 24,
      backgroundImage:
        "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Crect width='23' height='23' x='.5' y='.5' fill='%23FFF' fill-rule='nonzero' stroke='%23999' rx='4'/%3E%3Ctext fill='%23F2410A' font-size='20' font-weight='bold'%3E%3Ctspan x='1' y='18'%3E✓%3C/tspan%3E%3C/text%3E%3C/g%3E%3C/svg%3E%0A\")",
      content: '""'
    },
    "input:hover ~ &": {
      backgroundColor: "#106ba3"
    }
  }
});

const App = props => {
  const classes = useStyles();
  const [consentGiven, setConsentGiven] = useState(false);
  const handleChange = event => {
    !consentGiven && setConsentGiven(true);
  };

  return (
    <div>
      <Checkbox
        className={classes.checkbox}
        checked={consentGiven}
        color="primary"
        onChange={handleChange}
        icon={<span className={classes.icon} />}
        checkedIcon={<span className={classes.checkedIcon} />}
        inputProps={{
          "aria-label": "primary checkbox"
        }}
      />
    </div>
  );
};

render(<App />, document.getElementById("root"));

index.html:

<div id="root"></div>

Here's a Sample StackBlitz with the minimal code required to reproduce the issue.

问题: 该解决方案似乎在 Chrome 中完美运行。但在 IE 中,一旦用户选中复选框,它就会消失。

预期行为:复选框一旦选中,应在 IE 上保持可见状态。

问题最初由 Alexey Zuev on Twitter here

在推特上回答

只是把它贴在这里并附上详细的解释,这样它可能会对某人有所帮助。正如 Alexey 在他的推文中提到的那样:

It's an issue with inlining svg into background css property in IE.

Just follow this answer Inline SVG in CSS and you will be able to fix the issue like here

At least it works in Edge :)

FIX

  1. 我去了 https://mothereff.in/url 并粘贴了 url 编码的 svg 字符串:

    输入:

    "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Crect width='23' height='23' x='.5' y='.5' fill='%23FFF' fill-rule='nonzero' stroke='%23999' rx='4'/%3E%3Ctext fill='%23F2410A' font-size='20' font-weight='bold'%3E%3Ctspan x='1' y='18'%3E✓%3C/tspan%3E%3C/text%3E%3C/g%3E%3C/svg%3E%0A\")"
    

    输出:

    "url(\"data:image/svg xml,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'><g fill='none' fill-rule='evenodd'><rect width='23' height='23' x='.5' y='.5' fill='#FFF' fill-rule='nonzero' stroke='#999' rx='4'/><text fill='#F2410A' font-size='20' font-weight='bold'><tspan x='1' y='18'>✓</tspan></text></g></svg>
    \")"
    
  2. 获取生成的 svg(从 <svg</svg>)并使用 btoa 将 svg 编码为 Base64。这样做时,您会收到一条错误消息:

    VM116:1 Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

    现在的原因是因为我们 svg 中的这个刻度符号 ()。因此,我们首先需要将其转换为 扩展特殊 HTML 代码 ,对于 符号,它是 &#10004; (Source)

  3. 现在我们有一个 svg 可以正确编码,如下所示:

    <svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'><g fill='none' fill-rule='evenodd'><rect width='23' height='23' x='.5' y='.5' fill='#FFF' fill-rule='nonzero' stroke='#999' rx='4'/><text fill='#F2410A' font-size='20' font-weight='bold'><tspan x='1' y='18'>&#10004;</tspan></text></g></svg>
    

    我们可以通过btoa传递它来生成一个Base64编码的字符串:

    const base64UrlString = btoa("<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'><g fill='none' fill-rule='evenodd'><rect width='23' height='23' x='.5' y='.5' fill='#FFF' fill-rule='nonzero' stroke='#999' rx='4'/><text fill='#F2410A' font-size='20' font-weight='bold'><tspan x='1' y='18'>&#10004;</tspan></text></g></svg>");
    
    console.log('Here is the generated Base64 Encoded String: ', base64UrlString);
    

  4. 最后,我们现在可以使用 Base64 编码字符串代替我们之前使用的内联 svg

    backgroundImage: "url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScyNCcgaGVpZ2h0PScyNCcgdmlld0JveD0nMCAwIDI0IDI0Jz48ZyBmaWxsPSdub25lJyBmaWxsLXJ1bGU9J2V2ZW5vZGQnPjxyZWN0IHdpZHRoPScyMycgaGVpZ2h0PScyMycgeD0nLjUnIHk9Jy41JyBmaWxsPScjRkZGJyBmaWxsLXJ1bGU9J25vbnplcm8nIHN0cm9rZT0nIzk5OScgcng9JzQnLz48dGV4dCBmaWxsPScjRjI0MTBBJyBmb250LXNpemU9JzIwJyBmb250LXdlaWdodD0nYm9sZCc+PHRzcGFuIHg9JzEnIHk9JzE4Jz7inJM8L3RzcGFuPjwvdGV4dD48L2c+PC9zdmc+\")",
    

    它也应该在 IE 中正确呈现。

Here's a Working Code Sample on StackBlitz for your ref.