CSS Style Inheritance

Can a CSS class inherit one or more other classes?

There are tools like LESS, which allow you to compose CSS at a higher level of abstraction similar to what you describe.

Less calls these "Mixins"

Instead of

/* CSS */
#header {
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
}

#footer {
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
}

You could say

/* LESS */
.rounded_corners {
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
}

#header {
.rounded_corners;
}

#footer {
.rounded_corners;
}

JavaFX CSS style inheritance

A quick and simple answer is Slaw's comment (which may not use CSS inheritance at all):

.base_arc, .child_arc { /* common styles */ } 
.child_arc { /* specific styles */ }

A longer answer, discussing CSS inheritance and its relationship with object-oriented inheritance is below.

Background on CSS inheritance vs object-oriented inheritance

CSS inheritance is not like the object oriented inheritance that Java has.

Instead, CSS inheritance is based upon the node position in the scene graph. Child nodes can inherit CSS properties from their parents (if the CSS property is inheritable). Inheritance is based upon position in the scene graph, not on the Java class type hierarchy. This is documented in the JavaFX CSS documentation on inheritance.

Applying CSS inheritance to your example

Create CSS rules for the parent node

Let's say you have a Pane in which you draw your arcs, and you set the style drawing-pane on it. If you have the following css rule:

.drawing-pane Arc { 
-fx-stroke: black;
}

, then all arcs drawn in the pane would be black. I didn't test that, but it is my understanding of how it works.

The Arc rule is a CSS type selector, so .drawing-pane Arc will select any arcs which have been drawn in the drawing pane.

Create CSS rules for specific types of child nodes

Now, to differentiate different arcs to have different styles, you need to have an additional, more specific, CSS rule which applies the specific style.

So, if you create the following rule:

.drawing-pane .child-arc {
-fx-stroke-line-cap: BUTT;
}

, then all of the arcs which are added to the drawing pane which also have the style class child-arc assigned to then will get a butt cap. They will also have a black stroke as the previous drawing-pane Arc rule still also applies to them (through CSS inheritance).

Associate your nodes with appropriate CSS rules

There are various ways you could associate the child-arc class with an arc, for example with a factory method:

Arc createChildArc() {
Arc arc = new Arc();
arc.getStyleCass().add("child-arc");
}

Or via inheritance by setting the style in a constructor:

public class ChildArc extends Arc {
public ChildArc() {
getStyleClass().add("child-arc");
}
}

Using CSS type selectors rather than class selectors

Note: it is possible to use a type selector (no . prefix and refers to a simple, non-package prefixed Java class name) rather than a css class selector (uses a . prefix), so you could do:

public class ChildArc extends Arc {}

and have CSS as:

.drawing-pane ChildArc {
-fx-stroke-line-cap: BUTT;
}

But, in general, the css style classes are probably a bit more flexible and also in more common usage then the type selectors, so I'd probably just stick with the class selectors.


I'm not really sure if this is the answer you really wanted, but it is my understanding of one way to solve the problem you currently have.

I think what you are really looking for is the info on SASS outlined below, though, in general it isn't how the problem would be solved when using straight CSS without additional tooling.

Using SASS to add object-oriented inheritance to CSS

If you use a pre-processor such as SASS on your css style sheets, you can bring a lot more features (from SASS) into your style sheets. The features that SASS supports include mix-ins and extensions for CSS styles. So SASS makes CSS more object oriented in how it defines its styling rules, by allowing object-oriented style inheritance of style information.

Whether you want to invest the time and assume the complexity to learn SASS and implement it into your build chain is up to you. Personally, for myself, I wouldn't use SASS unless I were writing an awful lot of CSS, which I just don't do.

The standard default css for JavaFX (modena.css), is large, complex and feature rich, and does not make use of SASS style features in its implementation. Studying modena.css is the best way to learn JavaFX CSS best usage practices and principles. If SASS isn't required for something as complicated as modena.css, then it is unlikely to be really necessary for the CSS stylesheets you create for your application.

CSS inheritance: How to override inherited values

I figured it out and I thought this might help others.

Adding an asterix to my parent element did the trick:

.A * {
background-color: transparent;
}

This way the change in the parent element is picked up by the nested children aswell.

Prevent CSS inheritance to children of the selected element

Some CSS properties are inherited and you can't prevent that.

Inheritance propagates property values from parent elements to their children.

Some properties are inherited properties, as defined in their
property definition table. This means that, unless the cascade results
in a value, the value will be determined by inheritance.

However, you can override that by selecting the children and restoring the desired value.

.wrapper > ul:first-child > li:last-child {  color: red;}.wrapper > ul:first-child > li:last-child > * {  color: initial;}
<div class="wrapper">  <ul>    <li>Lorem</li>    <li>Ipsum</li>    <li>Dolar</li>    <li>Style me!      <ul>        <li>Lorem</li>        <li>Don't style me!</li>      </ul>    </li>  </ul></div>

How to prevent inheritance of any css style of parent node to child node?

There is no generic way. You need to set a value (other than inherit) for every property that has inherit as the default value.

Even that won't prevent all influence.

e.g.

 body { width: 300px; }
div { width: auto; }

The width of the div is influenced by the width of the body.

How do I prevent CSS inheritance?

As of yet there are no parent selectors (or as Shaun Inman calls them, qualified selectors), so you will have to apply styles to the child list items to override the styles on the parent list items.

Cascading is sort of the whole point of Cascading Style Sheets, hence the name.

How to prevent css inheritance?

You selector is correct and its rule-set applies only to the immediate divs of the .parent element. The problem is with the color property, because color is an inherited property. So all elements inside .parent > div will have color: red, even if they are spans, sections etc.

An easy approach to deal with that is to set all divs with some color, and then add your selector. But as you can see in the example below all the elements inside our target div have their color as red, apart from the ones that we have set them elsewhere.

div {
color: black;
}

.parent > div {
color: red;
}
<div class="parent">
<div> DIV A
<div> DIV B </div>
<span> SPAN </span>
</div>
</div>


Related Topics



Leave a reply



Submit