inherit properties from class other than parent - css

Say I have two classes in my CSS, say .classA{} and .classB{}, and I've defined and tailored classA to however I like it. Now I'd like classB to be mostly like classA, with a couple of changes. Since they will be used separately (i.e., A is not the parent of B), B won't inherit properties from A in the layout. Can I do something like
.classB{
from .classA inherit *
some additional changes
}
while writing the CSS, which will avoid having to copy/paste and also ensure that if I were to change A sometime later, B changes automatically and I don't have to keep track of it.

CSS has no concept of variables to allow for the adjusting of one CSS measurement to influence others automatically. However, there are CSS writing systems that allow for variables (that are then 'compiled' and spit out plain CSS). Those are useful, but require use of the particular framework. (one example: http://lesscss.org/ )
If you are using a server side scripting language such as PHP, you could write your CSS files as PHP files, using variables within.
Barring that, I'd use multiple classes:
.sharedStyles {...the styles to be the same on elements}
.uniqueStylesA {...}
.uniqueStylesB {...}
Then apply as such:
<div class="sharedStyles uniqueStylesA">...</div>
<div class="sharedStyles uniqueStylesB">...</div>
Or...if you can nest in your HTML:
<div class="sharedStyles">
<div class="uniqueStylesA">...</div>
<div class="uniqueStylesB">...</div>
</div>

Related

Is there a difference between CSS custom properties and CSS variables?

In all of the material I've read online, it appears that CSS custom properties and CSS variables are the same thing. However, at the end of an example in the Inheritance of CSS Variables section of the Mozilla Developer Network documentation, there is this confusing statement:
Keep in mind that these are custom properties, not actual CSS
variables. The value is computed where it is needed, not stored for
use in other rules. For instance, you cannot set a property for an
element and expect to retrieve it in a sibling's descendant's rule.
The property is only set for the matching selector and its
descendants, like any normal CSS.
Which gives me the impression that these two concepts are not synonymous.
What is the difference between custom properties and variables?
A CSS Custom Property is the same thing as a CSS Variable. But that seems to come of some clumsy naming.
They weren't wrong to title the page: Using CSS custom properties (variables)
However a CSS Variable is not a variable in the traditional sense, as there is no way to define it so that it is globally scoped like in a programming language, or CSS Preprocessor (LESS/Sass).
Even a root scoped custom property/variable is not global. Changing the value of a property in a child will not change the value above or for siblings of that scope. If someone is expecting to be global, it may cause confusion and I suspect that's what Mozilla's writers are trying to point out.
if you look at
w3.org's CSS Custom Properties for Cascading Variables
This module introduces a family of custom author-defined properties known collectively as custom properties
Custom properties are definitions that can be referenced using var(--my-custom-prop). Like a variable!
quote continued...
as one only has to change the value once, in the custom property, and the change will propagate to all uses of that variable automatically.
Awkward... The above statement is not true exactly. It seems Mozilla Developer Network documentation is trying clarify that idea so that it's less confusing. Repeating the original quote:
Keep in mind that these are custom properties, not actual CSS variables. The value is computed where it is needed, not stored for use in other rules. For instance, you cannot set a property for an element and expect to retrieve it in a sibling's descendant's rule. The property is only set for the matching selector and its descendants, like any normal CSS.
They're pointing out it's not a variable in the traditional sense of a programming language. But that it is computed just like styles, adhering to the general cascade/scoping rules of CSS.
Thus var(--my-custom-prop) could resolve to very different things based on where it is declared, and that declarations don't propagate out to a higher scope.
Here's a codepen to mess around with if you'd like to try it out.
So think of CSS Custom Property the same as CSS Variable but be sure to remember that values cascade, and there's no global scope.
To be clear, the specification is called Custom Properties for Cascading Variables. The key is in the word "Cascading"; custom properties cascade, much like any other property with a few key differences.
In everyday usage, there is no difference between a "custom property" and a "CSS variable"; as far as authors are concerned, they're the same thing, just as "property" and "attribute" refer to the same thing in everyday usage even though the correct terms are "custom property" and "property" respectively (CSS doesn't have attributes; any reference to an attribute such as in attribute selectors and attr() refers to attributes in host languages like HTML).
The name "CSS Variables", the spec's URL slug css-variables, and the var() notation, are all just there to placate authors' clamors over the years for variable support in CSS. The spec never actually canonizes the term "CSS variable", even though it uses the word "variable" a couple dozen times throughout its prose to make itself easier for authors to understand (which is strange because CSS specs aren't intended to be read by authors).
As MDN explains, custom properties aren't true variables like that of programming languages or even CSS preprocessors, even though they have a lot in common. As mentioned above, cascading is what sets custom properties apart. Those traits that they have in common are what authors really are looking for in "variable" support in CSS, and they're good enough for most authors' needs.
That's why everyone just calls them "CSS variables", even though in reality it's a bit of a misnomer.
I have looked at the page you have linked; they are trying to explain the "cascading" of css. They are saying that the style depends on a selector's parents, as opposed to being a set value as you would get in a variable.
The explanation attempts to clarify the difference between a css property and a vairable in programming languages. If you already understand css, you don't need to worry about this explanation.
If we look at the example they provide:
<div class="one">
<div class="two">
<div class="three"></div>
<div class="four"></div>
</div>
</div>
If you give properties to class="two", they will be applied to class="three" and class="four".
If you re-use class="three" and class="four" within another class, like this:
<div class="five">
<div class="three"></div>
<div class="four"></div>
</div>
then they will inherit whatever properties you applied to class="five" with nothing to do with class="two".
This all assumes that class="three" and class="four" do not have their own properties. Let's say you assign the color red to class="three", then it will be red in both cases plus the properties inherited from its parent classes.
I believe that it simply means that if you have the following rules:
#foo{
--my-prop: 10px;
}
.bar{
height: var(--my-prop);
}
with the following HTML:
<div id="foo">
<div class="bar"></div>
</div>
<div id="sibling">
<div class="bar"></div>
</div>
then the height of the .bar div in the #sibling div is going to be 0, because the value of --my-prop is only inherited by descendants of #foo.
The language is confusing. I think the author is probably trying to draw a distinction between variables in procedural languages (like JS) versus Custom CSS Properties. You cannot set a property and use it anywhere, like you might with a variable in another language.

Using nth-child or creating new classes in CSS?

I've just started my first project which is building an admin panel. My task is to create HTML and CSS - sort of a base of design to process further to the back-end developers.
I was asked to keep CSS simple and classes as descriptive as possible ( could be long ) and to use Bootstrap.
To avoid creating unnecessary classes which could be used once or twice I decided to go with :nth-child since I thought giving new class to each column is too much. Additionally I created few base classes that might be used for adding 0px padding and margin.
Unfortunately, as I was writing more and more code I've noticed that some CSS code looks like this:
.print-history-advanced-search > [class*='col-']:nth-child(5) > .form-group > .form-horizontal > .form-group > [class*='col-']:first-child
And it is not a single line.
Additionally, I've noticed that sometimes that when I am making a new class and it has lots of parent elements, I cannot write the CSS selector by its own, but I need to state the parents of the this particular element and put the class at the end, which does not make sense.
Is there any solution I could use to avoid creating classes that are simply used in one or two divs, but also make the CSS code less chaotic and avoid very long names? Or maybe I should just give up on children and nesting and work with just classes?
Thank you for your help!
Have a nice day!
If you want to write good CSS, then I'd suggest the BEM model is a good route to go down.
The essentials are;
No element/selector heirachy
No use of elements in selectors
Class based styles only
BEM stands for Block, Element, Modifier - which is how your class names are formed. Borrowing an example from their site;
.form { }
.form--theme-xmas { }
.form--simple { }
.form__input { }
.form__submit { }
.form__submit--disabled { }
<form class="form form--theme-xmas form--simple">
<input class="form__input" type="text" />
<input
class="form__submit form__submit--disabled"
type="submit" />
</form>
You can see there's a form Block, and then a form__input and form__submit Element, and then a form__submit--disabled Modifier.
Depending on your needs I would recommend using css preprocessors like SASS,LESS.
You’ll find that as a website grows, you’ll develop a pretty long, scrolling list of various elements and CSS rules. Some of the rules might overlap or override each other eventually (in that case, usually the more specific rule will win).
You can end up with a lot more code than you expected, especially considering the different variations of a rule you need for different browsers and screen sizes.
There are many ways to refactor your CSS code to make it easier to navigate and use. Some of the easiest methods are the most effective and have the most mileage. Here are some of the quickest ones:
Keep your spacing uniform: Maintain the same spacing between rules
and within declarations throughout your file so that it’s easier to
read.
Use semantic or “familiar” class/id names: Instead of using a class
name like “bottom_menu”, try using the semantic tag “footer”. Or
when you have an image in your “contact” section, make sure you’re
using a class on your image like “contact_image”
Keep it DRY (Don’t Repeat Yourself): Ideally you want to repeat as
little of your code as possible. Do you find the declaration
“background-color: #000″ repeated throughout your CSS file? Consider
typing it once and instead, using multiple selectors on the one
declaration.
Put your tidiness to the test with these tools: Run your CSS through
CSS Lint or W3C—these will help to parse your CSS file correctly,
and highlight problem areas. Your web browser’s developer tools are
also extremely useful for pinpointing specific elements on your
website and using the area as a sandbox to experiment with different
styles and positioning.
Have a look here for more info

BEM Common Styles

