CSS Object Model implemented in pure JavaScript. It's also a parser!

Overview

CSSOM

CSSOM.js is a CSS parser written in pure JavaScript. It is also a partial implementation of CSS Object Model.

CSSOM.parse("body {color: black}")
-> {
  cssRules: [
    {
      selectorText: "body",
      style: {
        0: "color",
        color: "black",
        length: 1
      }
    }
  ]
}

Parser demo

Works well in Google Chrome 6+, Safari 5+, Firefox 3.6+, Opera 10.63+. Doesn't work in IE < 9 because of unsupported getters/setters.

To use CSSOM.js in the browser you might want to build a one-file version that exposes a single CSSOM global variable:

➤ git clone https://github.com/NV/CSSOM.git
➤ cd CSSOM
➤ node build.js
build/CSSOM.js is done

To use it with Node.js or any other CommonJS loader:

➤ npm install cssom

Don’t use it if...

You parse CSS to mungle, minify or reformat code like this:

div {
  background: gray;
  background: linear-gradient(to bottom, white 0%, black 100%);
}

This pattern is often used to give browsers that don’t understand linear gradients a fallback solution (e.g. gray color in the example). In CSSOM, background: gray gets overwritten. It does NOT get preserved.

If you do CSS mungling, minification, or image inlining, considere using one of the following:

Tests

To run tests locally:

➤ git submodule init
➤ git submodule update

Who uses CSSOM.js

