Giter Site home page Giter Site logo

peterbe / mincss Goto Github PK

View Code? Open in Web Editor NEW
855.0 39.0 92.0 281 KB

Tool for finding out which CSS selectors you're NOT using.

Home Page: https://peterbe.github.io/mincss/

License: BSD 3-Clause "New" or "Revised" License

CSS 2.82% HTML 31.80% Python 64.45% JavaScript 0.94%

mincss's Introduction

UPDATE April 2019

INSTEAD OF USING THIS, A MUCH BETTER ALTERNATIVE IS https://github.com/peterbe/minimalcss/ WHICH SUPPORTS JAVASCRIPT AND THE CSS PARSING AND TRANSFORMATIONS ARE DONE WITH A PARSED AST.

mincss

Build status

Clears the junk out of your CSS by finding out which selectors are actually not used in your HTML.

By Peter Bengtsson, 2012-2018

Tested in Python 2.7, 3.3, 3.4 and 3.5

Example

$ mincss https://github.com

Installation

From pip:

$ pip install mincss

Why?

With the onslaught of Twitter Bootstrap upon the world it's very tempting to just download their whole fat 80+Kb CSS and serve it up even though you're not using half of the HTML that it styles.

There's also the case of websites that have changed over time but without the CSS getting the same amount of love refactoring. Then it's very likely that you get CSS selectors that you're no longer or never using.

This tool can help you get started reducing all those selectors that you're not using.

Whitespace compression?

No, that's a separate concern. This tool works independent of whitespace compression/optimization.

For example, if you have a build step or a runtime step that converts all your CSS files into one (concatenation) and trims away all the excess whitespace (compression) then the output CSS can still contain selectors that are never actually used.

What about AJAX?

If you have a script that creates DOM elements in some sort of window.onload event then mincss will not be able to know this because at the moment mincss is entirely static.

So what is a web developer to do? Simple, use /* no mincss */ like this for example:

.logged-in-info {
    /* no mincss */
    color: pink;
}

That tells mincss to ignore the whole block and all its selectors.

Ignore CSS

By default, mincss will find all <link rel="stylesheet" ... and <style...> tags and process them. If you have a link or an inline tag that you don't want mincss to even notice, simply add this attribute to the tag:

data-mincss="ignore"

Leave CSS as is

One technique to have a specific CSS selector be ignored by mincss is to put in a comment like /* no mincss */ inside the CSS selectors block.

Another way is to leave the whole stylesheet as is. The advantage of doing this is if you have a link or style tag that you want mincss to ignore but still find and include in the parsed result.

mincss's People

Contributors

ajdavis avatar bernimoses avatar chrisdl avatar frewsxcv avatar j33f avatar ksokhan avatar mnunes01 avatar myint avatar peterbe avatar rerb avatar sureshvv avatar svisser avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mincss's Issues

Mincss does not crawl links

Hi,

and thanks for this great tool.

I can't find a way to crawl the whole site starting from the index page.

mincss http://www.mysite.com 

will crawl index but not other linked pages like

http://www.mysite.com/sub 

Despite a menu clearly linking to it on the index (absolute URLs).

Is it normal or am I missing something ? Is there a way to use a text file filled with URLs or so ?

Thanks

UnicodeEncodeError

Using Python 3.3: got the following error which according to http://stackoverflow.com/a/3224300/1245478 can be fixed with encoding the unicode string as ascii first. The unicode is for a glyph and is defined elsewhere and is correct.

UnicodeEncodeError: 'charmap' codec can't encode character '\ue73d' in position
#1389: character maps to

Traceback (most recent call last):
File "\mincss-script.py", line 9, in load_entry_point('mincss==0.8.1', 'console_scripts', 'mincss')()

File "\main.py", line 70, in main return run(args)

File "\main.py", line 37, in run f.write(link.after)

File "\cp1252.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_table)[0]

Duplicate @media queries trigger an AssertionError

I have the following HTML file with the same @media query appearing twice:

<!-- /tmp/example.html -->
<html>
  <head>
    <style>
      @media screen and (min-width: 600px) { p { display: none; } }
      @media screen and (min-width: 600px) { p { display: none; } }
    </style>
  </head>
  <body>
    <p>Hello world</p>
  </body>
</html>

If I run the following script:

from mincss.processor import Processor

p = Processor()
p.process('file:///tmp/example.html')

I get an AssertionError:

