This question may be foolish, though I want to know from experts in CSS. Is there a way to write CSS classes under one class.
Suppose I have a few divs under a div
<div class="parent">
<div class="c1"></div>
<div class="c2"></div>
<div class="c3"></div>
</div>
Normally, we write css classes like below-
.parent { width: 100%; }
.parent .c1 { //somecode }
.parent .c2 { //somecode }
.parent .c3 { //somecode }
But, I want to know. Can we write like below-
.parent {
width: 100%;
.c1 {
//somecode
}
.c2 {
//somecode
}
.c3 {
//somecode
}
}
Please let me know the answer on my curiosity. Thanks you.
You can't using normal css.
Maybe you are looking for less? Specifically the Nested Rules section further down the page.
This allows you to do what you are asking, along with many other useful functions, variables and mixins.
Alternatively there is the option of SASS. Which is very similar to less.
CSS can't do that, but LESS and SASS can.
Take note these are CSS compilers, so they'll need a compile step and generate the needed CSS for you (instead of you writing everything by hand).
Sounds like you are looking for something similar to nesting or selector Inheritance.
This can be done with SASS. Very similar to LESS. http://sass-lang.com/
no you cant using normal css, but for readability purposes, and if you aren't going to use .c1-3 in anything other than a parent class then you could just indent your CSS and do
.parent {
width: 100%;
}
.c1 {
//somecode
}
.c2 {
//somecode
}
.c3 {
//somecode
}
in this way you can easily see in your code which classes belong to which parent classes. (if you don't want to go down the LESS SASS route
Related
With the LESS preprocessor, you can nest CSS code inside other CSS code, like this:
.Element {
.AnotherElement {
background-color: #FFF;
}
.YetAnotherElement {
background-color: #000;
}
}
This would make the background of .Element .AnotherElement white, and it makes .Element .YetAnotherElement have a background color of black. It does it all without writing it out like:
.Element .AnotherElement {
background-color: #FFF;
}
.Element .YetAnotherElement {
background-color: #000;
}
Does the first example coincide with CSS syntax, or do I have to use the LESS preprocessor?
Nesting is a feature of LESS and SASS, not native to CSS.
This is one of the most common uses for CSS preprocessors, but they offer a lot more too.
No, css doesn't support this syntax, in your css example the "Element" and "AnotherElement" will to receive this properties, AnotherElement will not inherit properties of Element.
I'm wondering, I have alot of image on my website that behave depending on the class. I was wondering if it would be possible using CSS to do this for example.
.willReactOnHover.class1{ background: url('../images/image1.png');}
.willReactOnHover.class2{ background: url('../images/image2.png');}
And then, on hover
.willReactOnHover:hover{
background: /*Here, .class1 would be .image1-hover.png AND
.class2 would be .image2-hover.png */
}
I don't know if it's possible to just had a suffix -hover to all the existing path even if different... I know in javascript I could but I'd love a pure CSS solution else I'll have to create the hover event for every class but since it's the same task for each class I don't know if there's a way it'd be optimal. Or maybe is there a CSS selector that I could use to achieve this?
before CSS-3 people often used background-position along with a image-sprite so you could use the old-horse background-position , like so :
.willReactOnHover.class1{ background: url('../images/image1.png');}
.willReactOnHover.class2{ background: url('../images/image2.png');}
.willReactOnHover:hover{
background-position:-10px;
}
Unfortunately this seems to be impossible with pure CSS at the moment. If you use a prepocessor, like LESS, you could use a loop to accomplish what you want very easily:
Example CSS
#url: "../images/image";
#ext: ".png";
#hover: "_hover";
.generate-images(5);
.generate-images(#n, #i: 1) when (#i =< #n) {
.class#{i} {
background-image: url("#{url}#{i}#{ext}");
}
.class#{i}:hover {
background-image: url("#{url}#{i}#{hover}#{ext}");
}
.generate-images(#n, (#i + 1));
}
Demo
Try before buy
It seems that you could define a CSS rule for each class that you need.
Perhaps the following may be helpful.
.willhover.class1 {
color: blue;
}
.willhover.class2 {
color: green;
}
.willhover.class1:hover {
background-color: yellow;
}
.willhover.class2:hover {
background-color: beige;
}
<div class="willhover class1">Class 1</div>
<div class="willhover class2">Class 2</div>
However, you still need to create specific two types of CSS rules, one for pointing to the non-hover image and the other pointing to the hover image.
I have this html markup:
<figure class="about half">
<figcaption class="head_section">
<h3>About</h3>
</figcaption>
</figure>
and this LESS set up:
figure {
//some style
&.half {
width: 48%;
}
figcaption {
h3 {
.about & & {
// what i need to do but isn't working
}
}
}
&.about {
h3 {
// some style i have which is working
}
}
}
So, my question is how to refer two previus class of figure.about so as not to be out of style h3. I hope that is clear... Much thx.
I'm still not sure I understand what you are trying to achieve here, as you haven't supplied a desired css output. The idea I kinda managed to extract from your question would be a css that looks like this:
figure {
/* some style */
}
figure.half {
width: 48%;
}
figure.about figcaption h3 {
/* what i need to do but isn't working */
}
is this correct?
Here is a way to get this to work with &:
figure {
/* some style */
&.half {
width: 48%;
}
}
figcaption {
h3 {
.about & {
/* what i need to do but isn't working */
}
}
}
The thing here is that the & returns the "path" for all nesting levels above, so you need to construct the nesting rules with exactly the ones you want to use (in our case I moved the figcaption out of the figure rule). So this should give you the selector appearance you want. However, the structure of the nested rules will often depend on the way you want to use #variable inheritance and scope referencing and in some cases it just makes it hard to build the structural selector exactly the way you want, but then there will almost never be the need for including the whole html structure in your selector - and just as in your case figure.about h3 will work just as well as figure.about figcaption h3, as you probably will not add more h3 elements into the figure container.
does anybody know a way or a tool how inheritance can be used in CSS independent of the structure of the elements?
Example:
.bg_red {
background: red;
}
.bold {
font-weight: bold;
}
.bg_red_and_bold {
//this class should inherit all the properties of the above two classes
}
I hope it is clear what I mean...
Thanks
There is no way you can do that in CSS, but since you are looking for tools as well, you might look into CSS preprocessing:
LESS
SASS
Their mixin and #extend features should do what you are looking for.
ability to add multiple classes to element is there for exactly that reason.
<div class="bg_red bold">The red and bold text</div>
There is no such thing in CSS. Only thing you can do is:
.bg_red, .bg_red_and_bold {
background: red;
}
.bold, .bg_red_and_bold {
font-weight: bold;
}
CSS does not support this.
Consider using LESS, which compiles to CSS and supports mixins:
.bg_red_and_bold {
.bg_red();
.bold();
}
Probably not what you want but there is aggregation:
<div class="bg_red bold"...
The div will "inherit" characteristics of both styles.
Is it possibile to add span3 class in a mixin to avoid putting it in every element in my HTML?
Something like:
.myclass {
.span3;
// other rules...
}
EDIT
I apologize I forgot to specify an important detail: span3 is a standard class of Bootstrap.
I didn't find its definition in any file of the Bootstrap framework.
New Answer (requires LESS 1.4.0)
What you actually desire is something known as extending in LESS and SASS terminology. For example, you want an HTML element (just an example)...
<div class="myclass"></div>
...to fully behave as if it had a span3 class from bootstrap added to it, but without actually adding that class in the HTML. This can be done in LESS 1.4.0 using :extend(), but still not easily, mainly because of the dynamic class generation of bootstrap will not be picked up by :extend().
Here is an example. Assume this initial LESS code (not dynamically generated .span3 classes as bootstrap does):
.span3 {
width: 150px;
}
.someClass .span3 {
font-size: 12px;
}
.someOtherClass.span3 {
background: blue;
}
You add this LESS code in 1.4.0:
.myclass {
&:extend(.span3);
}
Which produces this CSS:
.span3,
.myclass {
width: 150px;
}
.someClass .span3 {
font-size: 12px;
}
.someOtherClass.span3 {
background: blue;
}
NOTE how it did not automatically extend the other instances of .span3. This is different than SASS, but it only means you need to be a bit more explicit in extending. This has the advantage of avoiding excessive CSS code bloat.
To fully extend, simply add the all keyword in the extend() (this is updated from my original code, as I was unaware of the all option):
.myclass {
&:extend(.span3 all);
}
Which produces this:
.span3,
.myclass {
width: 150px;
}
.someClass .span3,
.someClass .myclass {
font-size: 12px;
}
.someOtherClass.span3,
.someOtherClass.myclass {
background: blue;
}
That makes your .myclass fully equivalent (in my example) to the .span3 class. What this means in your case, however, is that you need to redefine any dynamic class generations of bootstrap to be non-dynamic. Something like this:
.span3 {
.span(3);
}
This is so the :extend(.span3) will find a hard coded class to extend to. This would need to be done for any selector string that dynamically uses .span#{index} to add the .span3.
Original Answer
This answer assumed you desired to mixin properties from a dynamically generated class (that is what I thought your issue was).
Okay, I believe I discovered your issue. First of all, bootstrap defines the .spanX series of classes in the mixins.less file, so you obviously need to be sure you are including that in your bootstrap load. However, I assume it is a given that you have those included already.
Main Problem
The main issue is how bootstrap is generating those now, through a dynamic class name in a loop. This is the loop that defines the .spanX series:
.spanX (#index) when (#index > 0) {
.span#{index} { .span(#index); }
.spanX(#index - 1);
}
.spanX (0) {}
Currently, because the class name itself is being dynamically generated, it cannot be used as a mixin name. I don't know if this is a bug or merely a limitation of LESS, but I do know that at present time of writing, any dynamically generated class name does not function as a mixin name. Therefore, .span3 may be in the CSS code to put as a class in your HTML, but it is not directly available to access for mixin purposes.
The Fix
However, because of how they have structured the code, you can still get what you need, because as you can see above in the loop code, they use a true mixin itself to define the code for the .spanX classes. Therefore, you should be able to do this:
.myclass {
.span(3);
// other rules...
}
The .span(3) code is what the loop is using to populate the .span3 class, so calling it for your classes will give the same code that .span3 has. Specifically bootstrap has this defined in mixins.less for that mixin:
.span (#columns) {
width: (#fluidGridColumnWidth * #columns) + (#fluidGridGutterWidth * (#columns - 1));
*width: (#fluidGridColumnWidth * #columns) + (#fluidGridGutterWidth * (#columns - 1)) - (.5 / #gridRowWidth * 100 * 1%);
}
So you will get the width properties for the .span3 in your .myclass.
This is easy to accomplish with Less.js, but the real question is: "Should I mix structural grid classes with my non-structural classes?"
And the answer is no.
This is a bad idea, the advantage of a grid system is that it creates a separation of concerns between structural styling and other styling. I'm not saying "it should never, ever, ever be done". But in general, it shouldn't. I don't even like seeing this:
<div class="span3 sidebar">
<ul class="nav">
...
</ul>
</div>
Where the span3 is in the same div as the .sidebar class. The problem with this is that now your sidebar is not just "floating around" inside a column of the grid, it has become part of the grid - which (in general) makes it even more difficult to maintain your styles because of the workarounds you need to create to force this kind of styling to be responsive.
Well you can do it but you have to define .somethign first, in this example I will do it font-wight: bold; and font-size 20px. As you can see in second class .body I didn't have to define font-weight: bold; and font-size: 20px; I just added .something into it
.something {
font-weight: bold;
font-size: 20px;
}
.body {
background-color: gray;
border: ridge 2px black;
.something
}
You can see example here. http://jsfiddle.net/7GMZd/
YOU CAN'T DO IT THIS WAY
.body {
background-color: gray;
border: ridge 2px black;
.something {
font-weight: bold;
font-size: 20px;
}
}