Comments
  • Crossbrowser version?

    Crossbrowser version?

    If someone needs a crossbrowser version of CSSOM.js please describe what are you intend to do with that. It is possible to remove all these __proto__ and Object.defineProperty, but I don't feel the need right now.

    discuss 
    opened by NV 10
  • @import support

    @import support

    @import url("partial.css");
    @import url("http://usercss.ru/styles/night/night.css");
    

    Spec. WebKit implementation: CSSImportRule.cpp.

    v0.4 
    opened by NV 9
  • b2507c6 regression: Quoted CSS values don't parse anymore

    b2507c6 regression: Quoted CSS values don't parse anymore

    This used to work fine before b2507c6:

    cssom.parse('body{-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";}');
    cssom.parse('body{font-family: "times new roman";}');
    
    opened by papandreou 8
  • Parser generator?

    Parser generator?

    It seems feasible to use some parser generator and reuse WebKit's stuff http://svn.webkit.org/repository/webkit/trunk/WebCore/css/tokenizer.flex http://svn.webkit.org/repository/webkit/trunk/WebCore/css/CSSGrammar.y

    Never did it before. Any pointers?

    discuss 
    opened by NV 8
  • CSSStyleSheet.toString()

    CSSStyleSheet.toString()

    Ability to serialize CSSStyleSheet object into CSS string.

    CSSOM.parse("body {color: black}").toString()
    -> "body {color: black}"
    

    It might need a few options, such as indent or propertiesSeparator. Not sure about it yet.

    opened by NV 7
  • Improve error information about parse errors

    Improve error information about parse errors

    I've tried improving on the details of the error messages that CSSOM will throw.

    The changes try to do the following:

    • Throw new Error instead of strings
    • Keep track of line and char numbers (1-indexed to match most editors)
    • Write line and chars numbers in error.message
    • Add line and char numbers to error as properties
    • Added the stylesheet in the state of parsing that it was in when the error occurred

    I've changed the one thrown SyntexError with Error, since the SyntaxError seems to be reserved for node internals during failed eval().

    opened by Munter 6
  • Fix multiple declarations of the same property

    Fix multiple declarations of the same property

    This simple fix merges properties already declared in the style into a single property as a semicolon-delimited list. For example:

    .background-gradient {
        background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#1a82f7), to(#2F2727));
        background: -webkit-linear-gradient(top, #2F2727, #1a82f7); 
        background: -moz-linear-gradient(top, #2F2727, #1a82f7); 
        background: -ms-linear-gradient(top, #2F2727, #1a82f7); 
        background: -o-linear-gradient(top, #2F2727, #1a82f7)
    }
    

    would result in:

    cssRules: [
        {
            selectorText: '.background-gradient',
            parentRule: null,
            style: {
                0: 'background',
                background: '-webkit-gradient(linear, 0% 0%, 0% 100%, from(#1a82f7), to(#2F2727)); background: -webkit-linear-gradient(top, #2F2727, #1a82f7); background: -moz-linear-gradient(top, #2F2727, #1a82f7); background: -ms-linear-gradient(top, #2F2727, #1a82f7); background: -o-linear-gradient(top, #2F2727, #1a82f7)',
                length: 1
            }
        }
    ]
    

    This allows the declarations to be preserved as well as correctly parsed, and it will be overwritten if a more specific selector redefines the property. A downside to this implementation is that it does not give individual access to each rule. But since this didn't work to begin with I don't see it as a problem.

    opened by straker 5
  • Add CSSGroupingRule and CSSConditionRule

    Add CSSGroupingRule and CSSConditionRule

    This change adds the CSSGroupingRule and CSSConditionRule constructors, and it establishes the prototype chain between these and CSSMediaRule and CSSSupportsRule.

    For the updated functionality, it includes references to the appropriate specifications, and I did my best to keep the coding style in sync with the existing project. For instance, I preserved the styling where tabs are currently intermixed with spaces in CSSMediaRule.js, and I preserved the strategy of using new CSSOM.CSS... over Object.create (which is done to support for Firefox 3.6, perhaps?).

    For the tests, I verified that, while one test is failing from the current main branch, all the other tests are still passing after this change. I included a comment similar to others for a currently untestable getter.

    Resolves #105

    opened by jonathantneal 4
  • CSSFontFaceRule is missing from npm package exports

    CSSFontFaceRule is missing from npm package exports

    versions 0.3.2 and 0.3.3 are missing CSSFontFaceRule from exports. I couldn't find it in the source code, as tags for these versions don't exists.

    For reference, here's the contents of index.js for v0.3.3:

    exports.CSSStyleDeclaration = require("./CSSStyleDeclaration").CSSStyleDeclaration;
    exports.CSSRule = require("./CSSRule").CSSRule;
    exports.CSSStyleRule = require("./CSSStyleRule").CSSStyleRule;
    exports.CSSImportRule = require("./CSSImportRule").CSSImportRule;
    exports.MediaList = require("./MediaList").MediaList;
    exports.CSSMediaRule = require("./CSSMediaRule").CSSMediaRule;
    exports.StyleSheet = require("./StyleSheet").StyleSheet;
    exports.CSSStyleSheet = require("./CSSStyleSheet").CSSStyleSheet;
    exports.parse = require("./parse").parse;
    exports.clone = require("./clone").clone;
    
    opened by amitzur 4
  • should not remove spaces in calc() function

    should not remove spaces in calc() function

    Spaces are mandatory inside CSS calc() function, and should not be removed in inlining.

    .foo {
      width: calc(100% - 80px);
    }
    

    gets parsed to this

    .foo {width: calc(100%-80px);}
    

    and that doesn't work in the browser.

    linear-gradient also has the same issue.

    linear-gradient(135deg, #00689b 0%, #00375a 90%, #00375a 90%, #003455 100%);

    gets parsed to this

    linear-gradient(135deg, #00689b0%, #00375a90%, #00375a90%, #003455100%);

    opened by jonkemp 4
  • W3C

    W3C "transform" style doesn't work

    To replicate, create an element and do the following with it:

    const domElement = document.createElement('div');
    
    domElement.style.transform = 'translate3d(0px, 0px, 0px)';
    
    assert(domElement.style.transform === 'translate3d(0px, 0px, 0px)'); // undefined
    

    I can only get it to work if I use this specific pattern:

    const domElement = document.createElement('div');
    
    domElement.style['webkit-transform'] = 'translate3d(0px, 0px, 0px)';
    
    assert(domElement.style.WebkitTransform === 'translate3d(0px, 0px, 0px)');
    

    X-issue from https://github.com/tmpvar/jsdom/issues/1321

    opened by probablyup 4
  • Security Policy

    Security Policy

    Hello,

    Can you please add a Security Policy and describe what sort of vulnerabilities you consider valid for this library? I have found a few issues that could be pertinent depending on what you consider a vulnerability.

    Thanks, Carter Snook

    opened by sno2 0
  • Expose `parse` to `CSSGroupingRule`

    Expose `parse` to `CSSGroupingRule`

    CSSGroupingRule.insertRule requires parse. Previously:

    $ pwd
    /path/to/CSSOM
    $ node
    Welcome to Node.js v18.1.0.
    Type ".help" for more information.
    > const CSSOM = require('./lib');
    undefined
    > const rule = new CSSOM.CSSGroupingRule();
    undefined
    > rule.insertRule('#a{}', 0);
    Uncaught TypeError: CSSOM.parse is not a function
        at CSSGroupingRule.insertRule (/path/to/CSSOM/lib/CSSGroupingRule.js:41:22)
    

    Now:

    > rule.insertRule('#a{}', 0);
    0
    
    opened by MrDOS 1
  • Expose CSSOM.parse to CSSGroupingRule

    Expose CSSOM.parse to CSSGroupingRule

    Currently CSSGroupingRule is calling CSSOM.parse but parse wasn't included which leads to a syntax error. This PR fixes that

    Line which is currently calling CSSOM.parse: https://github.com/NV/CSSOM/blob/a469aae2f92e454e669aec821781626924f98d17/lib/CSSGroupingRule.js#L41

    opened by Juice10 3
  • "font-size" not accessible

    Hi, thanks for this library.

    I'm trying to access "font-size" on a CSSStyleDeclaration object like I would on the browser using .fontSize but apparently it is only accessible using ["font-size"]... I think this applies to all dashed properties, is this intended?

    opened by Kal-Aster 0
  • parseError on @media print {

    parseError on @media print {

    const cssom = require("cssom"); //version 0.4.4
    
    const styles = `@-moz-document url-prefix(){@media print{.enabled-vuetify-global-styling .v-application,.enabled-vuetify-global-styling .v-application--wrap{display:block}}}`;
    
    cssom.parse(styles);
    

    throws

    Uncaught Error: Unexpected } (line 1, char 157)
        at parseError (/Users/przemyslawbeigert/code/bethink/wnl-platform/node_modules/cssom/lib/parse.js:62:15)
        at Object.parse (/Users/przemyslawbeigert/code/bethink/wnl-platform/node_modules/cssom/lib/parse.js:386:7) {
      line: 1,
      char: 157,
      styleSheet: CSSStyleSheet {
        parentStyleSheet: null,
        cssRules: [ [CSSMediaRule] ]
      }
    }
    
    opened by przemyslawjanpietrzak 0
  • Error: Could not parse CSS stylesheet

    Error: Could not parse CSS stylesheet

    Screen Shot 2021-01-01 at 9 31 22 PM

    cssom is installed with version "0.4.4" and is a dependency for jsdom at ^0.4.4

    Followed this thread when this was an issue at version 0.3.2 with no avail

    opened by nhidtran 1
Releases(v0.3.0)
  • v0.3.0(Nov 9, 2013)

    • Allow \' and \" escape sequences in strings, albeit not full escape sequence support.
    • Support IE expression() values (#45).
    • Support @-moz-document (#47).
    • Fix some issues in older Firefox and IE browsers.
    • Correctly set parentStyleSheet on rules added via insertRules.
    • Fix package.json jake version to be modern.
    Source code(tar.gz)
    Source code(zip)
Owner
Nikita Vasilyev
Developer Tools developer. I work on WebKit Inspector at .
Nikita Vasilyev
CSS parser with support of preprocessors

Gonzales PE @dev Gonzales PE is a CSS parser which plays nicely with preprocessors. Currently those are supported: SCSS, Sass, LESS. Try out Gonzales

Tony Ganch 322 Dec 10, 2022
A decent CSS parser.

mensch A decent CSS parser. usage npm install mensch var mensch = require('mensch'); var ast = mensch.parse('p { color: black; }'); var css = mensch.

Brett Stimmerman 112 Sep 24, 2022
Plugin framework for CSS preprocessing in Node.js

rework CSS manipulations built on css, allowing you to automate vendor prefixing, create your own properties, inline images, anything you can imagine!

rework 2.8k Dec 6, 2022
Modern CSS to all browsers

stylecow: modern CSS for all browser Node library to fix your css code and make it compatible with all browsers. Created by Óscar Otero. License: MIT

stylecow 155 Dec 21, 2022
Collection of parsers written in JavaScript

CSS Parser Introduction The ParserLib CSS parser is a CSS3 SAX-inspired parser written in JavaScript. It handles standard CSS syntax as well as valida

null 284 Dec 16, 2022
Node.js object hash library with properties/arrays sorting to provide constant hashes. It also provides a method that returns sorted object strings that can be used for object comparison without hashes.

node-object-hash Tiny and fast node.js object hash library with properties/arrays sorting to provide constant hashes. It also provides a method that r

Alexander 73 Oct 7, 2022
Json-parser - A parser for json-objects without dependencies

Json Parser This is a experimental tool that I create for educational purposes, it's based in the jq works With this tool you can parse json-like stri

Gabriel Guerra 1 Jan 3, 2022
Simple and Extensible Markdown Parser for Svelte, however its simplicity can be extended to any framework.

svelte-simple-markdown This is a fork of Simple-Markdown, modified to target Svelte, however due to separating the parsing and outputting steps, it ca

Dave Caruso 3 May 22, 2022
It's a repository to studies. Its idea is to learn about Nx and its plugins.

StudyingNx This project was generated using Nx. ?? Smart, Fast and Extensible Build System Adding capabilities to your workspace Nx supports many plug

Open-ish 4 May 13, 2022
Can see everything, beware of its omniscience, kneel before its greatness.

Can see everything, beware of its omniscience, kneel before its greatness. Summary Presentation Installation Removing Credits Presentation Main goal T

Duc Justin 3 Sep 30, 2022
Seamless and lightweight parallax scrolling library implemented in pure JavaScript utilizing Hardware acceleration for extra performance.

parallax-vanilla.js Seamless and lightweight parallax scrolling library implemented in pure JavaScript utilizing Hardware acceleration for extra perfo

Erik Engervall 91 Dec 16, 2022
A single-page application that allows users to keep track of their books. Users can add the book details (book title and author) and also, and the books can also be removed. Built with JavaScript, HTML, and CSS

Project Name Awesome book with ES6 Description the project. This is a single page application that allows users to keep track of their books. Users ca

Micheal Oguntayo 4 Oct 13, 2022
Serialize and deserialize any object and all of its references 🥣

Super Cereal ?? Serialize and deserialize any object and all of its references. Supports: Class (with inheritance set-up) Object Array Function Map Se

Seb Ringrose 9 Dec 24, 2022
Serialize and deserialize any object and all of its references 🥣

Super Cereal ?? Serialize and deserialize any object and all of its references. Supports: Class (with inheritance set-up) Object Array Function Map Se

Seb Ringrose 5 Nov 1, 2022
This Login Form made using React hooks , React Js , Css, Json. This form have 3 inputs, it also validate those inputs & it also having length limitations.

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Yogesh Sharma 0 Jan 3, 2022
The app helps you to add todo items to your list, mark completed ones and also delete finished items. Its a handy tool for your day today activies. Check out the live demo.

Todo List App The app helps you to add todo items to your list, mark completed ones and also delete finished items. Its a handy tool for your day toda

Atugonza ( Billions ) Joel 14 Apr 22, 2022
Types generator will help user to create TS types from JSON. Just paste your single object JSON the Types generator will auto-generate the interfaces for you. You can give a name for the root object

Types generator Types generator is a utility tool that will help User to create TS Interfaces from JSON. All you have to do is paste your single objec

Vineeth.TR 16 Dec 6, 2022
Simple Library implemented using HTML, CSS and JavaScript. This is a simple implementation of JavaScript Modules of ES6.

Awesome-books A single page project with the porpuse of storing books' titles and authors. Built With CSS, HTML & Javascript. How to run in your local

Saadat Ali 7 Feb 21, 2022