macbre / analyze-css Goto Github PK
View Code? Open in Web Editor NEWCSS selectors complexity and performance analyzer
Home Page: https://www.npmjs.com/package/analyze-css
License: BSD 2-Clause "Simplified" License
CSS selectors complexity and performance analyzer
Home Page: https://www.npmjs.com/package/analyze-css
License: BSD 2-Clause "Simplified" License
$ analyze-css --url http://example.a
{ [Error: getaddrinfo ENOTFOUND] code: 'ENOTFOUND', errno: 'ENOTFOUND', syscall: 'getaddrinfo' }
$ analyze-css --url http://example.com
Error: missing '{' near line 51:1
Introduce oldPropertyPrefix
metric that counts uses of outdated CSS properties browser-specific prefixes:
See http://www.w3schools.com/cssref/css3_browsersupport.asp
Might take the approach of https://github.com/ai/autoprefixer and use the Can I Use JSON file - @nschonni
"Moved" from macbre/phantomas#111
Add duplicatedSelectors
metric
Inspired by Parker - @katiefenn
I tried on different css files and I can't find any colors count.
Can you check if it works for you?
This package has node-sass
listed as a dependency (version 1.1.2).
Version 1.1.2 of node-sass has a pretty major bug that prevents some users from installing it. For me, it freezes my computer by consuming all my RAM. Therefore, I cannot install the analyze-css
package since it requires [email protected]
If the dependency version could be updated, that would probably fix the problem. npm view node-sass
shows the latest 1.x version as 1.2.3
, and the very latest version as 3.0.0-alpha.0
.
I don't know if this would break compatibility with the analyze-css package. Are there unit tests that would catch it? I'm new to the area of package management, so I don't know what the negative effects could be.
Increase multiClassesSelectors
metric when the following selectors are found:
.foo.bar
foo .bar.baz qux
Watch out for universal selectors:
Most expensive selectors tend to be those with multiple classes (
.foo.bar
,foo .bar.baz qux
, etc.).
https://github.com/reworkcss/css v2.2.0 is out. It now returns the AST with missing fields and a list of parsing errors when run in silent mode.
Analyze-css could do the same, I mean it could have a silent mode that doesn't break on error. It would then return:
parsingErrors
Version 0.9.3
introduced a bug where it includes the glob
dependency in
analyze-css/lib/preprocessors.js
Line 7 in 86bf364
glob
is marked as a development dependency. Installing analyze-css in a project with npm install --production
makes it unusable, since the glob
is not installed.Handle --pretty
option to emit formatted JSON
Hey there,
I noticed that selectors like "body > .foo .bar" return to be a redundantBodySelector, even though the body selector is combined with a child selector.
Is this wanted behaviour?
Thanks, Matt
I've just read this interesting article about accidental reset:
http://css-tricks.com/accidental-css-resets/
It might be interesting to detect this kind of mistake. Or it could just be taken in account in "duplicatedProperties".
I would like to get only the metrics parts without the offenders
part.
Perhaps it could be --no-offenders
, and -N
.
https://developers.google.com/speed/docs/best-practices/rendering:
Avoid using descendant selectors, especially those that specify redundant ancestors.
For example, the rule body ul li a {...} specifies a redundant body selector, since all elements are descendants of the body tag.
I am curious, why are colors listed under offenders?
Hi @macbre!
Would it be possible to add detection for tr-td and th-td in the redundantChildNodesSelectors? It currently detects table-tr and table-th, but nothing for td...
After doing sudo npm install --global analyze-css
I get the following output in my log :
0 info it worked if it ends with ok
1 verbose cli [ 'node',
1 verbose cli '/usr/local/bin/npm',
1 verbose cli 'install',
1 verbose cli '--global',
1 verbose cli 'analyze-css' ]
2 info using [email protected]
3 info using [email protected]
4 verbose cache add [ 'analyze-css', null ]
5 verbose cache add name=undefined spec="analyze-css" args=["analyze-css",null]
6 verbose parsed url { protocol: null,
6 verbose parsed url slashes: null,
6 verbose parsed url auth: null,
6 verbose parsed url host: null,
6 verbose parsed url port: null,
6 verbose parsed url hostname: null,
6 verbose parsed url hash: null,
6 verbose parsed url search: null,
6 verbose parsed url query: null,
6 verbose parsed url pathname: 'analyze-css',
6 verbose parsed url path: 'analyze-css',
6 verbose parsed url href: 'analyze-css' }
7 silly lockFile 29d1466f-analyze-css analyze-css
8 verbose lock analyze-css /Users/abotermans/.npm/29d1466f-analyze-css.lock
9 silly lockFile 29d1466f-analyze-css analyze-css
10 silly lockFile 29d1466f-analyze-css analyze-css
11 verbose addNamed [ 'analyze-css', '' ]
12 verbose addNamed [ null, '' ]
13 silly lockFile ba4893c7-analyze-css analyze-css@
14 verbose lock analyze-css@ /Users/abotermans/.npm/ba4893c7-analyze-css.lock
15 silly addNameRange { name: 'analyze-css', range: '', hasData: false }
16 verbose url raw analyze-css
17 verbose url resolving [ 'https://registry.npmjs.org/', './analyze-css' ]
18 verbose url resolved https://registry.npmjs.org/analyze-css
19 info trying registry request attempt 1 at 20:58:06
20 verbose etag "9S2S8771EYEVXJTX0193TQKUV"
21 http GET https://registry.npmjs.org/analyze-css
22 http 304 https://registry.npmjs.org/analyze-css
23 silly registry.get cb [ 304,
23 silly registry.get { date: 'Mon, 11 Aug 2014 18:58:06 GMT',
23 silly registry.get server: 'Apache',
23 silly registry.get via: '1.1 varnish',
23 silly registry.get 'last-modified': 'Mon, 11 Aug 2014 18:58:06 GMT',
23 silly registry.get 'cache-control': 'max-age=60',
23 silly registry.get etag: '"9S2S8771EYEVXJTX0193TQKUV"',
23 silly registry.get 'x-served-by': 'cache-fra1223-FRA',
23 silly registry.get 'x-cache': 'HIT',
23 silly registry.get 'x-cache-hits': '1',
23 silly registry.get 'x-timer': 'S1407783486.807473,VS0,VE176',
23 silly registry.get vary: 'Accept',
23 silly registry.get 'content-length': '0',
23 silly registry.get 'keep-alive': 'timeout=10, max=50',
23 silly registry.get connection: 'Keep-Alive' } ]
24 verbose etag analyze-css from cache
25 silly addNameRange number 2 { name: 'analyze-css', range: '_', hasData: true }
26 silly addNameRange versions [ 'analyze-css',
26 silly addNameRange [ '0.1.0', '0.2.0', '0.3.0', '0.4.0', '0.4.1', '0.5.0' ] ]
27 verbose addNamed [ 'analyze-css', '0.5.0' ]
28 verbose addNamed [ '0.5.0', '0.5.0' ]
29 silly lockFile 3d425a4f-analyze-css-0-5-0 [email protected]
30 verbose lock [email protected] /Users/abotermans/.npm/3d425a4f-analyze-css-0-5-0.lock
31 silly lockFile 3d425a4f-analyze-css-0-5-0 [email protected]
32 silly lockFile 3d425a4f-analyze-css-0-5-0 [email protected]
33 silly lockFile ba4893c7-analyze-css analyze-css@
34 silly lockFile ba4893c7-analyze-css analyze-css@
35 silly resolved [ { name: 'analyze-css',
35 silly resolved version: '0.5.0',
35 silly resolved author:
35 silly resolved { name: 'Maciej Brencz',
35 silly resolved email: '[email protected]',
35 silly resolved url: 'https://github.com/macbre' },
35 silly resolved description: 'CSS selectors complexity and performance analyzer',
35 silly resolved main: './lib/index.js',
35 silly resolved repository: { type: 'git', url: 'git://github.com/macbre/analyze-css.git' },
35 silly resolved keywords: [ 'css', 'analyzer', 'complexity', 'webperf' ],
35 silly resolved license: 'BSD',
35 silly resolved engines: { node: '>=0.8' },
35 silly resolved dependencies:
35 silly resolved { cli: '~0.6.2',
35 silly resolved 'css-parse': '~1.7.0',
35 silly resolved debug: '~1.0.4',
35 silly resolved 'fast-stats': '0.0.x',
35 silly resolved glob: '^4.0.5',
35 silly resolved 'node-sass': '^0.9.3',
35 silly resolved optimist: '0.6.x',
35 silly resolved slick: '~1.12.1',
35 silly resolved specificity: '~0.1.3' },
35 silly resolved devDependencies:
35 silly resolved { autoprefixer: '~2.2.0',
35 silly resolved glob: '~4.0.5',
35 silly resolved istanbul: '^0.3.0',
35 silly resolved jshint: '~2.5.2',
35 silly resolved mocha: '~1.21.3' },
35 silly resolved bin: { 'analyze-css': './bin/analyze-css.js' },
35 silly resolved preferGlobal: true,
35 silly resolved scripts:
35 silly resolved { test: 'mocha -R spec',
35 silly resolved lint: 'jshint --verbose bin/ lib/ rules/ test/',
35 silly resolved coverage: 'istanbul cover mocha -- -R spec' },
35 silly resolved jshintConfig: { node: true, strict: true, validthis: true },
35 silly resolved readme: 'analyze-css\n===========\n\n\n
\n
\n\nCSS selectors complexity and performance analyzer. analyze-css is built as a set of rules bound to events fired by CSS parser. Each rule can generate metrics and add "offenders" with more detailed information (see Usage section for an example).\n\n## Install\n\nanalyze-css comes as a "binary" for command-line and as CommonJS module. Run the following to install them globally:\n\n
\nnpm install --global analyze-css\n
\n\n## Usage\n\n### Command line tool\n\nYou can use analyze-css "binary" to analyze local CSS files or remote CSS assets:\n\n\nanalyze-css --file examples/elecena.css\nanalyze-css --url http://jigsaw.w3.org/css-validator/style/base.css\n
\n\nYou can provide CSS via stdin as well (notice the dash: -
):\n\n\necho ".foo {margin: 0 \\!important}" | analyze-css -\n
\n\nThis will emit JSON formatted results on stdout
. Use --pretty
(or -p
shortcut) option to make the output readable for human beings.\n\n### CommonJS module\n\njs\nvar analyzer = require(\'analyze-css\');\n\nnew analyzer(\'.foo {margin: 0 !important}\', function(err, results) {\n console.error(err);\n console.log(results); // example? see below\n});\n\n
\n\n### grunt task\n\n> Created by @DeuxHuitHuit\n\n\nnpm i grunt-contrib-analyze-css\n
\n\nIt uses configurable threshold and compares the analyze-css result with it.\n\n### Results\n\njson\n{\n "generator": "analyze-css v0.4.1",\n "metrics": {\n "base64Length": 9308,\n "redundantBodySelectors": 0,\n "comments": 1,\n "commentsLength": 68,\n "complexSelectors": 32,\n "complexSelectorsByAttribute": 3,\n "duplicatedSelectors": 7,\n "emptyRules": 0,\n "expressions": 0,\n "oldIEFixes": 51,\n "imports": 0,\n "importants": 3,\n "mediaQueries": 0,\n "oldPropertyPrefixes": 65,\n "qualifiedSelectors": 28,\n "specificityIdAvg": 0.05,\n "specificityIdTotal": 35,\n "specificityClassAvg": 1.25,\n "specificityClassTotal": 872,\n "specificityTagAvg": 0.78,\n "specificityTagTotal": 548,\n "selectorsByAttribute": 93,\n "selectorsByClass": 568,\n "selectorsById": 35,\n "selectorsByPseudo": 166,\n "selectorsByTag": 519,\n "universalSelectors": 4,\n "length": 51665,\n "rules": 422,\n "selectors": 699,\n "declarations": 1240\n },\n "offenders": {\n "importants": [\n ".foo {margin: 0 !important}"\n ]\n }\n}\n
\n\n## Metrics\n\n base64Length: total length of base64-encoded data in CSS source (will warn about base64-encoded data bigger than 4 kB)\n* redundantBodySelectors: number of redundant body selectors (e.g. body .foo
, section body h2
, but not body > h1
)\n* comments: number of comments in CSS source\n* commentsLength: length of comments content in CSS source\n* complexSelectors: number of complex selectors (consisting of more than three expressions, e.g. header ul li .foo
)\n* complexSelectorsByAttribute: number of selectors with complex matching by attribute (e.g. [class$="foo"]
)\n* duplicatedSelectors: number of CSS selectors defined more than once in CSS source\n* emptyRules: number of rules with no properties (e.g. .foo { }
)\n* expressions: number of rules with CSS expressions (e.g. expression( document.body.clientWidth > 600 ? "600px" : "auto" )
)\n* oldIEFixes: number of fixes for old versions of Internet Explorer (e.g. * html .foo {}
and .foo { *zoom: 1 }
, read more)\n* imports number of @import
rules\n* importants: number of properties with value forced by !important
\n* mediaQueries: number of media queries (e.g. @media screen and (min-width: 1370px)
)\n* oldPropertyPrefixes: number of properties with no longer needed vendor prefix, powered by data provided by autoprefixer (e.g. --moz-border-radius
)\n* qualifiedSelectors: number of qualified selectors (e.g. header#nav
, .foo#bar
, h1.title
)\n* specificityIdAvg: average specificity for ID\n* specificityIdTotal: total specificity for ID\n* specificityClassAvg: average specificity for class, pseudo-class or attribute\n* specificityClassTotal: total specificity for class, pseudo-class or attribute\n* specificityTagAvg: average specificity for element\n* specificityTagTotal: total specificity for element\n* selectorsByAttribute: number of selectors by attribute (e.g. .foo[value=bar]
)\n* selectorsByClass: number of selectors by class\n* selectorsById: number of selectors by ID\n* selectorsByPseudo: number of pseudo-selectors (e,g. :hover
)\n* selectorsByTag: number of selectors by tag name\n* universalSelectors: number of selectors trying to match every element (e.g. .foo > *
)\n* length: length of CSS source (in bytes)\n* rules: number of rules (e.g. .foo, .bar { color: red }
is counted as one rule)\n* selectors: number of selectors (e.g. .foo, .bar { color: red }
is counted as two selectors - .foo
and .bar
)\n* declarations: number of declarations (e.g. .foo, .bar { color: red }
is counted as one declaration - color: red
)\n\n## Read more\n\n* Writing Efficient CSS (by Mozilla)\n* Optimize browser rendering (by Google)\n* Profiling CSS for fun and profit. Optimization notes.\n* CSS specificity\n* CSS Selector Performance has changed! (For the better) (by Nicole Sullivan)\n* CSS Performance (by Paul Irish)\n* GitHub's CSS Performance (by Joh Rohan)\n\n## Dev hints\n\nRunning tests and linting the code:\n\n\nnpm test && npm run-script lint\n
\n\nTurning on debug mode (i.e. verbose logging to stderr via debug module):\n\n\nDEBUG=analyze-css* analyze-css ...\n
\n',
35 silly resolved readmeFilename: 'README.md',
35 silly resolved bugs: { url: 'https://github.com/macbre/analyze-css/issues' },
35 silly resolved _id: '[email protected]',
35 silly resolved _from: 'analyze-css@' } ]
36 info install [email protected] into /usr/local/lib
37 info installOne [email protected]
38 info /usr/local/lib/node_modules/analyze-css unbuild
39 verbose tar unpack /Users/abotermans/.npm/analyze-css/0.5.0/package.tgz
40 silly lockFile 32bcc707-cal-lib-node-modules-analyze-css tar:///usr/local/lib/node_modules/analyze-css
41 verbose lock tar:///usr/local/lib/node_modules/analyze-css /Users/abotermans/.npm/32bcc707-cal-lib-node-modules-analyze-css.lock
42 silly lockFile 56b8b159-pm-analyze-css-0-5-0-package-tgz tar:///Users/abotermans/.npm/analyze-css/0.5.0/package.tgz
43 verbose lock tar:///Users/abotermans/.npm/analyze-css/0.5.0/package.tgz /Users/abotermans/.npm/56b8b159-pm-analyze-css-0-5-0-package-tgz.lock
44 silly gunzTarPerm modes [ '755', '644' ]
45 silly gunzTarPerm extractEntry package.json
46 silly gunzTarPerm extractEntry .npmignore
47 silly gunzTarPerm extractEntry README.md
48 silly gunzTarPerm extractEntry LICENSE
49 silly gunzTarPerm extractEntry bin/analyze-css.js
50 silly gunzTarPerm extractEntry .travis.yml
51 silly gunzTarPerm extractEntry examples/_reset.scss
52 silly gunzTarPerm extractEntry examples/base.scss
53 silly gunzTarPerm extractEntry examples/elecena.css
54 silly gunzTarPerm extractEntry examples/ti.mobile.css
55 silly gunzTarPerm extractEntry lib/collection.js
56 silly gunzTarPerm extractEntry lib/index.js
57 silly gunzTarPerm extractEntry lib/preprocessors.js
58 silly gunzTarPerm extractEntry lib/runner.js
59 silly gunzTarPerm extractEntry lib/preprocessors/sass.js
60 silly gunzTarPerm extractEntry test/errors.js
61 silly gunzTarPerm extractEntry test/rules.js
62 silly gunzTarPerm extractEntry test/sass.js
63 silly gunzTarPerm extractEntry test/rules/base64.js
64 silly gunzTarPerm extractEntry test/rules/emptyRules.js
65 silly gunzTarPerm extractEntry test/rules/expressions.js
66 silly gunzTarPerm extractEntry test/rules/ieFixes.js
67 silly gunzTarPerm extractEntry test/rules/import.js
68 silly gunzTarPerm extractEntry test/rules/duplicated.js
69 silly gunzTarPerm extractEntry test/rules/length.js
70 silly gunzTarPerm extractEntry test/rules/mediaQueries.js
71 silly gunzTarPerm extractEntry test/rules/multiClassesSelectors.js
72 silly gunzTarPerm extractEntry test/rules/prefixes.js
73 silly gunzTarPerm extractEntry test/rules/qualified.js
74 silly gunzTarPerm extractEntry test/rules/complex.js
75 silly gunzTarPerm extractEntry test/rules/specificity.js
76 silly gunzTarPerm extractEntry test/rules/comments.js
77 silly gunzTarPerm extractEntry test/rules/stats.js
78 silly gunzTarPerm extractEntry test/rules/bodySelectors.js
79 silly gunzTarPerm extractEntry test/rules/universal.js
80 silly gunzTarPerm extractEntry test/rules/important.js
81 silly gunzTarPerm extractEntry rules/base64.js
82 silly gunzTarPerm extractEntry rules/emptyRules.js
83 silly gunzTarPerm extractEntry rules/expressions.js
84 silly gunzTarPerm extractEntry rules/ieFixes.js
85 silly gunzTarPerm extractEntry rules/import.js
86 silly gunzTarPerm extractEntry rules/duplicated.js
87 silly gunzTarPerm extractEntry rules/length.js
88 silly gunzTarPerm extractEntry rules/mediaQueries.js
89 silly gunzTarPerm extractEntry rules/multiClassesSelectors.js
90 silly gunzTarPerm extractEntry rules/prefixes.js
91 silly gunzTarPerm extractEntry rules/stats.js
92 silly gunzTarPerm extractEntry rules/complex.js
93 silly gunzTarPerm extractEntry rules/qualified.js
94 silly gunzTarPerm extractEntry rules/comments.js
95 silly gunzTarPerm extractEntry rules/specificity.js
96 silly gunzTarPerm extractEntry rules/bodySelectors.js
97 silly gunzTarPerm extractEntry rules/universal.js
98 silly gunzTarPerm extractEntry rules/important.js
99 silly gunzTarPerm extractEntry rules/prefixes.json
100 silly gunzTarPerm extractEntry data/prefixes.js
101 silly lockFile 32bcc707-cal-lib-node-modules-analyze-css tar:///usr/local/lib/node_modules/analyze-css
102 silly lockFile 32bcc707-cal-lib-node-modules-analyze-css tar:///usr/local/lib/node_modules/analyze-css
103 silly lockFile 56b8b159-pm-analyze-css-0-5-0-package-tgz tar:///Users/abotermans/.npm/analyze-css/0.5.0/package.tgz
104 silly lockFile 56b8b159-pm-analyze-css-0-5-0-package-tgz tar:///Users/abotermans/.npm/analyze-css/0.5.0/package.tgz
105 info preinstall [email protected]
106 verbose readDependencies using package.json deps
107 verbose readDependencies using package.json deps
108 verbose cache add [ 'cli@~0.6.2', null ]
109 verbose cache add name=undefined spec="cli@~0.6.2" args=["cli@~0.6.2",null]
110 verbose parsed url { protocol: null,
110 verbose parsed url slashes: null,
110 verbose parsed url auth: null,
110 verbose parsed url host: null,
110 verbose parsed url port: null,
110 verbose parsed url hostname: null,
110 verbose parsed url hash: null,
110 verbose parsed url search: null,
110 verbose parsed url query: null,
110 verbose parsed url pathname: 'cli@~0.6.2',
110 verbose parsed url path: 'cli@~0.6.2',
110 verbose parsed url href: 'cli@~0.6.2' }
111 verbose cache add name="cli" spec="~0.6.2" args=["cli","~0.6.2"]
112 verbose parsed url { protocol: null,
112 verbose parsed url slashes: null,
112 verbose parsed url auth: null,
112 verbose parsed url host: null,
112 verbose parsed url port: null,
112 verbose parsed url hostname: null,
112 verbose parsed url hash: null,
112 verbose parsed url search: null,
112 verbose parsed url query: null,
112 verbose parsed url pathname: '~0.6.2',
112 verbose parsed url path: '~0.6.2',
112 verbose parsed url href: '~0.6.2' }
113 verbose addNamed [ 'cli', '~0.6.2' ]
114 verbose addNamed [ null, '>=0.6.2-0 <0.7.0-0' ]
115 silly lockFile 2262b754-cli-0-6-2 cli@~0.6.2
116 verbose lock cli@~0.6.2 /Users/abotermans/.npm/2262b754-cli-0-6-2.lock
117 verbose cache add [ 'css-parse@~1.7.0', null ]
118 verbose cache add name=undefined spec="css-parse@~1.7.0" args=["css-parse@~1.7.0",null]
119 verbose parsed url { protocol: null,
119 verbose parsed url slashes: null,
119 verbose parsed url auth: null,
119 verbose parsed url host: null,
119 verbose parsed url port: null,
119 verbose parsed url hostname: null,
119 verbose parsed url hash: null,
119 verbose parsed url search: null,
119 verbose parsed url query: null,
119 verbose parsed url pathname: 'css-parse@~1.7.0',
119 verbose parsed url path: 'css-parse@~1.7.0',
119 verbose parsed url href: 'css-parse@~1.7.0' }
120 verbose cache add name="css-parse" spec="~1.7.0" args=["css-parse","~1.7.0"]
121 verbose parsed url { protocol: null,
121 verbose parsed url slashes: null,
121 verbose parsed url auth: null,
121 verbose parsed url host: null,
121 verbose parsed url port: null,
121 verbose parsed url hostname: null,
121 verbose parsed url hash: null,
121 verbose parsed url search: null,
121 verbose parsed url query: null,
121 verbose parsed url pathname: '~1.7.0',
121 verbose parsed url path: '~1.7.0',
121 verbose parsed url href: '~1.7.0' }
122 verbose addNamed [ 'css-parse', '~1.7.0' ]
123 verbose addNamed [ null, '>=1.7.0-0 <1.8.0-0' ]
124 silly lockFile a652e804-css-parse-1-7-0 css-parse@~1.7.0
125 verbose lock css-parse@~1.7.0 /Users/abotermans/.npm/a652e804-css-parse-1-7-0.lock
126 verbose cache add [ 'debug@~1.0.4', null ]
127 verbose cache add name=undefined spec="debug@~1.0.4" args=["debug@~1.0.4",null]
128 verbose parsed url { protocol: null,
128 verbose parsed url slashes: null,
128 verbose parsed url auth: null,
128 verbose parsed url host: null,
128 verbose parsed url port: null,
128 verbose parsed url hostname: null,
128 verbose parsed url hash: null,
128 verbose parsed url search: null,
128 verbose parsed url query: null,
128 verbose parsed url pathname: 'debug@~1.0.4',
128 verbose parsed url path: 'debug@~1.0.4',
128 verbose parsed url href: 'debug@~1.0.4' }
129 verbose cache add name="debug" spec="~1.0.4" args=["debug","~1.0.4"]
130 verbose parsed url { protocol: null,
130 verbose parsed url slashes: null,
130 verbose parsed url auth: null,
130 verbose parsed url host: null,
130 verbose parsed url port: null,
130 verbose parsed url hostname: null,
130 verbose parsed url hash: null,
130 verbose parsed url search: null,
130 verbose parsed url query: null,
130 verbose parsed url pathname: '~1.0.4',
130 verbose parsed url path: '~1.0.4',
130 verbose parsed url href: '~1.0.4' }
131 verbose addNamed [ 'debug', '~1.0.4' ]
132 verbose addNamed [ null, '>=1.0.4-0 <1.1.0-0' ]
133 silly lockFile 0bd7c3a1-debug-1-0-4 debug@~1.0.4
134 verbose lock debug@~1.0.4 /Users/abotermans/.npm/0bd7c3a1-debug-1-0-4.lock
135 verbose cache add [ '[email protected]', null ]
136 verbose cache add name=undefined spec="[email protected]" args=["[email protected]",null]
137 verbose parsed url { protocol: null,
137 verbose parsed url slashes: null,
137 verbose parsed url auth: null,
137 verbose parsed url host: null,
137 verbose parsed url port: null,
137 verbose parsed url hostname: null,
137 verbose parsed url hash: null,
137 verbose parsed url search: null,
137 verbose parsed url query: null,
137 verbose parsed url pathname: '[email protected]',
137 verbose parsed url path: '[email protected]',
137 verbose parsed url href: '[email protected]' }
138 verbose cache add name="fast-stats" spec="0.0.x" args=["fast-stats","0.0.x"]
139 verbose parsed url { protocol: null,
139 verbose parsed url slashes: null,
139 verbose parsed url auth: null,
139 verbose parsed url host: null,
139 verbose parsed url port: null,
139 verbose parsed url hostname: null,
139 verbose parsed url hash: null,
139 verbose parsed url search: null,
139 verbose parsed url query: null,
139 verbose parsed url pathname: '0.0.x',
139 verbose parsed url path: '0.0.x',
139 verbose parsed url href: '0.0.x' }
140 verbose addNamed [ 'fast-stats', '0.0.x' ]
141 verbose addNamed [ null, '>=0.0.0-0 <0.1.0-0' ]
142 silly lockFile 18867ebf-fast-stats-0-0-x [email protected]
143 verbose lock [email protected] /Users/abotermans/.npm/18867ebf-fast-stats-0-0-x.lock
144 verbose cache add [ 'glob@^4.0.5', null ]
145 verbose cache add name=undefined spec="glob@^4.0.5" args=["glob@^4.0.5",null]
146 verbose parsed url { protocol: null,
146 verbose parsed url slashes: null,
146 verbose parsed url auth: null,
146 verbose parsed url host: null,
146 verbose parsed url port: null,
146 verbose parsed url hostname: null,
146 verbose parsed url hash: null,
146 verbose parsed url search: null,
146 verbose parsed url query: null,
146 verbose parsed url pathname: 'glob@^4.0.5',
146 verbose parsed url path: 'glob@^4.0.5',
146 verbose parsed url href: 'glob@^4.0.5' }
147 verbose cache add name="glob" spec="^4.0.5" args=["glob","^4.0.5"]
148 verbose parsed url { protocol: null,
148 verbose parsed url slashes: null,
148 verbose parsed url auth: null,
148 verbose parsed url host: null,
148 verbose parsed url port: null,
148 verbose parsed url hostname: null,
148 verbose parsed url hash: null,
148 verbose parsed url search: null,
148 verbose parsed url query: null,
148 verbose parsed url pathname: '^4.0.5',
148 verbose parsed url path: '^4.0.5',
148 verbose parsed url href: '^4.0.5' }
149 verbose addNamed [ 'glob', '^4.0.5' ]
150 verbose addNamed [ null, null ]
151 silly lockFile a8e851ff-glob-4-0-5 glob@^4.0.5
152 verbose lock glob@^4.0.5 /Users/abotermans/.npm/a8e851ff-glob-4-0-5.lock
153 silly addNameRange { name: 'cli', range: '>=0.6.2-0 <0.7.0-0', hasData: false }
154 verbose cache add [ 'node-sass@^0.9.3', null ]
155 verbose cache add name=undefined spec="node-sass@^0.9.3" args=["node-sass@^0.9.3",null]
156 verbose parsed url { protocol: null,
156 verbose parsed url slashes: null,
156 verbose parsed url auth: null,
156 verbose parsed url host: null,
156 verbose parsed url port: null,
156 verbose parsed url hostname: null,
156 verbose parsed url hash: null,
156 verbose parsed url search: null,
156 verbose parsed url query: null,
156 verbose parsed url pathname: 'node-sass@^0.9.3',
156 verbose parsed url path: 'node-sass@^0.9.3',
156 verbose parsed url href: 'node-sass@^0.9.3' }
157 verbose cache add name="node-sass" spec="^0.9.3" args=["node-sass","^0.9.3"]
158 verbose parsed url { protocol: null,
158 verbose parsed url slashes: null,
158 verbose parsed url auth: null,
158 verbose parsed url host: null,
158 verbose parsed url port: null,
158 verbose parsed url hostname: null,
158 verbose parsed url hash: null,
158 verbose parsed url search: null,
158 verbose parsed url query: null,
158 verbose parsed url pathname: '^0.9.3',
158 verbose parsed url path: '^0.9.3',
158 verbose parsed url href: '^0.9.3' }
159 verbose addNamed [ 'node-sass', '^0.9.3' ]
160 verbose addNamed [ null, null ]
161 silly lockFile 2d1d1d8c-node-sass-0-9-3 node-sass@^0.9.3
162 verbose lock node-sass@^0.9.3 /Users/abotermans/.npm/2d1d1d8c-node-sass-0-9-3.lock
163 verbose cache add [ '[email protected]', null ]
164 verbose cache add name=undefined spec="[email protected]" args=["[email protected]",null]
165 verbose parsed url { protocol: null,
165 verbose parsed url slashes: null,
165 verbose parsed url auth: null,
165 verbose parsed url host: null,
165 verbose parsed url port: null,
165 verbose parsed url hostname: null,
165 verbose parsed url hash: null,
165 verbose parsed url search: null,
165 verbose parsed url query: null,
165 verbose parsed url pathname: '[email protected]',
165 verbose parsed url path: '[email protected]',
165 verbose parsed url href: '[email protected]' }
166 verbose cache add name="optimist" spec="0.6.x" args=["optimist","0.6.x"]
167 verbose parsed url { protocol: null,
167 verbose parsed url slashes: null,
167 verbose parsed url auth: null,
167 verbose parsed url host: null,
167 verbose parsed url port: null,
167 verbose parsed url hostname: null,
167 verbose parsed url hash: null,
167 verbose parsed url search: null,
167 verbose parsed url query: null,
167 verbose parsed url pathname: '0.6.x',
167 verbose parsed url path: '0.6.x',
167 verbose parsed url href: '0.6.x' }
168 verbose addNamed [ 'optimist', '0.6.x' ]
169 verbose addNamed [ null, '>=0.6.0-0 <0.7.0-0' ]
170 silly lockFile 153c05cb-optimist-0-6-x [email protected]
171 verbose lock [email protected] /Users/abotermans/.npm/153c05cb-optimist-0-6-x.lock
172 silly addNameRange { name: 'css-parse',
172 silly addNameRange range: '>=1.7.0-0 <1.8.0-0',
172 silly addNameRange hasData: false }
173 silly addNameRange { name: 'debug', range: '>=1.0.4-0 <1.1.0-0', hasData: false }
174 silly addNameRange { name: 'fast-stats',
174 silly addNameRange range: '>=0.0.0-0 <0.1.0-0',
174 silly addNameRange hasData: false }
175 verbose cache add [ 'slick@~1.12.1', null ]
176 verbose cache add name=undefined spec="slick@~1.12.1" args=["slick@~1.12.1",null]
177 verbose parsed url { protocol: null,
177 verbose parsed url slashes: null,
177 verbose parsed url auth: null,
177 verbose parsed url host: null,
177 verbose parsed url port: null,
177 verbose parsed url hostname: null,
177 verbose parsed url hash: null,
177 verbose parsed url search: null,
177 verbose parsed url query: null,
177 verbose parsed url pathname: 'slick@~1.12.1',
177 verbose parsed url path: 'slick@~1.12.1',
177 verbose parsed url href: 'slick@~1.12.1' }
178 verbose cache add name="slick" spec="~1.12.1" args=["slick","~1.12.1"]
179 verbose parsed url { protocol: null,
179 verbose parsed url slashes: null,
179 verbose parsed url auth: null,
179 verbose parsed url host: null,
179 verbose parsed url port: null,
179 verbose parsed url hostname: null,
179 verbose parsed url hash: null,
179 verbose parsed url search: null,
179 verbose parsed url query: null,
179 verbose parsed url pathname: '~1.12.1',
179 verbose parsed url path: '~1.12.1',
179 verbose parsed url href: '~1.12.1' }
180 verbose addNamed [ 'slick', '~1.12.1' ]
181 verbose addNamed [ null, '>=1.12.1-0 <1.13.0-0' ]
182 silly lockFile 948a04a3-slick-1-12-1 slick@~1.12.1
183 verbose lock slick@~1.12.1 /Users/abotermans/.npm/948a04a3-slick-1-12-1.lock
184 verbose cache add [ 'specificity@~0.1.3', null ]
185 verbose cache add name=undefined spec="specificity@~0.1.3" args=["specificity@~0.1.3",null]
186 verbose parsed url { protocol: null,
186 verbose parsed url slashes: null,
186 verbose parsed url auth: null,
186 verbose parsed url host: null,
186 verbose parsed url port: null,
186 verbose parsed url hostname: null,
186 verbose parsed url hash: null,
186 verbose parsed url search: null,
186 verbose parsed url query: null,
186 verbose parsed url pathname: 'specificity@~0.1.3',
186 verbose parsed url path: 'specificity@~0.1.3',
186 verbose parsed url href: 'specificity@~0.1.3' }
187 verbose cache add name="specificity" spec="~0.1.3" args=["specificity","~0.1.3"]
188 verbose parsed url { protocol: null,
188 verbose parsed url slashes: null,
188 verbose parsed url auth: null,
188 verbose parsed url host: null,
188 verbose parsed url port: null,
188 verbose parsed url hostname: null,
188 verbose parsed url hash: null,
188 verbose parsed url search: null,
188 verbose parsed url query: null,
188 verbose parsed url pathname: '~0.1.3',
188 verbose parsed url path: '~0.1.3',
188 verbose parsed url href: '~0.1.3' }
189 verbose addNamed [ 'specificity', '~0.1.3' ]
190 verbose addNamed [ null, '>=0.1.3-0 <0.2.0-0' ]
191 silly lockFile 8e55d64e-specificity-0-1-3 specificity@~0.1.3
192 verbose lock specificity@~0.1.3 /Users/abotermans/.npm/8e55d64e-specificity-0-1-3.lock
193 info addNameTag [ 'glob', '^4.0.5' ]
194 info addNameTag [ 'node-sass', '^0.9.3' ]
195 silly addNameRange { name: 'optimist', range: '>=0.6.0-0 <0.7.0-0', hasData: false }
196 silly addNameRange { name: 'slick', range: '>=1.12.1-0 <1.13.0-0', hasData: false }
197 silly addNameRange { name: 'specificity',
197 silly addNameRange range: '>=0.1.3-0 <0.2.0-0',
197 silly addNameRange hasData: false }
198 verbose url raw cli
199 verbose url resolving [ 'https://registry.npmjs.org/', './cli' ]
200 verbose url resolved https://registry.npmjs.org/cli
201 info trying registry request attempt 1 at 20:58:07
202 verbose etag "1BI7VML5ZAH55O20NYCVGZ1OZ"
203 http GET https://registry.npmjs.org/cli
204 verbose url raw css-parse
205 verbose url resolving [ 'https://registry.npmjs.org/', './css-parse' ]
206 verbose url resolved https://registry.npmjs.org/css-parse
207 info trying registry request attempt 1 at 20:58:07
208 verbose etag "8LKM72WHL2NB559F4JE0Q8M6C"
209 http GET https://registry.npmjs.org/css-parse
210 verbose url raw debug
211 verbose url resolving [ 'https://registry.npmjs.org/', './debug' ]
212 verbose url resolved https://registry.npmjs.org/debug
213 info trying registry request attempt 1 at 20:58:07
214 verbose etag "20GEU8UKR4073SIYWSJOANGTH"
215 http GET https://registry.npmjs.org/debug
216 verbose url raw fast-stats
217 verbose url resolving [ 'https://registry.npmjs.org/', './fast-stats' ]
218 verbose url resolved https://registry.npmjs.org/fast-stats
219 info trying registry request attempt 1 at 20:58:07
220 verbose etag "1BYWQPNOPX20XEJZAMXU9578J"
221 http GET https://registry.npmjs.org/fast-stats
222 verbose url raw glob
223 verbose url resolving [ 'https://registry.npmjs.org/', './glob' ]
224 verbose url resolved https://registry.npmjs.org/glob
225 info trying registry request attempt 1 at 20:58:07
226 verbose etag "E0H7WTUVWGDLBAMR8L78YRHXG"
227 http GET https://registry.npmjs.org/glob
228 verbose url raw node-sass
229 verbose url resolving [ 'https://registry.npmjs.org/', './node-sass' ]
230 verbose url resolved https://registry.npmjs.org/node-sass
231 info trying registry request attempt 1 at 20:58:07
232 verbose etag "3U12TJR5Z4B72IKOT1YPD8DON"
233 http GET https://registry.npmjs.org/node-sass
234 verbose url raw optimist
235 verbose url resolving [ 'https://registry.npmjs.org/', './optimist' ]
236 verbose url resolved https://registry.npmjs.org/optimist
237 info trying registry request attempt 1 at 20:58:07
238 verbose etag "2PCLK7LSR31LE5IWKN2IJPRGB"
239 http GET https://registry.npmjs.org/optimist
240 verbose url raw slick
241 verbose url resolving [ 'https://registry.npmjs.org/', './slick' ]
242 verbose url resolved https://registry.npmjs.org/slick
243 info trying registry request attempt 1 at 20:58:07
244 verbose etag "3PZTJUCWBR0G9R7PFBQBF73R3"
245 http GET https://registry.npmjs.org/slick
246 verbose url raw specificity
247 verbose url resolving [ 'https://registry.npmjs.org/', './specificity' ]
248 verbose url resolved https://registry.npmjs.org/specificity
249 info trying registry request attempt 1 at 20:58:07
250 verbose etag "1P67BUTL3Z2UUR31SJHJU7OIU"
251 http GET https://registry.npmjs.org/specificity
252 http 304 https://registry.npmjs.org/cli
253 silly registry.get cb [ 304,
253 silly registry.get { date: 'Mon, 11 Aug 2014 18:58:07 GMT',
253 silly registry.get server: 'Apache',
253 silly registry.get via: '1.1 varnish',
253 silly registry.get 'last-modified': 'Mon, 11 Aug 2014 18:58:07 GMT',
253 silly registry.get 'cache-control': 'max-age=60',
253 silly registry.get etag: '"1BI7VML5ZAH55O20NYCVGZ1OZ"',
253 silly registry.get 'x-served-by': 'cache-fra1232-FRA',
253 silly registry.get 'x-cache': 'HIT',
253 silly registry.get 'x-cache-hits': '1',
253 silly registry.get 'x-timer': 'S1407783487.230289,VS0,VE0',
253 silly registry.get vary: 'Accept',
253 silly registry.get 'content-length': '0',
253 silly registry.get 'keep-alive': 'timeout=10, max=50',
253 silly registry.get connection: 'Keep-Alive' } ]
254 verbose etag cli from cache
255 silly addNameRange number 2 { name: 'cli', range: '>=0.6.2-0 <0.7.0-0', hasData: true }
256 silly addNameRange versions [ 'cli',
256 silly addNameRange [ '0.1.0',
256 silly addNameRange '0.1.1',
256 silly addNameRange '0.1.3',
256 silly addNameRange '0.1.4',
256 silly addNameRange '0.1.5',
256 silly addNameRange '0.1.6',
256 silly addNameRange '0.1.7',
256 silly addNameRange '0.1.8',
256 silly addNameRange '0.1.9',
256 silly addNameRange '0.2.0',
256 silly addNameRange '0.2.1-1',
256 silly addNameRange '0.2.2-1',
256 silly addNameRange '0.2.3-1',
256 silly addNameRange '0.2.3-2',
256 silly addNameRange '0.2.3-3',
256 silly addNameRange '0.2.3-4',
256 silly addNameRange '0.2.3-5',
256 silly addNameRange '0.2.4-1',
256 silly addNameRange '0.2.4-2',
256 silly addNameRange '0.2.5',
256 silly addNameRange '0.2.6',
256 silly addNameRange '0.2.7',
256 silly addNameRange '0.2.8',
256 silly addNameRange '0.3.0',
256 silly addNameRange '0.3.1',
256 silly addNameRange '0.3.2',
256 silly addNameRange '0.3.3',
256 silly addNameRange '0.3.4',
256 silly addNameRange '0.3.5',
256 silly addNameRange '0.3.6',
256 silly addNameRange '0.3.7',
256 silly addNameRange '0.3.8',
256 silly addNameRange '0.3.9',
256 silly addNameRange '0.4.0',
256 silly addNameRange '0.4.1',
256 silly addNameRange '0.4.2',
256 silly addNameRange '0.4.3',
256 silly addNameRange '0.4.4',
256 silly addNameRange '0.4.4-1',
256 silly addNameRange '0.4.4-2',
256 silly addNameRange '0.4.5',
256 silly addNameRange '0.5.0',
256 silly addNameRange '0.6.0',
256 silly addNameRange '0.6.2',
256 silly addNameRange '0.6.3' ] ]
257 verbose addNamed [ 'cli', '0.6.3' ]
258 verbose addNamed [ '0.6.3', '0.6.3' ]
259 silly lockFile 5858ae5a-cli-0-6-3 [email protected]
260 verbose lock [email protected] /Users/abotermans/.npm/5858ae5a-cli-0-6-3.lock
261 silly lockFile 5858ae5a-cli-0-6-3 [email protected]
262 silly lockFile 5858ae5a-cli-0-6-3 [email protected]
263 silly lockFile 2262b754-cli-0-6-2 cli@~0.6.2
264 silly lockFile 2262b754-cli-0-6-2 cli@~0.6.2
265 http 304 https://registry.npmjs.org/node-sass
266 silly registry.get cb [ 304,
266 silly registry.get { date: 'Mon, 11 Aug 2014 18:58:07 GMT',
266 silly registry.get server: 'Apache',
266 silly registry.get via: '1.1 varnish',
266 silly registry.get 'last-modified': 'Mon, 11 Aug 2014 18:58:07 GMT',
266 silly registry.get 'cache-control': 'max-age=60',
266 silly registry.get etag: '"3U12TJR5Z4B72IKOT1YPD8DON"',
266 silly registry.get 'x-served-by': 'cache-fra1232-FRA',
266 silly registry.get 'x-cache': 'HIT',
266 silly registry.get 'x-cache-hits': '1',
266 silly registry.get 'x-timer': 'S1407783487.282869,VS0,VE0',
266 silly registry.get vary: 'Accept',
266 silly registry.get 'content-length': '0',
266 silly registry.get 'keep-alive': 'timeout=10, max=49',
266 silly registry.get connection: 'Keep-Alive' } ]
267 verbose etag node-sass from cache
268 http 304 https://registry.npmjs.org/glob
269 silly registry.get cb [ 304,
269 silly registry.get { date: 'Mon, 11 Aug 2014 18:58:07 GMT',
269 silly registry.get server: 'Apache',
269 silly registry.get via: '1.1 varnish',
269 silly registry.get 'last-modified': 'Mon, 11 Aug 2014 18:58:02 GMT',
269 silly registry.get 'cache-control': 'max-age=60',
269 silly registry.get etag: '"E0H7WTUVWGDLBAMR8L78YRHXG"',
269 silly registry.get 'x-served-by': 'cache-fra1230-FRA',
269 silly registry.get 'x-cache': 'HIT',
269 silly registry.get 'x-cache-hits': '2',
269 silly registry.get 'x-timer': 'S1407783487.283851,VS0,VE0',
269 silly registry.get vary: 'Accept',
269 silly registry.get 'content-length': '0',
269 silly registry.get 'keep-alive': 'timeout=10, max=50',
269 silly registry.get connection: 'Keep-Alive' } ]
270 verbose etag glob from cache
271 silly lockFile 2d1d1d8c-node-sass-0-9-3 node-sass@^0.9.3
272 silly lockFile 2d1d1d8c-node-sass-0-9-3 node-sass@^0.9.3
273 silly lockFile a8e851ff-glob-4-0-5 glob@^4.0.5
274 silly lockFile a8e851ff-glob-4-0-5 glob@^4.0.5
275 verbose about to build /usr/local/lib/node_modules/analyze-css
276 info /usr/local/lib/node_modules/analyze-css unbuild
277 info preuninstall [email protected]
278 info uninstall [email protected]
279 verbose true,/usr/local/lib/node_modules,/usr/local/lib/node_modules unbuild [email protected]
280 verbose /usr/local/bin,[object Object] binRoot
281 info postuninstall [email protected]
282 error Error: No compatible version found: node-sass@'^0.9.3'
282 error Valid install targets:
282 error ["0.2.0","0.2.1","0.2.2","0.2.3","0.2.4","0.2.5","0.2.6","0.3.0","0.4.0","0.4.1","0.4.2","0.4.3","0.4.4","0.5.0","0.5.1","0.5.2","0.5.3","0.5.4","0.6.0","0.6.1","0.6.2","0.6.3","0.6.4","0.6.5","0.6.6","0.6.7","0.7.0-alpha","0.7.0","0.8.0","0.8.1","0.8.2","0.8.3","0.8.4","0.8.5","0.8.6","0.9.0","0.9.1","0.9.2","0.9.3"]
282 error at installTargetsError (/usr/local/lib/node_modules/npm/lib/cache.js:719:10)
282 error at /usr/local/lib/node_modules/npm/lib/cache.js:638:10
282 error at saved (/usr/local/lib/node_modules/npm/node_modules/npm-registry-client/lib/get.js:142:7)
282 error at /usr/local/lib/node_modules/npm/node_modules/graceful-fs/polyfills.js:133:7
282 error at Object.oncomplete (fs.js:107:15)
283 error If you need help, you may report this log at:
283 error http://github.com/isaacs/npm/issues
283 error or email it to:
283 error [email protected]
284 error System Darwin 13.3.0
285 error command "node" "/usr/local/bin/npm" "install" "--global" "analyze-css"
286 error cwd /Users/abotermans
287 error node -v v0.10.15
288 error npm -v 1.3.5
289 verbose exit [ 1, true ]
Hey!
First up, great tool! I’m loving that people are starting to build this kind of thing for CSS.
I just gave it a little run over some CSS I’m working on and the following was a false positive:
"redundantBodySelectors": [
".has-modal > body"
]
This is actually exactly what I need to have: when a modal is shown, a class of .has-modal
is applied to the html
element, and the body
’s overflow etc. is configured accordingly.
I understand that the body
in something like body h1 {}
would be redundant, but perhaps a simple adjustment to the rule should be that if the body
element is the key selector, then it doesn’t get flagged…?
Hi @macbre,
The redundant body selector could be extended to some other rules.
li elements are always inside ul elements, but i often see this kind of rules in stylesheets: .content ul li
Same thing for select option
, table tr
, tr td
and probably some other cases i'm forgetting.
As per #9 (comment)
npm ERR! Error: No compatible version found: minimatch@'^0.3.0'
npm ERR! Valid install targets:
npm ERR! ["0.0.1","0.0.2","0.0.4","0.0.5","0.1.1","0.1.2","0.1.3","0.1.4","0.1.5","0.2.0","0.2.2","0.2.3","0.2.4","0.2.5","0.2.6","0.2.7","0.2.8","0.2.9","0.2.10","0.2.11","0.2.12","0.2.13","0.2.14","0.3.0"]
npm ERR! at installTargetsError (/usr/local/Cellar/node/0.8.12/lib/node_modules/npm/lib/cache.js:553:10)
npm ERR! at /usr/local/Cellar/node/0.8.12/lib/node_modules/npm/lib/cache.js:477:15
npm ERR! at saved (/usr/local/Cellar/node/0.8.12/lib/node_modules/npm/node_modules/npm-registry-client/lib/get.js:138:7)
npm ERR! at /usr/local/Cellar/node/0.8.12/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:218:7
npm ERR! at Object.oncomplete (fs.js:297:15)
npm ERR! If you need help, you may report this log at:
npm ERR! <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR! <[email protected]>
p { width: expression( document.body.clientWidth > 600 ? "600px" : "auto" ); }
body { background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" ); }
base64Length
Hi!
I've seen that the CSS parser used by analyze-css has a 'silent' option: https://github.com/reworkcss/css#cssparsecode-options
Here's my idea: analyze-css could parse the CSS file a first time without this option, to detect any parsing error.
Then, if there is one, restart parsing in silent mode so the rest of the file can be analyzed despite the error.
-R, --reporter <name> specify the reporter to use
complexSelectorsByAttribute
to be a number of selectors by attribute's value with "regular expressions matching" (img[src$=.jpg]
)
case '~=': // contains value in a whitespace-separated list of words
case '|=': // starts with value or value-
case '^=': // starts with
case '$=': // ends with
case '*=': // contains
analyze-css.js - -p
As suggested by @RafLeszczynski
Evaluate node-sass npm module
Would be cool addition to include CSS specificity into the metrics provided.
Specificity is great as it gives you information about what your rules are actually made up of, not just how many you have, etc.
I guess you could calculate specificity for all rules and then provide things like;
<element>
specificitiesHello,
For exemple on this stylesheet:
http://www.laredoute.fr/css/1/fr-FR/bundles/master?v=5f2VA4kNn1isin_Q20pvCYNBAA2CHJajWpBg8zy4l4Q1
There is @font-face (8 times)
in the duplicated selectors offenders. It might be a little bug!
Increase universalSelectors
metric when the following selectors are found:
.foo > *
.foo * li
[type="..."]
Watch out for universal selectors:
In both Opera and WebKit,
[type="..."]
selectors seem to be more expensive thaninput[type="..."]
. Probably due to browsers limiting attribute check to elements of specified tag (after all,[type="..."]
IS a universal selector).
The following rule should be treated as an empty one:
.foo { /* a comment */ }
I just wanted to let you know that I've made an analyze-css grunt task.
https://www.npmjs.org/package/grunt-contrib-analyze-css
npm i grunt-contrib-analyze-css
It uses configurable threshold and compare the analyze-css result with to it.
The following selectors should be ignored by this rule:
table[class*="infobox"] tr
table[class*="infobox"] tr p
ol:lang(or) li
Relates #51
ftr: #47 (comment)
I didn't find the colors metric, but i found one that's not documented in the readme: cssMultiClassesSelectors
Is it a hidden feature?
hey just wanted to let you know I'm using your package for www.testmycss.com (great work on this by the way), would it be cool if I opened a PR to the readme for example usage?
When analyzing CSS via HTTP send a proper user agent:
analyze-css/0.8.0 (node v0.10.4, linux x64)
@media screen and (min-width: 1370px) {
#foo {
color: red
}
}
echo "@media screen and (min-width: 1370px) { #foo {} }" | DEBUG=* ./bin/analyze-css.js - -p
/* Everything but Internet Explorer 6 */
html>body #tres { color: red }
Comprehensive List of Browser-Specific CSS Hacks by Paul Irish
Use a modular approach similar to the one in phantomas:
Expose as npm module.
Expose global "binary": analyze-css
Hi @macbre!
What about having a metric giving the average length of selectors?
For example:
div .foo {}
div .bar {}
div .foo .bar {}
has an average complexity of 2.333
By the way, is there a reason why analyze-css doesn't count attribute expressions in the complexity?
For example .form_b2_legacy .row-fluid input[class*="span"]
has 4 expressions but is not in the complexSelectors offenders.
Gaël
It is solved in #64.
Report duplicated CSS properties.
.foo {
background:#474646;
border:1px solid #6b6a6a;
background:#4c4b4b;
border:1px solid #6b6a6a;
margin-bottom:10px;
}
// Position and Source parameters
var output_obj_pos = parse(css, { position: true, source: 'file.css' });
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.