csstool

package module
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 1, 2018 License: MIT Imports: 9 Imported by: 2

README

csstool

CSS filters and formatters in golang

Build Status

css cut

Use awesome CSS frameworks without the weight by cutting out unused rules.

css cut is similar to purgecss (GitHub). It scans your HTML for elements, classes and identifiers and then cuts out any CSS rule that doesn't apply. The results for a small site using a framework like bootstrap can be dramatic:

Bootstrap css cut savings
uncompressed 141k 5.6k 96%
compressed 20k 1.8k 91%

See also Hugo #4446

Example

For use with hugo using bootstrap:

# install the binary
go get github.com/client9/csstool/css

# build your site, by default the output is in `public`
hugo

# create new minimized CSS file from bootstrap
curl -s https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css | \
    css cut --html 'public/**/*.html' > static/bootstrap-csscut.min.css

Of course, you'll need to use the new bootstrap-csscut.min.css file in your template source.

Be sure to put the HTML file pattern 'public/**/*.html' in single quotes.

Usage

TK - likely to change, feedback welcome

API

TK - likely to change, feedback welcome

How It Works
The Correct Algorithm

The "correct way" to strip out CSS rules might be:

  1. Read in all the CSS files, and extract all the selectors
  2. For each HTML file, execute each selector and see if it returns anything
  3. Use that data to the emit each CSS file with only the selectors that were used.

There are a few problems:

  1. Slow, as you are executing n CSS rules against m HTML files.
  2. Need a perfect CSS Level 3 (or 4!) selector library, else you might strip out rules that are actually used.
  3. Need to know which pseudo-classes matter and which ones do not. For instance :hover can be ignored, but :last_child needs to be evaluated.
The CSSCut Algorithm

Since the Correct Way seems problematic, csscut does the following:

  1. Read each HTML file and keep track of elements, classes and ids found.
  2. Scan the CSS file and convert a selector into a set of "basic selectors". If a rule is h1 h2 h3 then the list of basic selectors is h1, h2, and h3. Classes and identifiers (ids) are preserved, while pseudo elements and attribute selectors are ignored.
  3. Then if each of the basic selectors is found in out list in the first step, the original selector is preserved. This not the rule is tossed out.

As a special case, "universal selectors" are passed through: *, ::before, ::after, ::root. Pure attribute selectors are also passed through: [hidden].

In practice this works well for "flat" CSS frameworks such as bootstrap. For highly specified CSS it might not work as well.

css format

Makes minified CSS readable.

css format < bootstrap.min.css

css minify

css minify < bootstrap.min.css

minify is a shortcut of 'css format' with all options selected to produce the smallest output. It is "conservative" in that it only removes whitespace and does not do any property value rewriting.

css count

See commonly or rarely used CSS classes and identifiers.

Work in progress

Credits

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Dump added in v0.2.0

func Dump(r io.Reader, w io.Writer) error

Dump emits grammar info

really only useful for debugging

Types

type CSSCount

type CSSCount struct {
	Debug bool
	// contains filtered or unexported fields
}

CSSCount is for keeping a running frequency of CSS identifiers

func NewCSSCount

func NewCSSCount() *CSSCount

NewCSSCount returns an initialized CSSCount object

func (*CSSCount) Add

func (c *CSSCount) Add(r io.Reader) error

Add frequency counts of CSS identifiers from a input reader

func (*CSSCount) Counts

func (c *CSSCount) Counts() map[string]int

Counts returns a map of identifers and their frequency counts

NOTE: returns internal object, not a copy

func (*CSSCount) List

func (c *CSSCount) List() []string

List returns a sort list of identifiers found

func (*CSSCount) Reset

func (c *CSSCount) Reset()

Reset return object to initial state

type CSSFormat

type CSSFormat struct {
	Indent          int
	IndentTab       bool
	AlwaysSemicolon bool
	RemoveAtRule    []string // ignore things like "@media XXX"
	RemoveSourceMap bool     // remove comment with source map
	Debug           bool
	Matcher         matcher
}

CSSFormat contains formatting perferances for CSS

func NewCSSFormat

func NewCSSFormat(indent int, useTabs bool, m matcher) *CSSFormat

NewCSSFormat creates an initialized CSSFormat object

func (*CSSFormat) Format

func (c *CSSFormat) Format(r io.Reader, wraw io.Writer) error

Format reformats CSS using a reader to output writer

type EmptyMatcher added in v0.2.0

type EmptyMatcher struct{}

EmptyMatcher this keeps all elements, or rather, doesn't remove anything

func (*EmptyMatcher) Remove added in v0.2.0

func (em *EmptyMatcher) Remove([]string) bool

Remove always returns false (i.e. keep everything)

type TagMatcher added in v0.2.0

type TagMatcher struct {
	// contains filtered or unexported fields
}

TagMatcher determines if a given CSS identifier should be kept or removed doesn't need to be public

func NewTagMatcher added in v0.2.0

func NewTagMatcher(tags []string) *TagMatcher

NewTagMatcher creates an initialized TagMatch object

func (*TagMatcher) AddSelector added in v0.2.0

func (tm *TagMatcher) AddSelector(key string)

AddSelector adds a selector to save

func (*TagMatcher) Remove added in v0.2.0

func (tm *TagMatcher) Remove(selectors []string) bool

Remove returns true if tag is to be dropped

func (*TagMatcher) RemoveSelector added in v0.2.0

func (tm *TagMatcher) RemoveSelector(key string)

RemoveSelector deletes a selector to save

Directories

Path Synopsis
cmd
css
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL