Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional parameter to prefix all IDs within SVG to avoid clashes #22

Merged
merged 3 commits into from
Jul 16, 2024

Conversation

bekahmcdonald
Copy link
Contributor

Purpose

Provide a way to prevent clashes between IDs used in SVGs.

The problem it solves

When an SVG is used more than once on a page, any IDs used within in the SVG will not be unique. This can cause problems when an SVG is relying on an ID (eg. for a clip-path or linear-gradient), as it can be referencing the wrong one. (Particularly a problem when you're animating SVGs!)

ID clashes often occur across multiple SVGs too, particularly when the IDs used are vague (eg. id="gradient1") or have been exported from another tool (eg. id="Layer1").

The solution

I've added another parameter to the @svg directive called $id_prefix. It allows the developer to provide a string that will be prefixed to all the IDs used within the SVG.

Usage and example

You may be using the same logo in the header and footer of the site. If the logo relies on an ID (eg. for a linear-gradient), there will be an ID clash. To get around this, you'd just pass different prefixes to the directive.

@svg('images.logo', 'w-32', ['aria-label' => 'Logo'], 'header-logo')

A detailed example

Without providing an ID prefix, my SVG markup looks like this. (This SVG was exported from Illustrator, and run manually through SVGOMG which simplified the ID to just a – optimised, but not super helpful...

<svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <defs>
    <linearGradient id="a" x1="0" x2="100" y1="50" y2="50" gradientUnits="userSpaceOnUse">
      <stop offset="0" stop-color="#b6ff2a" />
      <stop offset=".995" stop-color="#0097ff" />
    </linearGradient>
  </defs>
  <path fill="url(#a)"
    d="M50 0C22.386 0 0 22.386 0 50s22.386 50 50 50 50-22.386 50-50S77.614 0 50 0Zm0 92.148C26.722 92.148 7.852 73.278 7.852 50S26.722 7.852 50 7.852 92.148 26.722 92.148 50 73.278 92.148 50 92.148Z"/>
</svg>
@svg('images.logo', 'w-32', ['aria-label' => 'Logo'], 'header-logo')

Passing an $id_prefix parameter to the @svg directive turns my SVG's unhelpful ID of a into the more specific header-logo-a, both where it's declared on the linearGradient in defs and where it's referenced as the fill on the path.

<svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <defs>
    <linearGradient id="header-logo-a" x1="0" x2="100" y1="50" y2="50" gradientUnits="userSpaceOnUse">
      <stop offset="0" stop-color="#b6ff2a" />
      <stop offset=".995" stop-color="#0097ff" />
    </linearGradient>
  </defs>
  <path fill="url(#header-logo-a)"
    d="M50 0C22.386 0 0 22.386 0 50s22.386 50 50 50 50-22.386 50-50S77.614 0 50 0Zm0 92.148C26.722 92.148 7.852 73.278 7.852 50S26.722 7.852 50 7.852 92.148 26.722 92.148 50 73.278 92.148 50 92.148Z"/>
</svg>

tldr;

With the addition of an $id_prefix parameter to the @svg directive, the developer is back in control of how unique an SVG's IDs are, even if that SVG is stored in the CMS.

@Log1x
Copy link
Owner

Log1x commented Jan 4, 2024

This sounds good!

I changed your implementation slightly to instead be passed as an options array like ['idPrefix' => 'example-'] that way if there is more functionality that gets added down the road, the function doesn't start getting overloaded or introduce breaking changes.

Let me know if that's ok and that everything is still working and I can get this merged.

Thanks!

@bekahmcdonald
Copy link
Contributor Author

I realised I committed without the vital part of the preg_replace replacement pattern... I've added it back in! It's all working now.

The options array makes sense, thanks for changing that. This is such a helpful package for me, and it's nice to be able to contribute!

@Log1x Log1x merged commit 98ca9fb into Log1x:master Jul 16, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants