Pass style description to child component - css

How do I define a style in a parent component and then pass it to a child component e.g.?
<style>
.teststyle {
background-color: red;
width: 100px;
}
</style>
I thought if I did not use scoped the .teststyle would be available to the child, but it didn't work for me.
I can pass the style to use in a v-bind:style command using props cannot find a way to pass (or make available) for use with v-bind:class.
The child component is for re-use by many parent components each parent component with different style/class attributes each with different properties.
In one example the child component is a generic table and it needs things like column widths, cell colors etc.
In another instance the child component is a grid css layout and that needs no, columns, column layout etc.

What I normally do is I try to design the component as simply and cleanly as possible:
Give the root element a sensible class name (e.g. flyout).
Give child elements class names that use the root element's class name as a prefix (e.g. flyout-title, flyout-content, etc). Sometimes I'll abbreviate the root element's class name if it is long (as fly- or whatever).
<div class="flyout">
<div class="flyout-title">{{ title }}</div>
<div class="flyout-content"><slot/></div>
</div>
This is just my own class naming convention, but you can use whatever as long as it's consistent and unlikely to clash with other class names app-wide.
Now, when you use <flyout> as a child component and you want to style it with CSS, you give it a class name specific to the parent component. For example, if your parent component is app-menu then give the flyout the class name app-menu-flyout. Notice that this convention is the same as the aforementioned; always try to be consistent.
<flyout class="app-menu-flyout"/>
In your <style> section of the parent component, you can declare styles for the child component as follows:
.flyout.app-menu-flyout {
/* Root element */
}
.flyout.app-menu-flyout .flyout-content {
/* Child element */
}
I'm using selectors like this so that they are more specific and will override any styles defined on the child component itself. It'll also work regardless of the order in which the CSS ends up being (order may not be guaranteed by Webpack).
Note that this makes the parent and child components tightly coupled regarding the structure of the child component's template and the class names used. If you change the child component's template and/or class names, then you need to change the corresponding CSS in every other component that declares overriding styles for that component.
If you are using scoped CSS, then pay attention to how child components should be styled.

Related

How should a parent style a child component for Angular? I'd like a good solution that won't be deprecated

When I need a component to change slightly for a new use, I've looked at transclusion and multi-slot transclusion vs adding HTML around the component but there are still situations where a component's internal styling needs to be changed.
You can pass a style in as an input, and then set it in the template with [ngStyle].
So for a simple example i'll show how to do this with a background color.
customComponent.html
<div [ngStyle]="{'background-color': data?.backgroundColor }">
<p> the background color will be set from an input </p>
</div>
customComponent.ts
#Input('data')
data: {
backgroundColor: string;
};
parent.html
<customComponent [data]="{backgroundColor: 'grey'}"></customComponent>
Components should be self contained and programmed so they don't require refactoring whenever a new use is needed.
One solution is to add a class to the parent using ng-class, and then use regular css rules to style the child: one set of rules that requires the class to be on the parent div, and another set that doesn’t require the class to be on the parent div.
Example css:
.my_class {Normal styling}
.my_parent_div_class .my_class {Special styling goes here}

In Javafx CSS, does a selector always choose a class?

For example, .button{} selects Button class and .text-area{} selects TextArea class. So when it does that, does that select the entire class itself(opposed to specific instances of a class)? If it does, is there any way for Javafx CSS to select a specific instance of a class or just in general, a variable?
You're selecting every Node containing the style class contained in the location where you apply the css stylesheet.
For some nodes one or more style classes are added, it's also possible to modify them.
someNode.getStyleClass().setAll("my-class");
To select individual nodes though usually a id selector is used:
mySpecialButton.setId("special-button");
CSS
#special-button {
/* TODO... */
}

How to use :host-context selector in an ngClass condition?

I want to set a class active on a div (part of a component) if a variable is true (workspace.active here) AND an ancestor element has class .home.
Something like:
<div [ngClass]="{'active': workspace.active && ':host-context(.home)', }">
Can I use somehow this pseudo selector :host-context in such an conditional expression for ngClass ?
Details:
I want to use same component in two use cases. Only some css properties should be different on the two cases. So I want to customize a css class set on a div on my component based on decision: "there is an ancestor home in the dom tree or not" - this should differentiate the two use cases.
I could do things like this in css:
:host-context(.home) .active {
background-color: #405976;
}
but then all selector combinations containing .active class should be combined also with :host-context and I I don't want to grow the complexity in css as it is already complex.
I would prefer to just set the class .active based on the condition. In css file !, not in code. (This is why :host-context exists in the end.)
In angular you should not make any logical decisions in the code based on the html content properties such as classes or attributes, but vice versa - you should render classes and attributes in html based on data bindings. That's the main idea of angular - rendering view based on data bindings. Component's code should not really care too much about view structure.
So, in this case if your class should be based on some external information you need to #Import() that data through data bindings into your component and then use component properties in the ngClass directive. Yes, it moves logic into the component instead of html/css, but that's where it's supposed to be anyway: in the model/controller code, not in the view markup. Also, this way it will be much more convenient to test such a component.

Target one class of those specified with CSS

I have a div element which has 3 classes:
<div class='captcha_article captcha_email captcha_register'></div>
How can I target the third class for example, without affecting the style of the other two classes in the div?
Also, if I were to have 4 classes, how to target the last one without using last-child property ? Would :nth-child apply here?
You misunderstand CSS.
You can add styles to the captcha_register class by doing this in your CSS file.
.captcha_register {
// Attributes go here
}
Depending on where this is placed in your CSS file will determine if any of the style attributes adding to the captcha_article and captcha_email classes will be affected.
For example:
.captcha_article {
height: 200px;
}
.captcha_register {
height: 100px; // This will override the height of 200px on the div
}
UPDATE
If each class is suppose to represent a different web page then adding them all to the same element might explain why you are seeing unexpected results. It might be better to combine the styles that appear in all classes into one reusable class, lets call it .page. Then on each page you use this you can modify it with another class, if it needs to be modified.

JavaFX: Styling application with CSS Selectors

I have a couple of questions about styling a JavaFX application with CSS Selectors (such as: .table-view for every TableView).
I have created a main CSS-file, in which I want to define the universal style properties for my application. For example: every TableView gets the same color in every screen. I just import the Main.css in every .css that is associated with a .fxml file.
Now I would like to style every HBox in a 'sidebar' the same way. I have tried it like this (as suggested in Oracle's documentation):
.sidebar > .hbox {
/* Just some styling */
}
This is not working to my surprise, but the following pieces of code are working:
.sidebar > HBox {
/* Just some styling */
}
.sidebar HBox {
/* Just some styling */
}
Maybe it has something to do with the fact that .sidebar is a custom style, but I am not sure about this.
So my questions are:
1. Why isn't the first one working?
2. What should be the way to do this? (with .hbox or HBox and > or nothing?)
As you can see in the CSS documentation the HBOX class has no style class defined. Therefore you can't simply use .hbox
http://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html#hbox
If you want to lookup only direct children of the toolbar the > sign can be used. Using the > sign in a CSS selector will have some benefit in performance issues because by doing so not the complete child hierarchy under the Toolbar Control need to be scanned. Matching Nodes will only be searched in the first hierarchy of children.
So if you want to select all buttons that are direct children of a sidebar you can do the following:
. sidebar > .button
But if you really want to style all button in a sidebar (even if they are wrapped in panes, etc.) you need to use the following selector:
.sidebar .button
Back to your HBOX question: Even if the HBOX has no defined style class (.hbox) it has a type that can be used for a type selector. As described in the CSS doc all nodes have a type:
Node's getTypeSelector method returns a String which is analogous to a
CSS Type Selector. By default, this method returns the simple name of
the class. Note that the simple name of an inner class or of an
anonymous class may not be usable as a type selector. In such a case,
this method should be overridden to return a meaningful value.
Because of that the HBOX selector is working.

Resources