开发者

Programmatically separate stylesheet into sub-stylesheets?

Say you have a massive stylesheet with a full site worth of selectors, each loaded with properties in it (positioning, sizing, fonts, colors, etc... all together) and you want to separate them into different, appropriate files (e.g. fonts.css, colors.css, layout.css, etc..)..

Are there any known (automated) methods for completing such a task?

Example:

#myid {
display:block;
width:100px;
height:100px;
border:1px solid #f00;
background-color:#f00;
fo开发者_如何学编程nt-size:.75em;
color:#000;
}

Would be converted to the following 3 files:

layout.css:

#myid {
    display:block;
    width:100px;
    height:100px;
}

color.css:

#myid {
    border:1px solid #f00;
    background-color:#f00;
    color:#000;
}

fonts.css:

#myid {
    font-size:.75em;
}

My example probably doesn't utilize the best conventions for doing this, but a way to automate the separation of the properties into different files would be very convenient in framework creation, I imagine.


Here's how I would do it:

  1. Copy your big stylesheet to the 3 files.
  2. Open each one and remove the styles you don't need.

For step 2, you can save a lot of time by using search/replace in an editor like Notepad++. For example in layout.css, you could do a regex search for ^.*background:.+$ and replace with nothing. (Then at the end remove all blank lines.)

In theory you should be able to reduce this to only a couple of regexes per file, but Notepad++ doesn't seem to like the pipe character, or parentheses for that matter. ^.*background(-color|-image)?:.+$ ought to work, but it doesn't.

This isn't programmatic, but TBH by the time you'd written your own code to do what you're asking you could have typed the stylesheets out from scratch.


Roll your own. Valid CSS should not be terribly difficult to parse.

  • Split the entire file by }
  • In each of those, what comes before the { is the selector
  • Split what comes after { by ; to get each individual rule for each selector
  • Evaluate each rule and build your files accordingly

Semi-pseudo VB.NET code...

 Dim CssFile as String = System.IO.File.ReadAllText("MyFile.css")
 Dim CssRules as String() = CssFile.Split("}")

 For Each Rule as String in CssRules
     Dim Selector as String = Rule.Substring(0, Rule.IndexOf("{")).Trim();
     Dim Styles as String() = Rule.Substring(Rule.IndexOf("{") + 1).Trim().Split(";");

     For Each Style as String in Styles
         If Style.StartsWith("font") Then 
              ' Build your files... yada, yada, yada
         End If
     Next
 Next


Do you have a command line grep? Do you care about comments in the output? Can you do a first pass to clean up the formatting? For example in your editor of choice ensure that {,}, and ; are followed by a new-line. Then these might get you close:

grep -i '[{]\|[}]\|background\|border\|color' source.css > color.css
grep -i '[{]\|[}]\|font\|letter\|line-height' source.css > font.css
grep -v 'background\|border\|color\|font\|letter\|line-height' source.css > layout.css

You'll have to make adjustments if you don't want any of the following tags in the layout.css: outline-*, text-*, white-space, word-spacing. That is if your css uses them. I'd also take a quick look to see what tags you are actually using. For example,

grep -v '[{]\|[}]' test2.css | sed -e 's/:.*$//g' | sort -u


This should get you started:

#!/usr/bin/env python
import cssutils

PATH_TO_CSS_FILE = 'old_huge_css_file.css'

LAYOUT = ('display', 'width', 'height', 'margin', 'padding',
          'position', 'top', 'left', 'bottom', 'right')
COLOR = ('color', 'background', 'border', 'background-color')
FONTS = ('font', 'font-size')

def strip_styles(infile_path, outfile_path, properties_to_keep):
    stylesheet = cssutils.parseFile(infile_path)

    for rule in stylesheet:
        if not rule.type == rule.STYLE_RULE:
            continue

        [ rule.style.removeProperty(p) for p in rule.style.keys() 
            if not p in properties_to_keep ]

    f = open(outfile_path, 'w')
    f.write(stylesheet.cssText)
    f.close()

segments = (
    ('layout.css', LAYOUT),
    ('color.css', COLOR),
    ('fonts.css', FONTS),
)

for segment in segments:
    strip_styles(PATH_TO_CSS_FILE, *segment)

You'll need CssUtils

And obviously I havn't filled in the tuples at the beginning with every possible css property. I'll leave that as an exercise to the reader

note: It will leave all the comments in the stylesheet even though many of them will not pertain to the separated styles.

Also, all styles not enumerated in the LAYOUT, COLOR, and FONTS variables at the top will be filtered out.

You can easily modify the strip_styles function to filter out the styles in those three variables to make a 4th stylesheet that contains all the misc. properties if you like


The easy part is going to be parsing CSS. The hard part is classifying the different CSS directives and anticipating short-hand CSS selectors.

CSSTidy might be the ticket with some modifications. Not only will it parse CSS but it will also consolidate CSS properties whenever possible:

http://csstidy.sourceforge.net/download.php


I don't know of any methods that will separate out your css automatically, but the Blueprint CSS framework has this already broken out for you & in times past I've just plugged in my styles where needed & it took care of all the misc browser differences.

www.blueprintcss.org


Seems like a useful tool, I thought it might already exist, but I couldn't find anything.

I think you probably would need to create it. To do so you can probably leverage one of the many existing CSS parser libraries or programs that are out there.

A quick search reveals multiple ones in .NET, Java, Ruby, etc. There's even questions about this on StackOverflow.


Really easy to roll your own script. Here is a library for css in ruby, im sure you can find one with whatever platform you happen to use


* Split the entire file by }
* In each of those, what comes before the { is the selector
* Split what comes after { by ; to get each individual rule for each selector
* Evaluate each rule and build your files accordingly


I've done two big projects with multiple styles in the past months.

In one case there were different colors and styles per page. In the other case some colors and images were different for target groups.

I created a stylesheet main.css which contained the positioning, default fonts, spacing and everything else you'd expect in a stylesheet. Then for each target group I created an extra stylesheet containing the specific coloring, fonts and (background) images.

In your case, builing a framework, I would at least suggest the following components:

  • Reset
  • Main
  • Typography

One thing to keep in mind is the number of HTTP requests you're making by calling other stylesheets. If possible use as little stylesheets as possible.


Have you thought about using a program that takes care of the CSS for you, instead of manually going through and editing it all yourself? I've recently started using stylizer and I'm impressed with all the functions it has available (even in the free version). Although it won't split the CSS files like you want as far as I can tell.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