Go to homepage

← All articles Last edited:

SVG Interactive Icons

We just shipped Nucleo v3.1.6, which includes a new way to manage two-state icons (a.k.a., interactive icons). We also updated all the interactive icons and created new ones.

In the previous version, the animation was created as a <script> in the SVG code. Now, we create the animation in CSS. JavaScript is used to toggle the CSS class on click.

The main advantage is that you can create your own interactive icons with ease. We'll also convert them into Vue/JSX after you import them in Nucleo.

👋 First time here? Meet Nucleo, the icon manager for Mac/Windows. Download →

Here's a preview of all the interactive icons:

preview of all interactive icons
Interactive icons preview

The interactive icons are marked with a 'play' icon in the Nucleo application. To trigger the animation, click to select the icon.

click to animate
Click to animate

Using the icon context menu, you can copy the SVG/Vue/JXS code of the animated icon and paste it into your project.

copy using the context menu
Copy the icon using the context menu

The animation is created in CSS, in a <style> element inside the SVG code. The icon content is wrapped inside a group <g> element, to which we apply the icon class name (that changes for each icon) and the js-nc-int-icon class (same for all icons).

The script is used to toggle the nc-int-icon-state-b class, used to animate the icon (state 'B' of the animation). To create your own animated icons, use the template below as a starting point:

<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
  <g class="icon-class-name js-nc-int-icon">
    <line x1="30" y1="9" x2="2" y2="9" fill="none" stroke="#444" stroke-linecap="square" stroke-miterlimit="10" stroke-width="2"/>
    <!-- ... -->
  </g>

  <style>
    .icon-class-name {}
    .icon-class-name.nc-int-icon-state-b {}
  </style>

  <script>
    function initIntIcon(icon) {
      if(icon.classList.contains('js-nc-int-icon-loaded')) return;
      icon.classList.add('js-nc-int-icon-loaded');
      var svg = icon.closest('svg');
      svg.addEventListener('click', function(event) {
        icon.classList.toggle('nc-int-icon-state-b');
      });
    }
    var intIcons = document.getElementsByClassName('js-nc-int-icon');
    for(var i = 0; intIcons.length > i ; i++) {
      initIntIcon(intIcons[i]);
    }
  </script>
</svg>

For example, here's the full code of the animated checkbox:

<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
  <g class="nc-int-input-checkbox js-nc-int-icon">
    <rect width="16" height="16" rx="4" fill="#c8c8c8"/>
    <polyline points="3 8.5 6 11.5 13 4.5" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
  </g>

  <style>
    .nc-int-input-checkbox {
      --transition-duration: 0.3s;
    }

    .nc-int-input-checkbox *:last-child {
      stroke-dasharray: 15;
      stroke-dashoffset: 15;
    }

    .nc-int-input-checkbox.nc-int-icon-state-b *:first-child {
      fill: #3b57e8;
      transition: fill var(--transition-duration);
    }

    .nc-int-input-checkbox.nc-int-icon-state-b *:last-child {
      stroke-dashoffset: 0;
      transition: stroke-dashoffset var(--transition-duration) cubic-bezier(0.17,0.84,0.44,1);
    }
  </style>

  <script>
    function initIntIcon(icon) {
      if(icon.classList.contains('js-nc-int-icon-loaded')) return;
      icon.classList.add('js-nc-int-icon-loaded');
      var svg = icon.closest('svg');
      svg.addEventListener('click', function(event) {
        icon.classList.toggle('nc-int-icon-state-b');
      });
    }
    var intIcons = document.getElementsByClassName('js-nc-int-icon');
    for(var i = 0; intIcons.length > i ; i++) {
      initIntIcon(intIcons[i]);
    }
  </script>
</svg>

Once the icon is uploaded in Nucleo, the app automatically generates a Vue/JSX version that you can copy using the icon context menu.

Preview of the Nucleo icons

Cookie Compliance

We use cookies to give you the best possible website experience. Learn more.