$ python testcase.py
Traceback (most recent call last):
  File "testcase.py", line 7, in <module>
    p.process('file:///tmp/example.html')
  File "/Users/chana/.virtualenvs/tempenv-24ba183892d9d/lib/python3.6/site-packages/mincss/processor.py", line 152, in process
    processed = self._process_content(content, self._bodies)
  File "/Users/chana/.virtualenvs/tempenv-24ba183892d9d/lib/python3.6/site-packages/mincss/processor.py", line 380, in _process_content
    assert old in content, old
AssertionError: @media screen and (min-width: 600px) { p { display: none; } }

The expected behaviour in this case would be:

  • If the HTML contains a <p> tag, the CSS is reduced to one instance of the @media query
  • If the HTML does not contain a <p> tag, both instances of the @media query are removed

I hit this from a weird corner case in my build system where it sometimes renders duplicate CSS selectors, and then I pass it into mincss for extra processing. I have a fairly easy workaround – this could be considered a case of “garbage in, garbage out” – but having tracked it down, I thought I might as well report it.


Version info:

$ python --version
Python 3.6.0

$ pip freeze
appdirs==1.4.0
cssselect==1.0.1
lxml==3.7.3
mincss==0.11.2
packaging==16.8
pyparsing==2.1.10
six==1.10.0

AssertionError with @-ms-viewport inside @media

If you append the following code to tests/four.css

@media (max-width: 900px) {
  @-ms-viewport {
    width: 320px;
  }
}

it will cause an AssertionError exception to be raised. Seems the viewport selector gets replaced with a temp_key but the assertion for the @media selector doesn't know that.

Does not like an address like this one https://urzhumov.ru/wp-content/themes/ustudio/css/style.css?v=3

FOR https://urzhumov.ru/wp-content/themes/ustudio/css/style.css?v=3
Traceback (most recent call last):
File "c:\users\vit\anaconda3\lib\runpy.py", line 184, in _run_module_as_main
"main", mod_spec)
File "c:\users\vit\anaconda3\lib\runpy.py", line 85, in run_code
exec(code, run_globals)
File "C:\Users\vit\Anaconda3\Scripts\mincss.exe_main
.py", line 9, in
File "c:\users\vit\anaconda3\lib\site-packages\mincss\main.py", line 76, in main
return run(args) or 0
File "c:\users\vit\anaconda3\lib\site-packages\mincss\main.py", line 41, in run
with io.open(os.path.join(output_dir, orig_name), 'w') as f:
OSError: [Errno 22] Invalid argument: './output\style.css?v=3'

cssselect dependency missing from requirements.txt

OS X 10.7.5
python 2.7.3

