DEV Community

Cover image for Enabling inline CSS for pseudo classes
Dara
Dara

Posted on

Enabling inline CSS for pseudo classes

People have often asked how they may write inline styles for pseudo classes. E.g.,

<a href="#" style=":hover: background: blue; :hover: color: white;">Hover Here</a>
Enter fullscreen mode Exit fullscreen mode

So I got curious about what it'd take to make it happen. The most obvious solution was to use JavaScript to check for pseudo classes in an element's inline CSS. And then create an embedded stylesheet for any inline styles that have been detected.

I eventually landed on

const pseudoInlineStyles = {
  enable: function (options) {
    const defaultPseudoStyleTypes = ['active', 'focus', 'hover', 'visited', 'after', 'before', 'selected', 'first-child'];
    const pseudoStyleTypes = options?.pseudoStyleTypes ? [...defaultPseudoStyleTypes, ...options.pseudoStyleTypes] : defaultPseudoStyleTypes;

    const cssRules = [];

    // Iterate through the pseudo style types
    pseudoStyleTypes.forEach((pseudoStyleType) => {
      // Find elements with the specified pseudo style
      const elementsWithPseudoStyle = document.querySelectorAll(`[style*="${pseudoStyleType}"]`);

      // Loop through matching elements
      elementsWithPseudoStyle.forEach((element) => {
        const elementName = element.tagName.toLowerCase();
        const elementId = element.id ? `#${element.id}` : '';
        const elementClasses = element.className ? `.${element.className.split(' ').join('.')}` : '';
        const elementSelector = `${elementName}${elementId}${elementClasses}`;

        // Extract the inline style for the pseudo-class
        const elementInlineStyle = element.getAttribute('style');
        const pseudoStyleRegex = new RegExp(`:${pseudoStyleType}:(.*?);`, 'gi');
        // Match the pseudo style definition
        const pseudoStyleMatches = elementInlineStyle.match(pseudoStyleRegex);

        if (pseudoStyleMatches) {
          // Loop through the matches
          pseudoStyleMatches.forEach((pseudoStyleMatch) => {
            // Extract the pseudo style definition
            const pseudoStyleDefinition = pseudoStyleMatch.replace(`:${pseudoStyleType}:`, '');
            // Create the CSS rule
            const cssRuleForPseudoStyle = `${elementSelector}:${pseudoStyleType} { ${pseudoStyleDefinition.trim()}; }`;
            cssRules.push(cssRuleForPseudoStyle);
          });
        }
      });
    });

    // Insert all the collected CSS rules into a style element
    if (cssRules.length > 0) {
      const styleSheet = document.getElementById('pseudo-inline-css');
      if (styleSheet) {
        styleSheet.innerHTML = cssRules.join('\n');
      } else {
        const newStyleSheet = document.createElement('style');
        newStyleSheet.id = 'pseudo-inline-css';
        newStyleSheet.innerHTML = cssRules.join('\n');
        document.head.appendChild(newStyleSheet);
      }
    }
  },
};
Enter fullscreen mode Exit fullscreen mode

And that allowed me write

<html lang="en">
  <head>
    <script src="https://cdn.jsdelivr.net/gh/dara-tobi/pseudo-inline-styles@1.0.1/src/pseudo-inline-styles.js"></script>
    <title>PseudoInlineStyles Demo</title>
  </head>
  <body>

    <a href="#" id="primary-link" class="button large" style="
      :after: content: ' SOFTWARE';
      :focus: text-decoration: underline !important;
      :hover: background-color: red !important;
      :hover: color: black !important;
      text-decoration: none;
      color:white;
      background-color: #005493;
      font-size: 1.5rem;
      text-align: center;
      padding: 20px;">12 HANDS </a>

    <script>pseudoInlineStyles.enable({pseudoStyleTypes: ['focus-within', 'last-child']});</script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

If you're curious to see a live demo, check it out here.

And if you want to take it for a spin, check out the Github repo.

Caveats of using this approach are

i. for each inline pseudo class, you get an Unknown property name error when inspecting the element's styles in dev tools.

Screenshot of unknown-property-name errors that show up when inspecting the styles of an element with inline pseudo classes

ii. you get squiggly lines in your code editor because this isn't the standard syntax for writing inline styles.

Screenshot of VS Code showing squiggly lines under the inline pseudo classes

Top comments (0)