What is the purpose of postcss-autoreset and postcss-initial - css

What is the purpose for:
PostCSS Autoreset
PostCSS Initial
The documentation is very sparse on both and doesn't really explain why one should use them and what there purpose is.
I've tried autoreset. It seems to place all: initial on every element you style. This seems very wasteful when looking at the output.
How is it any different from:
* {
all: initial,
font-family: "Roboto"
}
Looking at the code for autoreset it seems to do just that: https://github.com/maximkoretskiy/postcss-autoreset/blob/master/src/resetRules.es6
I don't get why this is better than using *

postcss-autoreset protects your from inherited properties in CSS.
Imagine that you wrote a component and publish it to npm. You used BEM or CSS Modules, so selectors are isolated. But some developer took your component to webpage with:
* {
box-sizing: border-box;
line-height: 2
}
Because of non-default box-sizing all your sizes become broken. Because os non-standard line-height text become bigger and broke design.
Here is a real example of such issue in EmojiMart component.
postcss-autoreset will put a all: initial to every selector in your component CSS:
.component {
all: initial; /* added by postcss-autoreset, you didn’t write it */
width: 100px;
padding: 10px;
}
.component_title {
all: initial; /* added by postcss-autoreset, you didn’t write it */
height: 20px;
}
As result this auto-inserted all: initial disable user box-sizing and line-height in your component and your component looks in same way in user website.

This is better than * when you want to create isolable component, meaning component that you can integrate in other people app or website like a plug-in or add-on.

Related

Margin in angular global styles are not enforced

I created a global CSS file. It is working perfectly, except that I am unable to set margins.
For Example CSS:
.update_date {
font-size: small;
text-align: right;
margin: 0;
}
This is a CSS style for class update_date. When I use it, except margin, everything is applied. It's the same case with every other class. None of these classes are overridden in any other place.
Can someone provide a workaround on how I can set margins globally.
Environment:
Angular 10/11
Try using
.update_date {
font-size: small;
text-align: right;
margin: 0 !important;
}
this happens because that style is getting overridden by another
You should avoid "!important" if you can. It can cause unintended styling issues later down the line - see below.
My suggestion: In your browser, use your "Inspect Element" (Ctrl + Shift + I) tool to figure out where in the DOM Tree your styling is coming up and what is overriding it. This will help identify if !Important is truly the only solution you can use.
Inspect Element Tool Picture Example
Hard to say with your code snippet what is actually happening and being this post is 1.5 years old, you may already know this info. But I didn't see any other responses, so just wanted to raise awareness to the "!important" property.
More about !Important
From W3 Schools (I am sure you can find this elsewhere as well): https://www.w3schools.com/css/css_important.asp
"Tip: It is good to know about the !important rule, you might see it in some CSS source code. However, do not use it unless you absolutely have to."

Merge two CSS and find colliding properties using WebStorm

I have two CSS from two big projects, whereas I need to merge the two CSS together. Essentially, I just included both CSS in the HTML header of the new project that needs both CSS.
Using WebStorm what is the best way to find and track colliding CSS properties?
For example (note this is just a basic example to express my point):
first.css
.my-class-1 {
background: #eeeeee;
color: #ffffff;
font-family: 'Poppins', sans-serif !important;
min-height: 59%;
}
second.css
.my-class-2 {
background: #000000;
color: #ffffff;
font-family: 'Poppins', sans-serif !important;
min-height: 100%;
}
And given that it is used
<div class="my-class-1 my-class-2" ></div>
From these examples, the background and min-height properties are colliding to each other.
I think your best bet would be to actually load the page in your browser, and use chrome dev tools to inspect the styles. You can do this with most browsers, but I would choose either Chrome or Firefox as they're probably the most refined. This can show you the computed styles and what styles are overwritten by others.
You need to check for these styles manually as your IDE won't have the context to understand that there are conflicting classes being used in the html.
However, if you want to search for duplicate CSS within the CSS file, I would suggest something like http://csslint.net/
The best solution is to use https://stylelint.io/
With this configuration:
{
"extends": "stylelint-config-standard",
"rules": {
"no-duplicate-selectors": true
}
}
It is able to detect similar names which actually help (mostly) finding the colliding CSS properties based on common names.

SCSS variable class name

