3

I am trying to use regex to query all of the attributes inside of a CSS file. My end goal is to be able to take a css file like this:

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}

and return a list of selectors like this:

margin, padding, border, font-size, font, vertical-align, display, list-style, quotes, content, border-collapse, border-spacing

The first step is to create a regular expression than only matches all of the attributes in the css file, and only those that are not selectors (ie. a:hover) or inside of comments.

Right now all I have is /(?:([\w\d\S\-\_]+)\:)/g, which works, but still queries selectors and text inside of comments.

3
  • "and return a list of selectors like this:" Is requirement to return properties set at css ? Commented Jan 12, 2016 at 16:14
  • You could first filter out the comments, and then run your regex Commented Jan 12, 2016 at 16:14
  • @guest271314 no I just want to return the attributes themselves. margin <- this and not this -> margin: 0; Commented Jan 12, 2016 at 16:17

2 Answers 2

2

Try using String.prototype.replace() with RegExp /\/\*.*\*\/|(-moz-|-ms-|-o-|-webkit-)+\w+(?=:)/g to match , remove comment text , vendor prefixes ; String.prototype.match() with RegExp /[a-z-]+(?=:[^before|after|hover])/ig to match characters "a" through "z" or "-" case insensitive, followed by ":" , not followed by "before" or "after"

var style = document.querySelector("style");
var props = style.textContent
            // remove comments, vendor prefixes
            .replace(/\/\*.*\*\/|(-moz-|-ms-|-o-|-webkit-)+\w+(?=:)/g,"")
            // negate `:hover`
            .match(/[a-z-]+(?=:[^before|after|hover])/ig);
console.log(props)
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    /* duplicate `content` property here */
    /* content: none; */
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}

table:hover {
  color:blue;
  -moz-animation: name 1s;
}

Sign up to request clarification or add additional context in comments.

3 Comments

This is good, but I actually need it to do a couple more things. As it is right now this code will still match on :hover and other selectors as well as some special selectors like [href^='https']. Here is a full example of the stylesheet I'm matching on regexr.com/3cih2. I'd also like to have it not match browser-prefix attributes like -moz-*
Maybe I was wrong on that one. I know there was one selector that was returning a false positive, but I can't remember where
@mascaliente "I know there was one selector that was returning a false positive, but I can't remember where" ? Same link regexr.com/3cih2 ? Tried js at updated post ?
2

You may not need regular expressions for this.

You can access the stylesheet with JavaScript, then iterate over the stylesheet's cssRules object and split each declaration at ; then split each property/value pair at the : character.

It's worth pointing out that this method will expand the shorthand properties since the cssText property consists of the computed properties/values.

function getPropertiesFromStylesheet(stylsheetIndex) {
  var stylesheet = document.styleSheets[stylsheetIndex],
    rules = stylesheet.cssRules,
    properties = [];

  if (stylesheet) {
    Object.keys(rules).forEach(function(key) {
      rules[key].style.cssText.split(';').forEach(function(declaration) {
        if (declaration) {
          properties.push(declaration.split(':')[0].trim());
        }
      });
    });
  }

  return properties;
}

document.body.textContent = getPropertiesFromStylesheet(0);
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}

2 Comments

This is nice, but requires browser javascript. This is actually a node.js script
@mascaliente - so then edit your question to include the relevant tag and avoid wasting anyone else's time. :thumbs-down:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.