Styling one element with multiple selectors (sass) - css

I've an element I want to style only if it's got two classes applied to it:
custom-select-value--companies
and
custom-select-value--companies-disabled
It's actually the pseudo element I want to style, and the following css works:
.custom-select-value--companies.custom-select-value--companies-disabled::after { // Styles }
It's probably very simple, but I was just struggling to translate that to sass and was hoping someone could help? The following doesn't work:
.custom-select-value {
&--companies.&--companies-disabled::after {
// Styles
}
}
Also, just wondered as I was writing this - what's the main element of a pseudo element called? "Parent" doesn't seem quite right?
Thanks

Managed to get it working by typing the second selector out in full:
.custom-select-value {
&--companies.custom-select-value--companies-disabled::after {
// Styles
}
}

Related

CSS hierarchy to allow a class to trigger styles to all siblings without that class

First - sorry for the title - if you have a better suggestion as to what it should be named then please let me know.
I'm not sure if this is possible in the CSS hierarchy.
I have multiple elements and each one can have a .show class added to it, to show the the content.
I'd like to set a rule, so if the .show class has been added - any of the same element without (.show) it are then hidden.
My current not working attempt is to use:
.team_item {
display: grid;
&.show {
&:not(.show){
display: none;
}
}
So the logic would be:
element - should be visible
element + show class - element & inner content visible
element + show class - all elements without the show class should be hidden (display: none).
But I think I am trying to go back up the hierarchy in the CSS (scss).
Any help would be great.
Note: I'm fully aware that I can write JS to tackle this issue but was looking for a css (scss) solution.
I believe it needs to be along those lines:
$team-item-display:'block';
.wrapper {
#function hideElement() {
$team-item-display:'none';
#return 0;
}
&.show{
hideElement()
}
&:not(.show){
display:$team-item-display;
}
}
The direction of the solution is in calling a function that will set a different value of a variable that elements with no .show class use.
I havent tested the code. Hopefully it works.

Pierce component style globally

I need to pierce the styles of my component from the global styles.scss file.
Basically, I've used mat-card component wrapped in a custom-component. In
some cases, I want to change styles to the mat-card when a custom-component is preceded by another custom-component
The idea would be:
global-styles.scss
custom-component ~ custom-component::ng-deep {
.mat-card {
background-color: red;
}
}
The host-context seemed like a good idea, I tried it this way
custom-component.scss
// does not work
host-context(~custom-component) { background-color: red; }
I've tried this and some other combinations, but they don't seem to work. How are we supposed to use the >, ~, + selectors to style angular components?.
Cheers
Personally I avoid piercing selectors at all costs. It breaks the entire component model, and tightly couples code.
I would approach this in a slightly different way. I would have my custom-component have an optional Input() embedded = false
Your usage could be as follows:
// top level
<custom-component></custom-component>
// nested level
<custom-component [embedded]="true"></custom-component>
Then use ngClass with the embedded property to trigger the color change.
See docs for more info on ngClass
https://angular.io/api/common/NgClass
Ok not a solution for this, but there's one thing to consider.
If you want to apply styles to your component using the selector your-component, you have to set display: block; property in your component :host. I totally missed this, but it would look like this:
your-component.css
:host {
display: block;
}
your parent component css
your-component ~ your-component {
margin-top: 15px;
}
And it works. My problem was originally related to that.

HIghlighting row during runtime

I am trying to highlight a row based user input. I am using Angular 5, with ag-grid-angular 19.1.2. Setting the style with gridOptions.getRowStyle changes the background, but I would rather use scss classes if possible. The function setHighlight() is called in the html file through (change)=setHighlight()
setHighlight() {
const nextChronoId = this.getNextChronoDateId();
// this.highlightWithStyle(nextChronoId); // Working solution
this.highlightWithClass(nextChronoId);
const row = this.gridApi.getDisplayedRowAtIndex(nextChronoId);
this.gridApi.redrawRows({ rowNodes: [row]})
}
Function definitions:
highlightWithStyle(id: number) {
this.gridApi.gridCore.gridOptions.getRowStyle = function(params) {
if (params.data.Id === id) {
return { background: 'green' }
}
}
}
highlightWithClass(id: number) {
this.gridApi.gridCore.gridOptions.getRowClass = function(params) {
if (params.data.Id === id) {
return 'highlighted'
}
}
}
My scss class:
/deep/ .ag-theme-balham .ag-row .ag-row-no-focus .ag-row-even .ag-row-level0 .ag-row-last, .highlighted{
background-color: green;
}
My issue
Using getRowClass does not apply my highlighted class correctly to the rowNode. After reading (and trying) this, I think that my custom scss class overwritten by the ag-classes. The same problem occurs when using rowClassRules.
Question
How can I make Angular 5 and ag-grid work together in setting my custom scss class correctly?
Stepping with the debugger shows the class is picked up and appended to the native ag-grid classes.
In rowComp.js:
Addition, screen dump from dev tools:
angular's ViewEncapsulationis the culprit here.
First be aware that all shadow piercing selectors like /deep/ or ::ng-deep are or will be deprecated.
this leaves, to my knowledge, two options.
use ViewEncapsulation.None
add your highlighted class to the global stylesheet
setting ViewEncapsulation.None brings its own possible problems:
All components styles would become globally available styles.
I would advise to go with option two.
this answers sums it up pretty well.
Additionally:
.ag-theme-balham .ag-row .ag-row-no-focus .ag-row-even .ag-row-level0 .ag-row-last
this selector will never match anything, you should change it to
.ag-theme-balham .ag-row.ag-row-no-focus.ag-row-even.ag-row-level0.ag-row-last
every class after ag-theme-balham exists on the same element.
with the selector you wrote, you would denote a hierarchy.
Hope this helps

BEM: adding modifier to already existed modifier

I'd been confused by simple scenario when I was working with BEM.
There is a base button in example:
.button {
// styles for button
}
and its modifier with more specific styles:
.button.button_run {
// additional styles for this type of button
// i.e. custom width and height
}
One moment I realize that I need modifier for button_run, let's name it like button_run_pressed:
.button_run_pressed {
// more styles, i.e. darker background color
}
The problem is that it's not correct to name the last element as I did above button_run_pressed according to BEM conventions. But I need to add "pressed" styles only to "run" button, not for all buttons by writing class like button_pressed and mixing modifier button button_run button_pressed.
How should I refactor my code to match BEM conventions?
According to http://getbem.com/naming/, the modifier classes are initiated with two hyphens (--). So a modifier for .button should look like
.button--modifier { /* ... */ }
In your case, I would suggest choosing the following names:
.button {}
.button--run {}
.button--run-pressed {}
Notice, that I also decoupled the modifier classes from the block class, which is more according to BEM rules. You want to avoid creating classes which depend on others to work.
Since you added less as a tag to the post, here's how this could look in less or scss:
.button {
// button styles
&--run {
// modified styles
}
&--run-pressed {
// more modifiers
}
}
This would result in the classnames I wrote above
Firstly, the name should be .block--modifier or .button--run
If you want it only works with both modifier run and press, you should name it as
.button.button--run.button--pressed
Hope this help

Is there a way to group CSS selectors for clarity?

If I have a dozen CSS selectors, and want to assign :hover properties to all of them, I'm used to doing this:
selector, selector2, someOtherSelector, someSelector div {
//some properties
}
selector:hover, selector2:hover, someOtherSelector:hover, someSelector div:hover {
//some properties
}
Typing :hover four times seems redundant. Is there a way to group the selectors like
(selector, selector2, someOtherSelector, someSelector div):hover {
//some properties
}
instead?
Not natively in CSS. By using something like SCSS, you can write:
selector, selector2, someOtherSelector, someSelector div {
// some properties
&:hover {
// some more properties
}
}
If they all share the same hover properties you could create a class that is shared for all that defines your :hover
So you'd get:
allSelectors, selector, selector2, someOtherSelector, someSelector div {
//some properties
}
allSelectors:hover {
//some properties
}
Re-usable classes makes for cleaner and less code.
Sadly, there's not really any easier way of doing what you're trying to do, unfortunately. Unless you want to move the styles to jQuery or something (but that's not a good solution).

Resources