On my website, I'm constantly doing style="font-size: #ofpx;". However, I was wondering if there's a way to do it with scss so that, when I declare a class, it would also change the font size. For example:
<div class='col-lg-4 font-20'>whatever here</div>
and this would change my font-size to 20. If I did font-30, it would change my font-size to 30 and etc...
What I have so far:
.font-#{$fontsize} {
font-size: $fontsize;
}
This can't be done for arbitrary sizes. The nature of SCSS is that is needs to be flattened down to CSS before it gets applied to the HTML. What you are asking for, however, is essentially to create rules at run-time rather than compile-time.
In other words, SCSS makes it easier to write some of the repetitive parts of CSS, but it doesn't allow you to do anything new that wasn't already possible with plain old CSS.
What you're asking for is also a code smell. It smells like your markup isn't semantic enough. The purpose of a CSS class is to group objects with similar characteristics, but you're using them instead to describe the styles they impart. I would suggest stepping back and reconsidering what it is that you really want.
You obviously have details of certain elements that are context-dependent. For example, maybe you are applying these rules to buttons when you want to make them smaller or larger than usual. You need to identify the scenarios in which the buttons change. Maybe they are 20% smaller if they are in a modal dialog? Then write your normal .button rules, and also create rules for .modal .button which make it smaller.
If you're positive that you want to define font-size for each element within the HTML (and sometimes there are good reasons for doing so), just continue using inline styles. The only reason inline styling is frowned upon is because it combines model and view logic in a way that harms reusability; however, what you are requesting does so in exactly the same way. This is what inline styles were made for. Don't re-invent the wheel.
With all of that said, you can use sass loops to automatically generate classes for integers within a range. For example:
/* warning: this is generally a bad idea */
#for $i from 1 through 100 {
.font-#{$i} {
font-size: #{$i}px;
}
}
This is not a good idea. Pragmatically speaking it doesn't offer any advantages over just using inline styles and with large ranges your resulting file will be larger (which affects website load times).
Aside: There is a CSS philosophy (or fad, if you're feeling ungenerous) called Atomic CSS (or sometimes Functional CSS) which defies the classical advice given in this answer. I won't give an opinion on its effectiveness at producing clean, maintainable code, but it does typically require more tooling than SCSS alone if used with the degree of specificity requested in this question.
Just going to add, mixins are great, but if you want a util class (attach a class to an element, get that font-size applied to it, do a for-loop in SCSS like so..
#for $i from 1 through 4 {
$fontsize: 10px * $i;
.font-#{$i} {
font-size: $fontsize;
}
}
compiles to
.font-1 {
font-size: 10px;
}
.font-2 {
font-size: 20px;
}
.font-3 {
font-size: 30px;
}
.font-4 {
font-size: 40px;
}
If you want the class to match the # of pixels...
#for $i from 1 through 4 {
$base: 10;
$fontsize: $base * $i;
.font-#{$fontsize} {
font-size: $fontsize + 0px;
}
}
Which compiles to
.font-10 {
font-size: 10px;
}
.font-20 {
font-size: 20px;
}
.font-30 {
font-size: 30px;
}
.font-40 {
font-size: 40px;
}
Codepen example.
When using "words" instead of "numbers" for variables, and the word not being at the end of the classname. I could work something out using CSS Attribute selectors ("wildcard selector"). I can iterate over a map object, and use text values to build CSS selectors.
SASS
//map
$colors: (
primary: #121212,
success: #8bcea8
);
//loop
#each $color, $value in $colors {
//can't do this: div.first-class.is-style-#{$color}-component
//can do this:
div.first-class[class*="is-style-#{$color}-component"] {
background-color: $value;
}
}
HTML
<div class="first-class is-style-primary-component"></div>
This will generate a div.myComponent[class*="is-style-primary-component"] selector and so <div class="first-class is-style-primary-component"></div> (.first-class is not required, selector could be div[class*="is-style-#{$color}-component"] or even [class*="is-style-#{$color}-component"] only).
Yet, in some cases of CSS class naming, it could be limited due to the wildcard selector, which is "larger" than a specific class selector rule.
Of course, inline style tags are bad form. So yes, you should add some classes for font size, or just set font size on the elements you need to as you go. Up to you. If you want, you could use a mixin like so:
#mixin font-size($size) {
font-size: $size;
}
.some-div { #include font-size(10px); }
But that's probably overkill unless you get a group of rules that usually go together.
Just for those of you who might stumble across this question in a more recent time and are new to FrontEnd Development.
What Woodrow Barlow said about using inline-styles instead of rule specific classes isn't quite an up-to-date opinion. For instance, Bootstrap has some of those and Tachyons is entirely built upon them. Actually this practice is called Atomic CSS or Functional CSS.
It's better explained by John Polacek in his CSS Tricks article:
https://css-tricks.com/lets-define-exactly-atomic-css/
You can use mixins like this
#mixin font($fontsize) {
font-size: $fontsize;
}
.box {
#include font(10px);
}

