I want to alphabetize css selectors (and properties) in my scss files. I'm sure vim can do this (even if I need to use some external tool). How would you sort the following?
h2 {
color:red;
background-color:green;
}
h1 {
font-size:12px;
}
To this:
h1 {
font-size:12px;
}
h2 {
background-color:green;
color:red;
}
For your simple example the following two snippets seem to work, however I fear they may fall down with larger, more complex css.
To order the properties I used a macro**:
:let #q = "/{^Mvi{:sort^M"|%norm! #q
** Note that the ^M's here are entered with Ctrl-vCtrl-m.
Explanation:
Define a macro to:
Search for a "{"
Select text between "{" and "}"
Sort the selection by line
Run the macro across all lines in the buffer.
To order the selectors I used substitute and sort:
:%s/\v([^}])\n/\1/g|%sort|%s/\v[;{]/&\r/g
Explanation:
For every line that begins with something other than "}" remove the newline to collapse this block down to a single line.
Sort the buffer linewise.
After every ";" or "{" insert a newline.
Trailing whitespace throws this off a bit but you don't have any of that, right? :)
Try CSScomb. This tool sorts your css in cusomizable way. You can try it online.
CSScomb has plugin for Vim.
From the CSScomb's site:
Sorting CSS properties (The order of properties in the help of professionals)
Setting the order of CSS properties (Use the order to which you are accustomed to)
Related
I have built a HTML5 tool that used to be on a stand alone page. A client wants to include it in their page, but is concerned about CSS conflicts.
I would like to put my tool in a wrapper div with a class of say 'customtool' and then preface every CSS selector with .customtool I have a number of stylesheets and the total number of selectors is high. I am aware of the risk of human error with a manually amending the selectors.
Obviously I cannot simply target '.' or '#' as it would not work for a selector like .wrapper .content.customclass #div
In this instance I would like
.customtool .wrapper .content.customclass #div
but replacing '.' with '.customtool .' and '#' with '.customtool #' would give .customtool .wrapper .customtool .content.customtool. customclass .customtool #div
How would you go about making an automated procedure to a add the selector in front of every rule?
The http://www.css-prefix.com/ tool doesn’t seem to like comments, it will inject the desired prefix in to the CSS after a comment regardless of what is followed, leaving you with some CSS like this in some cases:
.customtool #div-id #header {
width: 100%;
height: 45px;
/* 60px;*/
.customtool
/* 68 originally */
.customtool margin-top: 15px;
/*margin-top: 35px; */
.customtool
/*margin-top: 20px; */
.customtool
/* to make it visible in the iPad browser */
.customtool
}
A fairly simple fix for this is to run it through a Beautifier such as http://www.cleancss.com/css-beautify/. This will highlight these wrongly injected classes in red making it easy to spot them and remove them.
A simple solution that is not fully automated is to use find and replace in Sublime text. Every selector (apart from the first) follows the previous one. Therefore you could find and replace '}' with '} .customtool'.
However for easy reading you may have a new line between every selector. In the Sublime Text pressing return in the find and replace pane runs find, rather than adding a line break in the find and replace pane. However you can type the following in Notepad (or other plain text editor):
}
[add empty line here - cannot be shown in stackoverflow]
Then copy and paste it into the find window. Then type the following in Notepad:
}
.customtool
Then paste it into the 'replace' window in Sublime. I would suggest using 'replace' to step through the changes rather than 'replace all' as for some reason Sublime doesn't seem to detect every } and there may be instances where you haven't added a space after the closing brace. Comments will stop the first selector after the comment from being picked up in the find and replace, so keep an eye out for these too
Next deal with the commas between selectors by finding , and replacing with , .customtool - simple enough.
Finally you will need to manually modify the first selector.
Using Find and Replace to partially automate the process of adding a new class before every selector, should save you time and effort. However as described above it does not work flawlessly and needs manual checking.
It would be useful if someone wrote a tool for completing this task that would parse CSS sheets and fully automate the process. However I am not aware of any such tools.
You could use this automatic prefixer, but it doesn't seem to handle spaces between your selectors well.
Is it possible to alter X amount of elements (h1, p, span...) only if they have a specific class? I'm looking for something like this:
(elem1, elem2, elem3, elem4).class {
/* do things here */
}
Previously I tried with parentheses, curly and square brackets, and curly seemed to work but a quick glance to Firefox's console inspector seemed to tell me it ignored eveything between the start and end of the brackets, and of course worked, but would also apply to a, say, div instead of p, span, hX.
I know that doing...
elem1.class, elem2.class, elem3.class, elem4.class {
/* do things here */
}
would work, but I was looking for a less verbose syntax, because I'm a lazy ass.
Sorry, but it's not possible with pure css.
There's just no syntax for it.
e1.class, e2.class, e3.class is as short as it gets.
Of course, there are workarounds.
There's an extension called sass
With sass you could write
e1, e2, e3 {
&:hover {
/* Some stuff */
}
}
There's also any which works like
:any(e1, e2, e3).class
But it's only supported in some very recent browsers like firefox and chrome beta (I think, but I could be wrong)
Some new browser supports :any (-webkit-/-moz-), e.g.
:any(elem1, elem2, elem3 ...).yourclass {
color: green;
}
A demo (tested on firefox only): http://jsbin.com/IZozOdo/1/
Futhetr information on MDN
Otherwise consider the opportunity to use a CSS preprocessor like someone else suggested before
I must be misinterpreting the question, because why wouldn't you just use a class selector without a tagname like:
.myclass {
...
}
That selector matches:
p.myclass, span.myclass, a.myclass, etc
Just leave the tag name off of the selector.
EDIT
As pointed out to me in the comment on this answer - if you don't want to include certain tagnames, then you either a) use the verbose syntax that you don't like or b) use another class name on the elements you do want to target (http://jsfiddle.net/Mm9HX/) - it's what CSS classes are for.
I know about mixins and parametric mixins. What we are looking for is a way to make any general purpose selectors in CSS / LESS into a mixin.
Eg in Twitter BootStrap, we have here
.navbar .nav > li {
float: left;
}
If I have to use it in a class say .mynavbar I want to be able to do this
INPUT->
.mynavbar {
.navbar .nav >li;
}
OUTPUT->
.mynavbar {
float:left;
}
Now I know this can't be done with the current version of LESS as the compiler flags a parser error. I wanted someone to help me out on changing the source code of less.js a little so that this is workable.
I've managed to reach the source code for the mixin parser. I've tried changing the RegExp there, but it interferes with other parts of the parser. I know we have to make only a few changes because, instead of just accepting .mixin and #mixin we have to accept any mixin like tags / attribute selectors like input[type=text].
It is currently needed for the development of a UI framework that uses Bootstrap. Unfortunately many places in bootstrap are littered with direct tag selectors instead of ids and classes.
This is possible since version 1.4.0 (2013-06-05) of LESS that include the extend feature. Based on the original example
.navbar .nav > li {
float: left;
}
.mynavbar:extend(.navbar .nav > li) {}
compiles to
.navbar .nav > li,
.mynavbar {
float: left;
}
Documentation here and discussion & example use for the original question here
EDIT: Added Code Sample
First off, I would strongly discourage doing such things. Instead, try to use the power of CSS and build your HTML such that the bootstrap rules apply, for example. Anyway, since you asked for it, here is the solution.
The problem is not the complexity of the selector, or the child rule, but the tag name selector part (i. e. the li). So, what we have to fix is the mixin parser only matching classes and ids. I guess we would not want to tamper with the first class or id test, since that is probably needed to distinguish mixins from normal CSS rules (although the tests run fine with that check commented out). (Actually, there is a parser preference in action, and the only thing tried after mixins are comments and directives, so we can safely remove that check as well). However, we can easily allow tag names in later parts of the mixin selector by adding a question mark after [#.] in the matching regular expression. So
while (e = $(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
– i. e. line 825 – becomes
while (e = $(/^[#.]?(?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
The test cases still run through fine, afterwards, but subtle breakage my occur, so be cautious.
Edit: There is a GitHub Issue for the same problem. Apparently the less folks rather want the mixin feature to be more narrow and function-like, instead of allowing a more flexible … well … mixing in of rules. With regard to the CSS output, that's probably reasonable.
I' currently trying to Style the word "Siteripe". I'd like each letter to have a different color. As shown on this page I'm able to style just the first letter with the lines of CSS code below
#namer:first-letter {
color:#09C;
font-size:1.1em;
font-weight:bold;
}
Since there eight(8) letters in the word, how do I style the remaining seven? I did try the styling bellow but it didn't work. Is there a way to Style the letters individually without wrapping each letter using spans.
#namer:(1)-letter {
color:#09C;
font-size:1.1em;
font-weight:bold;
}
Remember, CSS is Cascading. You can style the whole #namer element separately from the first letter - the more specific style will override the more general one.
#namer:first-letter {
color:#09C;
font-size:1.1em;
font-weight:bold;
}
#namer {
color:red;
}
Update:
Lettering.js allows for styling individual letters. See the comments below for additional information. The info above is for styling the initial character only, and was in answer to the OP's original question before it was edited to make it clearer.
You should be able to select the entire text using the selector without the indexing
#namer:first-letter {
color:#09C;
font-size:1.1em;
font-weight:bold;
}
#namer {
color:red!important;
}
You can then select the first letter using the indexing method above
The pseudo element "first-letter" is self-explanatory, it is intended for the first letter ONLY. Does each of the rest of the letters will have a different style?if not, you might want to wrap each letter within a span tag and assign it a CSS rule.
Now you are able to style the rest of the letters as a whole.
Then in your CSS:
#namer:first-letter {
color:#09C;
font-size:1.1em;
font-weight:bold;
}
span {
color:red;
.
.
.
}
If you want to style EACH letter you might try wrapping each letter using spans. However, it might visually look like a total mess.
Note: come up with a better name for your class #LOL
I want to remove all lines in a CSS file that contain the word "color".
This would include:
body {background-color:#000;}
div {color:#fff;}
How would you do that using the :%s/ command?
Should just be
:g/color/d
Is that such a wise idea? You could end up doing something you don't want if your CSS has sections like this
body {background-color: #000;
font-size: large;
}
p {
color: #fff; float: left;
}
You're better off removing only the properties containing color
s/\(\w\|-\)*color\w*\s*:.\{-}\(;\|$\)//
Update:
As too_much_php pointed out, the regex I didn't exactly work. I've fixed it, but it requires vim. It isn't feasible to forge a regex that only removes problem properties in vi. Because there are no character classes, you would have to do something like replacing the \w with \(a\|b\|c\|d\|....\Z\)
Standard ex sequence:
:/color/d
And just to give you a completely different answer:
:%!grep -v color
:)
This alludes to a larger bit of functionality; you can apply your knowledge of *nix commandline filters to editing your code. Want a list of enums sorted alphabetically? Visual select, :!sort and it's done.
You can use uniq, tac, etc, etc.
This did the trick for me:
:%s/.*color.*\n//