>>> from mincss.processor import Processor
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/rerb/.virtualenvs/mincss/lib/python2.7/site-packages/mincss-0.2-py2.7.egg/mincss/processor.py", line 7, in <module>
    from lxml.cssselect import CSSSelector, SelectorSyntaxError, ExpressionError
  File "/Users/rerb/.virtualenvs/mincss/lib/python2.7/site-packages/lxml/cssselect.py", line 18, in <module>
    raise ImportError('cssselect seems not to be installed. '
ImportError: cssselect seems not to be installed. See http://packages.python.org/cssselect/

mincss gets confused by relative URLs

I am trying to use mincss to create a CSS file containing the subset used by my site.
However, the same CSS file is linked by different pages using different relative links (../foo.css and ../../foo.css) which means mincss sees it as two different things.

I am using this script to try and analize what mincss can do:

import os
import sys

output_folder = os.path.abspath(sys.argv[1])
from mincss.processor import Processor
p = Processor()
urls = []
for root, dirs, files in os.walk(output_folder):
    for f in files:
        if not f.endswith('.html'):
            continue
        url = os.path.join(output_folder, root, f)
        urls.append(url)

p.process(*urls)
for inline in p.links:
    print "===>", inline.href, len(inline.before), len(inline.after)

And here is it's output:

===> ../../assets/css/bootstrap-responsive.min.css 16849 3251
===> ../assets/css/bootstrap-responsive.min.css 16849 3251
===> assets/css/bootstrap-responsive.min.css 16849 3251
===> ../../assets/css/bootstrap.min.css 106059 14737
===> ../assets/css/bootstrap.min.css 106059 14737
===> assets/css/bootstrap.min.css 106059 14737
===> ../../assets/css/code.css 3670 2114
===> ../assets/css/code.css 3670 2114
===> assets/css/code.css 3670 2114
===> ../../assets/css/colorbox.css 6457 774
===> ../assets/css/colorbox.css 6457 774
===> assets/css/colorbox.css 6457 774
===> ../../assets/css/rst.css 6559 2581
===> ../assets/css/rst.css 6559 2581
===> assets/css/rst.css 6559 2581
===> ../../assets/css/theme.css 1287 1061
===> ../assets/css/theme.css 1287 1061
===> assets/css/theme.css 1287 1061

It's perfectly possible that I am using mincss wrong, of course :-)

Split on : better

If you have a selector like .ui[class*="4:3"] you can't simply split this by the : like you can when you do a.foo:hover to make a.foo.

Setup issue

Hi !
I need some help to figure out a basic error.
I just installed python on ubuntu like so :
apt-get install python python-lxml python-cssselect python-setuptools
then installed mincss :
python setup.py install

I edited run_mincss to set my own URL. Then I launched :
python run_mincss

and I had this error :

Traceback (most recent call last):
File "run_mincss", line 38, in
run()
File "run_mincss", line 10, in run
p.process(URL)
File "/usr/local/lib/python2.7/dist-packages/mincss-0.8.1-py2.7.egg/mincss/processor.py", line 122, in process
processed = self._process_content(content, self._bodies)
File "/usr/local/lib/python2.7/dist-packages/mincss-0.8.1-py2.7.egg/mincss/processor.py", line 321, in _process_content
assert old in content
AssertionError

Did I missed something ? What can I do to fix that ?
best regards,
Anthony

AttributeError: 'LinkResult' object has no attribute 'url'

I tried this with 0d2e7e5:

./run.py https://mincss.readthedocs.org/en/latest/

and got an error:

FOR _static/pygments.css
Traceback (most recent call last):
  File "./run.py", line 35, in <module>
    if link.href != link.url:
AttributeError: 'LinkResult' object has no attribute 'url'

The attribute url assignment is commented out in the LinkResult.__init__. I guess the code above was forgotten to be updated?

Command line interface

I'd love to expand the current example/run_mincss into a proper command line interface in order to open the tool up to a wider audience.

The initial features off the top of my head are:

  • Save to file (creates a new .css file in a specified output dir)
  • Crawl site (takes a start url, then crawls all [internal] links to build up an array of urls to be processed)

Let me know if you think this is worthwhile and I'll get started.

Allow file & stdin as input

Unless I'm mistaken, it seems that the input has to be a URL. How about also allowing a file, so that

mincss file.html would work.
Also cat file.html | mincss would be nice. All those POSIXy goodness.

Remove unused @font-face

Hi

Great tool. It works great except that it doesn't remove unused CSS items, e.g.

@font-face {
  font-family: 'Lato';
  font-style: normal;
  font-weight: 400;
  src: local('Lato Regular'), local('Lato-Regular'), url(data:font/woff;base64,d09GR... <snip/> ...AisA) format('woff');
}

As you can see, the font data is encoded and embedded, which makes the spreadsheets massive (blame https://github.com/grammarly !).

help installing

my install died with the following

src/lxml/lxml.etree.c:16:20: fatal error: Python.h: No such file or directory

any clues why ?

  • debian wheezy
  • Python 2.7.3

Erroneous removal of flexbox

The following css keep on getting removed even though they are necessary.

.login{
    display: flex;
    justify-content: center;
    align-items: center;
}

mincss crashes when stylesheet links have query strings

>mincss http://web.archive.org/web/20140208025552/http://www.clarin.com/
[output omitted]
FOR /static/css/banner-styles.css?v=1516052760.0
Traceback (most recent call last):
  File "c:\program files\anaconda3\lib\runpy.py", line 184, in _run_module_as_ma
in
    "__main__", mod_spec)
  File "c:\program files\anaconda3\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Program Files\Anaconda3\Scripts\mincss.exe\__main__.py", line 9, in <
module>
  File "c:\program files\anaconda3\lib\site-packages\mincss\main.py", line 69, i
n main
    return run(args) or 0
  File "c:\program files\anaconda3\lib\site-packages\mincss\main.py", line 37, i
n run
    with io.open(os.path.join(output_dir, orig_name), 'w') as f:
OSError: [Errno 22] Invalid argument: './output\\banner-styles.css?v=1516052760.
0'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.