svg

Where two M ... Z sequences meet, the background color shows through


I have a very straightforward svg path here, but for some reason, certain parts have the background color when they should be black. It's a short, well-defined input, and a short, well-defined output. Does anyone know why that should be the output?

I have put a colored dot at each vertex, for clarity.

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <svg width="214" height="317" viewBox="0 0 214 317" xmlns="http://www.w3.org/2000/svg">
        <path d="M 199 317 L 107 32.5 L 14.5 317 L 0 317 L 105 0 L 109 0 L 214 317 L 199 317 Z 
                 M 166 199 L 44.5 199 L 41.5 211 L 170.5 211 Z" />
        <!-- The 2nd M...Z is the horizontal piece. -->
        <circle cx="166" cy="199" r="2" fill="red" stroke="none" />
        <circle cx="44.5" cy="199" r="2" fill="green" stroke="none" />
        <circle cx="41.5" cy="211" r="2" fill="blue" stroke="none" />
        <circle cx="170.5" cy="211" r="2" fill="yellow" stroke="none" />
    </svg>
</body>
</html>

Here is a large capital A.  Where the crosspiece meets the slanting sides, this is a white area.


Solution

  • Change the order of your points in the second part of your d attribute in your <path> element:

    <svg width="214" height="317" viewBox="0 0 214 317" xmlns="http://www.w3.org/2000/svg">
        <path d="M 199 317 L 107 32.5 L 14.5 317 L 0 317 L 105 0 L 109 0 L 214 317 L 199 317 Z 
                 M 166 199 L 170.5 211 L 41.5 211 L 44.5 199 Z" />
        <!-- The 2nd M...Z is the horizontal piece. -->
        <circle cx="166" cy="199" r="2" fill="red" stroke="none" />
        <circle cx="44.5" cy="199" r="2" fill="green" stroke="none" />
        <circle cx="41.5" cy="211" r="2" fill="blue" stroke="none" />
        <circle cx="170.5" cy="211" r="2" fill="yellow" stroke="none" />
    </svg>

    With this changed order of points you can observe the effect of the fill-rule attribute. The default value here is "nonzero", but if you change that to "evenodd" you will be getting your original appearance again:

    <svg width="214" height="317" viewBox="0 0 214 317" xmlns="http://www.w3.org/2000/svg">
        <path fill-rule="evenodd" d="M 199 317 L 107 32.5 L 14.5 317 L 0 317 L 105 0 L 109 0 L 214 317 L 199 317 Z 
                 M 166 199 L 170.5 211 L 41.5 211 L 44.5 199 Z" />
        <!-- The 2nd M...Z is the horizontal piece. -->
        <circle cx="166" cy="199" r="2" fill="red" stroke="none" />
        <circle cx="44.5" cy="199" r="2" fill="green" stroke="none" />
        <circle cx="41.5" cy="211" r="2" fill="blue" stroke="none" />
        <circle cx="170.5" cy="211" r="2" fill="yellow" stroke="none" />
    </svg>