How can I reset buttons back to default style if I have * {padding: 0; margin: 0;} set?

I have a page with
* {
padding: 0;
margin: 0;
}
set and it's the only way I can get the layout to work properly across all the browsers, but it unfortunately also makes any buttons in forms looks really ugly. I want the browser default styling on the button.
Is there any kind of CSS I can put to fix it?
it's the only way I can get the layout to work properly across all the browsers
I would suggest you fix that problem, rather then trying to just override it for buttons. Having said that, you can just explicitly put the padding back in:
* {
padding: 0;
margin: 0;
}
input[type=button], button {
padding: 6px;
}
(I don't know if "6px" is the default, but you can experiment).
Additionally, instead of just setting * with "padding: 0" you could try one of the reset CSS files which set it up on just those elements that require it.
I don't think there is a way to return to CSS back to the browser once you've specified a rule that overrides the browser style (never seen one in all my years, anyway).
I think, rather than a blanket reset like what you have there, you might want to try using a more sophisticated reset: http://meyerweb.com/eric/tools/css/reset/ or http://developer.yahoo.com/yui/3/cssreset/
Of course, you can further adapt either of these - but they are pretty solid foundations for CSS.

CSS Equivalent of the "if" statement

Is there any way to use conditional statements in CSS?
I'd say the closest thing to "IF" in CSS are media queries, such as those you can use for responsive design. With media queries, you're saying things like, "If the screen is between 440px and 660px wide, do this". Read more about media queries here: http://www.w3schools.com/cssref/css3_pr_mediaquery.asp, and here's an example of how they look:
#media screen and (max-width: 300px) {
body {
background-color: lightblue;
}
}
That's pretty much the extent of "IF" within CSS, except to move over to SASS/SCSS (as mentioned above).
I think your best bet is to change your classes / IDs within the scripting language, and then treat each of the class/ID options in your CSS. For instance, in PHP, it might be something like:
<?php
if( A > B ){
echo '<div class="option-a">';
}
else{
echo '<div class="option-b">';
}
?>
Then your CSS can be like
.option-a {
background-color:red;
}
.option-b {
background-color:blue;
}
No. But can you give an example what you have in mind? What condition do you want to check?
Maybe Sass or Compass are interesting for you.
Quote from Sass:
Sass makes CSS fun again. Sass is CSS, plus nested rules, variables, mixins, and more, all in a concise, readable syntax.
CSS itself doesn't have conditional statements, but here's a hack involving custom properties (a.k.a. "css variables").
In this trivial example, you want to apply a padding based on a certain condition—like an "if" statement.
:root { --is-big: 0; }
.is-big { --is-big: 1; }
.block {
padding: calc(
4rem * var(--is-big) +
1rem * (1 - var(--is-big))
);
}
So any .block that's an .is-big or that's a descendant of one will have a padding of 4rem, while all other blocks will only have 1rem. Now I call this a "trivial" example because it can be done without the hack.
.block {
padding: 1rem;
}
.is-big .block,
.block.is-big {
padding: 4rem;
}
But I will leave its applications to your imagination.
The #supports rule (92% browser support July 2017) rule can be used for conditional logic on css properties:
#supports (display: -webkit-box) {
.for_older_webkit_browser { display: -webkit-box }
}
#supports not (display: -webkit-box) {
.newer_browsers { display: flex }
}
The only conditions available in CSS are selectors and #media. Some browsers support some of the CSS 3 selectors and media queries.
You can modify an element with JavaScript to change if it matches a selector or not (e.g. by adding a new class).
I would argue that you can use if statements in CSS. Although they aren't worded as such. In the example below, I've said that if the check-box is checked I want the background changed to white. If you want to see a working example check out www.armstrongdes.com. I built this for a client. Re size your window so that the mobile navigation takes over and click the nav button. All CSS. I think it's safe to say this concept could be used for many things.
#sidebartoggler:checked + .page-wrap .hamb {
background: #fff;
}
// example set as if statement sudo code.
if (sidebaretoggler is checked == true) {
set the background color of .hamb to white;
}
CSS has become a very powerful tool over the years and it has hacks for a lot of things javaScript can do
There is a hack in CSS for using conditional statements/logic.
It involves using the symbol '~'
Let me further illustrate with an example.
Let's say you want a background to slide into the page when a button is clicked. All you need to do is use a radio checkbox.
Style the label for the radio underneath the button so that when the button is pressed the checkbox is also pressed.
Then you use the code below
.checkbox:checked ~ .background{
opacity:1
width: 100%
}
This code simply states IF the checkbox is CHECKED then open up the background ELSE leave it as it is.
css files do not support conditional statements.
If you want something to look one of two ways, depending on some condition, give it a suitable class using your server side scripting language or javascript. eg
<div class="oh-yes"></div>
<div class="hell-no"></div>
There is no native IF/ELSE for CSS available. CSS preprocessors like SASS (and Compass) can help, but if you’re looking for more feature-specific if/else conditions you should give Modernizr a try. It does feature-detection and then adds classes to the HTML element to indicate which CSS3 & HTML5 features the browser supports and doesn’t support. You can then write very if/else-like CSS right in your CSS without any preprocessing, like this:
.geolocation #someElem {
/* only apply this if the browser supports Geolocation */
}
.no-geolocation #someElem {
/* only apply this if the browser DOES NOT support Geolocation */
}
Keep in mind that you should always progressively enhance, so rather than the above example (which illustrates the point better), you should write something more like this:
#someElem {
/* default styles, suitable for both Geolocation support and lack thereof */
}
.geolocation #someElem {
/* only properties as needed to overwrite the default styling */
}
Note that Modernizr does rely on JavaScript, so if JS is disabled you wouldn’t get anything. Hence the progressive enhancement approach of #someElem first, as a no-js foundation.
Changing your css file to a scss file would allow you to do the trick. An example in Angular would be to use an ngClass and your scss would look like:
.sidebar {
height: 100%;
width: 60px;
&.is-open {
width: 150px
}
}
While this feels like a bit of a hack, and may not work perfectly in all browsers, a method I have used recently combines the fact that CSS (at least in Chrome) seems to ignore invalid values set on properties, and we can set custom properties that fall back to their default value when invalid.
(Note: I haven't deeply tested this, so treat it as a hacky proof of concept/possible idea)
The following is written in SCSS, but it should work just as well in standard CSS:
.hero-image {
// CSS ignores invalid property values
// When this var is set to an image URL, the browser will ignore it
// When this var isn't set, then we will use the default fallback for the var, which is 'none'
display: var(--loading-page-background-image, none);
// This part isn't directly relevant to my 'if' example, but shows how I was actually using this custom property normally
background-image: var(--loading-page-background-image, none);
}
I'm setting the custom property from JavaScript / React, but it would likely work regardless of how you set it:
// 'true' case
const chosenLoaderUrl = "https://www.example.com/loader.png";
// 'false' case
//const chosenLoaderUrl = "";
// containerRef is just a reference to the div object, you could get this with
// jquery or however you need. Since I'm in React, I used useRef() and attached
// that to my div
containerRef.current.style.setProperty(
"--loading-page-background-image",
`url(${chosenLoaderUrl})`
);
When chosenLoaderUrl is set to my url, that url is an invalid value for the display property, so it seems to get ignored.
When chosenLoaderUrl is set to an empty value, it falls back to the default value in my var() statement, so sets display to none
I'm not sure how 'generalisable' this concept it, but figured I would add it to the other suggestions here in case it is useful to anyone.
Your stylesheet should be thought of as a static table of available variables that your html document can call on based on what you need to display. The logic should be in your javascript and html, use javascript to dynamically apply attributes based on conditions if you really need to. Stylesheets are not the place for logic.
You can use combination of jquery and css classes i.e. I want to change a font color of certain element depending on the color of the background:
CSS:
.h3DarkMode{
color: lightgray;
}
.h3LightMode{
color: gray;
}
HTML:
<h3 class="myText">My Text Here...</h3>
JQuery:
var toggleMode = localStorage.getItem("toggleMode");
if (toggleMode == "dark"){
$(".myText").removeClass("h3LightMode").addClass("h3DarkMode");
}else{
$(".myText").removeClass("h3DarkMode").addClass("h3LightMode");
}
No you can't do if in CSS, but you can choose which style sheet you will use
Here is an example :
<!--[if IE 6]>
Special instructions for IE 6 here
<![endif]-->
will use only for IE 6 here is the website where it is from http://www.quirksmode.org/css/condcom.html , only IE has conditional comments. Other browser do not, although there are some properties you can use for Firefox starting with -moz or for safari starting with -webkit. You can use javascript to detect which browser you're using and use javascript if for whatever actions you want to perform but that is a bad idea, since it can be disabled.

Resources