Make Stylelint ignore indentation in certain instances? - css

I recently set up Stylelint to run through my stylesheets but there's an error it's throwing that I'd rather keep as-is:
The error is that I'm not using a single space before the { and while I'd like this to be true for most other instances for legibility I was hoping to keep this one.
Is it possible to either modify the rule to allow these sorts of indentation patterns or otherwise disable a rule for a block of CSS? The latter is not ideal but I'll take what I can get.
Otherwise I'll likely just ignore it.

I think the rule in question is block-opening-brace-space-before.
If you want to only enforce a single space before the opening brace of multiline blocks and ignore single-line blocks, then you can do so using the rule's always-multi-line primary option:
/* Enforce a single space before this opening brace */
a {
color: red;
}
/* Don't enforce anything before this opening brace */
a { color: red; }
There is, however, no option to specifically ignore the opening braces of single-line keyframe declaration blocks. If this is what you want then please raise a feature request issue.
Is it possible to either modify the rule to allow these sorts of indentation patterns
You can create a plugin that enforces the alignment of the open braces of single-line keyframe declaration blocks within each #keyframe.
otherwise disable a rule for a block of CSS?
You can use stylelint-disable commands to turn off the block-opening-brace-space-before rule for this block of code.

Related

Is there a way to type check CSS custom properties (aka CSS variables)?

