Search code examples
javascriptreactjstypescriptsvgstyled-components

Using an SVG as a css background image on input range thumb


I am trying to use a custom background SVG for a range slider thumb in React using styled components. At the moment I am having trouble getting the SVG I have created to show. I have tested with other SVG's online and it works. Here is where I have got to thus far. It is in React with Typescript using styled-components

My compomnent styles:

const sliderThumbStyles = (props: any) => `
  width: 40px;
  height: 40px;
  border: 0; 
  background: url("data:image/svg+xml, SVG to go in here");
  border-radius: 20px;
  border: 5px solid white;
  cursor: pointer;
  margin-top: -18px
`;

const SliderWrapper = styled.div`
  .value {
    flex: 1;
    font-size: 2rem;
  }
  .slider {
    -webkit-appearance: none;
    appearance: none;

    &::-webkit-slider-thumb {
      -webkit-appearance: none;
      appearance: none;
      ${(props) => sliderThumbStyles(props)}
    }
    &::-moz-range-thumb {
      ${(props) => sliderThumbStyles(props)}
    }

    &::-webkit-slider-runnable-track {
      background: black;
      height: 3px;

      outline: none;
    }

    &::-moz-slider-track {
      background: black;
      height: 3px;
      outline: none;
    }
  }
`;

And here is my SVG file that is in ./src/assets/images/slider/slider-thumb.svg

<svg width="63" height="63" viewBox="0 0 63 63" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="5.05025" y="31.2134" width="37" height="37" rx="18.5" transform="rotate(-45 5.05025 31.2134)" fill="#FF9675" stroke="white" stroke-width="7"/>
<path d="M31.3357 40.8633L31.3357 22.0019" stroke="#1D1D1D" stroke-width="2" stroke-miterlimit="10"/>
<path d="M38.67 26.334C32.3829 26.334 31.335 18.999 31.335 18.999C31.335 18.999 30.2871 26.334 24 26.334" stroke="#1D1D1D" stroke-width="2" stroke-miterlimit="10" stroke-linejoin="bevel"/>
<path d="M38.67 35.5283C32.3829 35.5283 31.335 42.8633 31.335 42.8633C31.335 42.8633 30.2871 35.5283 24 35.5283" stroke="#1D1D1D" stroke-width="2" stroke-miterlimit="10" stroke-linejoin="bevel"/>
</svg>

When I try and import the SVg and include it in the css property inside sliderThumbStyles method it doesn't work. I have tried dropping the SVG markup in directly too and this doesn't work. As I said, it works when I dropped in a random SVG from the web so I think my SVG markup is wrong or I am importing it incorrecty. Can anyone point me to as to where I am going wrong? Thanks


Solution

  • I manage to use your svg as a thumbnail, but I had to

    • convert the double quotes to single quotes
    • remove all line breaks
    • encode the # with %23
    • ajust the width and heigth inside your svg tag to match the css

    .slider {
      -webkit-appearance: none;
      appearance: none;
      width: 100%;
      height: 10px;
      background: #d3d3d3;
    }
    
    .slider::-webkit-slider-thumb {
      -webkit-appearance: none;
      appearance: none;
      width: 40px;
      height: 40px;
      border: 0;
      background: url("data:image/svg+xml,<svg width='40' height='40' viewBox='0 0 63 63' fill='none' xmlns='http://www.w3.org/2000/svg'><rect x='5.05025' y='31.2134' width='37' height='37' rx='18.5' transform='rotate(-45 5.05025 31.2134)' fill='%23FF9675' stroke='white' stroke-width='7'/><path d='M31.3357 40.8633L31.3357 22.0019' stroke='%231D1D1D' stroke-width='2' stroke-miterlimit='10'/><path d='M38.67 26.334C32.3829 26.334 31.335 18.999 31.335 18.999C31.335 18.999 30.2871 26.334 24 26.334' stroke='%231D1D1D' stroke-width='2' stroke-miterlimit='10' stroke-linejoin='bevel'/><path d='M38.67 35.5283C32.3829 35.5283 31.335 42.8633 31.335 42.8633C31.335 42.8633 30.2871 35.5283 24 35.5283' stroke='%231D1D1D' stroke-width='2' stroke-miterlimit='10' stroke-linejoin='bevel'/></svg>");
      cursor: pointer;
    }
    <input type="range" min="1" max="100" value="50" class="slider">