What is the best way of defining general non-block-specific styles throughout the site?
For example:
html
<div class="intro">
<p class="intro__text">foo</p>
</div>
<div class="profile">
<p class="profile__text">bar</p>
</div>
sass/css
.intro__text {
}
.profile__text {
}
.text {
margin-bottom: 0.5em;
}
If I wanted the text to be styled the same, would I (given I am using a pre-processor) #extend .text into the .intro__text and .profile__text classes, or just have all paragraphs throughout the site have a class of text?
Both those solutions seem slightly incorrect to me.
If I have a very common style, it feels like I'm going to be duplicating a lot of styles throughout my rendered css (bumping up the filesize) but having a class of text repeated all throughout my markup seems unnecessarily verbose and untidy.
Is there a best practice for this situation?
I can't say that there is the best way to do it. It depends on the structure of your project and what style your prefer. Both approaches are used in mostly code.
If you like to manage styles through css files - write #extend. However in case you want an element without common style you have to create a modifier for the el. For example - .profile__text--reset.
If you want declare common styles, your class list with common classes may become too long. But it is more clear and specific. And you have a possibility to manage it via javascript.
One improvement for this code is that it is better to use helpers with modifiers. For example, instead of simple .text use .text--sm or .text--m-sm. Or if you want only margin - .m-sm. But it is up to you.
You have several options:
Preprocessor (Sass/LESS/etc) mixins + clean-css/postcss cleaner — this way is simple and powerful, but not flexible, since it's not useful for dynamic landing pages, SPA, etc.;
Element of outer block mix (BEM/runtime mixin): class="intro__text grid__text" — in that way you just splitting manually visual and positioning styles and use their classes together;
Other block mix: class="intro__text paragraph paragraph--valuable" — almost like the previous variant but without linking to the abstract grid block, the best and the most flexible way (IMHO).
NB: Also you can extend BEM mixes with modifiers even in runtime, it's VERY powerful tool.
NB2: If you don't need dynamic web pages, you can freely use sass mixins. Personally I don't use sass/less mixins, only global variables for colors, grid, gaps, etc used in my own classes.

BEM and single selectors

This is sort of a theoretical question, but it bugs me for a couple of hours now.
I'm learning BEM and it's great so far, but I have a problem. Let's say I have this code:
<div class="section-hi main-section">
<h2 class="main-section_header">Blah</h2>
<p>Generated from the CMS</p>
</div>
How do I target the p to make it good with BEM? Can I just go with
.main-section p
or this would be against the rules? I coudn't find any answers to this, since every example and article about BEM focuses only on classes, and I can't expect my CMS to add different class to every groups of paragraphs.
One of the concepts of BEM is to create reusable components, using an element such as p goes against that.
Why?
By specifying p we are restricting the ways in which our component can be used. To display correctly the p tag must be used. For example the following markup would not work with the component.
<div class="section-hi main-section">
<h2 class="main-section_header">Blah</h2>
<span>Generated from the CMS</span> <!-- this will not pick up the styles -->
</div>
Specificity
Another important point is BEM aims to keep specificity to a minimum, using single class names. Creating a style with a p increases specificity.
.main-section p
It is now hard for me to override this style with a utility class, as it has a higher specificity than a single class.
More on CSS specificity
The solution
So instead the idea is to use class names to describe the element. That way we can choose to use whatever markup we like and the component will display as expected. e.g.
<div class="section-hi main-section">
<h2 class="main-section_header">Blah</h2>
<h3 class="main-section_subHeader>Generated from the CMS</h3> <!-- This will work -->
</div>
Must I always use class names?
You will find occasions when it is OK or necessary to create styles for elements and not use class names. For example you may have a component that you only want to be used with certain markup. Then it is perfectly valid to do so.
Summary
As a general rule always try and keep to the single class rule unless there is a valid reason not to do so. Otherwise it will trip you up later on down the line.
For further reading on BEM I recommend this post http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/
If we just look on this code - you can do that, but what if you have more <p> elements? If you can't add class to every element, you can always add id and call element by
#element_id{ }

Multiple classes in body tag, multi-dimensional css structure or blueprint for insanity?

This question is about an approach to css structuring, and so is more discussion oriented.
I'm working with some outsourced css where the body tags have multiple classes assigned, up to half a dozen. (To make things a little worse, none of the css selectors include an html tag which is making it confusing to analyze the css.) These body classes are then used to modify classed or id'd widgets within.
It seems like this approach is like adding an additional dimension to the css, perhaps in some attempt to create a structured css approach. Documentation might have helped, had we been provided any.
This differs from my approach where widgets are styled primarily via id'd divs, perhaps extracting the more generic elements into a class, i.e. div#MyWidget.widgets.
Any ideas on whether such an approach is maintainable, especially considering I am dealing with websites with thousands of pages including tons of legacy stuff, all done by different people with different skill levels? Thanks...
I find nothing particularly wrong with this approach, provided you are conceptually using the body tags to apply very general style rules. The higher up the class is in the DOM, the more generic it should be.
It's hard to answer specifically without examples. One I frequently use is to turn the URL segments into classes for body tag in my pages, for relatively small sites:
// mysite.com/users/show/
<body class="users show">
<div id="Content">
...
</div>
</body>
I use this almost exclusively for overriding default styles on very specific pages:
#Content {
width:500px;
}
.users.show #Content {
width:600px;
}

Resources