I'm considering replacing SCSS variables (i.e. $someValue) with CSS custom properties (e.g. var(--someValue)) in an attempt to both allow for a little more flexibility in the form of theming and context-specific overrides, and to make the devtools in browsers a little more usable. Eventually, I'd potentially like to dump SCSS variables entirely just to simplify the development stack.
However, I've noticed that unlike SCSS variables, CSS custom properties are entirely un-checked, and typos are a thing. I've had code break in confusing ways because a typo was made either setting a CSS custom property, or using it in an expression - after all, CSS is very lenient using un-set or invalidly set CSS properties.
Since CSS custom properties aren't exactly new at this point, I thought I'd be able to find some webpack plugin or other solution to add basic typechecking to CSS properties, but I can't seem to find any. Ideally, I'd like to require all CSS custom properties to be declared in some fashion, including something like a type for its contents (to ensure that e.g. variables are consistently used as a dimensionless vs. dimension-full value vs. color, etc), but even just a tool or technique to detect typos would catch real errors. However, I've been unable to find anything like this, either as a build tool, or SASS plugin.
How can I protect myself from simple oversights when using CSS custom properties, e.g. detect that a property set as --someValue: 13px is never used or conversely that a reference var(--someValue) appears to have no matching assignments?
Using the new #property rule you can almost have what you want since it will allow to define the type for your variables.
Example:
#property --primary-color {
syntax: '<color>';
inherits: false;
initial-value: blue;
}
.box {
--primary-color: red; /* this one is valid */
background:var(--primary-color);
height:100px;
}
.box-alt {
--primary-color:10px; /* this one is invalid and will fall to the intial-value */
background:var(--primary-color);
border:var(--primary-color) solid green; /* it won't be used here even if contain pixel */
height:100px;
}
<div class="box"></div>
<div class="box-alt"></div>
You need to run the above on Chrome or Edge (Firefox still doesn't support this). As you can see, using pixel value is not allowed here since we specified the type to be <color>.
Actually the dev tool will show you nothing but this will probably change in the future to get some warning. In the meantime, you can rely on the initial value that will get used when the custom property is either not defined or defined with an invalid value.

Automatically 'namespacing' CSS

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.

Overriding CSS property all: unset

For a CSS framework I am developing, I am using all: unset, which by itself works fine:
#foo { all: unset; }
However, in certain cases, I want to "undo" the effect of this rule, as in
#foo:hover { all: auto; }
However, this obviously does not work because there is no value of auto for all. Instead, we have the values inherit and initial, which instead of "cancelling" the all property, have different effects: of reverting all values to their parent's value, or their initial (I assume this means system-level default values).
To accomplish what I want, I am currently doing
#foo:not(:hover) { all: unset; }
which works fine, but is not too scalable if I want to do this for multiple pseudo-classes, for example, and I would prefer to override the all: unset property? Is there any way to do so?
It does not appear to be possible to undo the effects of the all property once it has been specified. This may be due to all being a shorthand property (that happens to accept only the CSS-wide keywords as values).
You can't erase a shorthand declaration from the cascade the same way that css-cascade-4's introduction of the revert keyword allows you to erase author-level declarations, and that's because a shorthand property doesn't exist as its own entity in the cascade; instead, it simply represents all of its component properties. Like with the more traditional shorthand properties such as background and font, the only way to override a shorthand declaration that has been applied is to re-specify the values for the longhands that were overridden, either via longhand declarations or via another shorthand declaration. But you can't do the latter with the all property since it only accepts CSS-wide keywords.
As the former is obviously not practical with the all shorthand, since you can't predict which author-level declarations are being overridden to begin with, your only other option is to restrict it via a selector, thereby preventing it from ever applying in specific circumstances in the first place. Hopefully we will see more implementations of level 4 :not() in the near future, which will make writing selectors a little easier.
Additionally to what BoltClock explained, what you want is not currently possible even for non-shorthand properties.
* { color: red; }
#foo { color: unset; }
#foo:hover { color: /* How to revert to red? */ }
Once you add a value which wins the cascade, there is not way to tell the cascade to "go back" and get the previous winner instead. You must set it explicitly, but that's only possible if you know it.
The closest thing is the revert keyword, introduced by CSS Cascade 4, which rolls back the cascade to previous origin level. But rolling the cascade back to the previous winner in the same origin level is currently not possible.
Then, the solution is restricting your selectors to apply only when you want them. This way there is no need to undo.
Have you tried
all: revert
More infos here MDN

Can I shorten my CSS?

Here is my original CSS to apply different colour backgrounds:
.one-colour {
background-color:#153a63;
}
.two-colour {
background-color:#f16c24;
}
.three-colour {
background-color:#337db9;
}
I know you can do multiple CSS classes such as .one.two.three {...}
But is my CSS condensed down as much as possible? and I don't mean just putting the code onto one line to make it "shorter".
But is my CSS condensed down as much as possible?
Yes(ish)
Each CSS rule is setting the same property style to a different value. As such, you have condensed the ruleset to the minimum number of rules to allow this level of distinction. If anything, you could simply change background-color to just background- if background properties aren't set in other rules which this could override.
*Although my predisposition is that this should be a comment, I guess in essence it is effectively an answer to your question.
Additional Methods Update:
As mentioned in the comments, there are some other (overkill?) methods for condensing:
Put everything in a single line, remove whitespace (minify)
Shorten your class names, e.g (.one-colour -> .c1), as noted below this is a subjective, context sensitive decision
The last style setting in a CSS rule does not require a trailing semi-colon in order for the rule to process, so you can also remove these
Convert your HEX colors to their 3 digit counterparts (approx), #036, #F63 and #36C
Depending on how you use these classes, there might be a way to remove one of those classes.
If you use those classes in a particular container - you could apply one of the colors to the container and then override it only on 2 of the inner divs.
Again, it depends on how you use the classes.
Yes, I would say so. If you wanted to start doing things to all the classes at once (like add a black border to them all) then you could combine that onto one line, as you suggested. Otherwise, it looks as compact as it's going to get at the moment. I can't suggest an improvement.

How important is it to leave out the last ';' inside a set of CSS rules?

I've had problems with Internet Explorer not applying the last property in a list of CSS properties. Is it necessary to leave out the last ; from a list of CSS properties? For example:
.style { width: 100px; height: 100px }
Or does it really not matter?
It doesn’t matter. Even Internet Explorer 6 will accept the redundant semi-colon at the end; your mistake must have been somewhere else.
Additional advice: Be absolutely sure you don't accidentally end a line with double semicolons, like
.aStyle {
background-color: #FFFFFF;;
color: #000000;
}
This can have the extremely unhappy effect of negating every single style that comes after it on the page. It is not at all like an additional semicolon at the end of a line of Javascript, which has no effect whatsoever except to add a character to the page weight.
You don't need to include the last semi-colon. Nor do you have to exclude it. It's optional.
From a maintenance point of view, I'd actually get into the habit of including after every property. Accidentally forgetting to put one one in when editing can cause some subtle errors.
I am not aware of any issue with IE causing issues with missing semi-colon's - either that was an awful long time ago or there was some other issue that maybe lead you to believe that was the problem ;)

Resources