Angular 6 component, apply css to class applied with hostbinding? - css

I normally use a global SCSS file in my apps, but today I wanted to make some scss scoped to just my component.
I have set a class on the component via #HostBinding (of class.card).
I can style items inside my component, such as the caard-body, but how can I apply overrides to this component's card class?
In other words, I have several cards on the page. I have styles that I only want to apply to this card, to make it look different. So I'd like to apply css such as
.card { background-color: violet; }
So that only this card is violet. I want to make this css part of this component, so everywhere I use it it will automatically be a violet card. (In reality I want to more than a simple thing, but you get the idea)
My component TS:
import { Component, Input, HostBinding } from '#angular/core';
#Component({
selector: 'app-reviews',
templateUrl: './reviews.component.html',
styleUrls: ['./reviews.component.scss']
})
export class ReviewsComponent {
#HostBinding('class.card')
true;
#Input()
review;
constructor() {}
}
My Component SCSS:
.card-header {
border: 0;
color: #cf0989;
font-family: 'Helvetica Neue', Arial, sans-serif;
font-size: 2rem;
font-weight: normal;
}
.card-body {
...
}
My component HTML:
<div class="card-header">Testimonials</div>
<div class="card-body">
<div class="review-image">
<img class="rounded-circle"
alt="{{review.acf.article_author.post_title}}"
src="{{review.acf.article_author.acf.image}}">
</div>
<div class="review-content">
<p class="review">
<span [innerHTML]="review.content.rendered"></span>
</p>
<p class="reviewer-name">{{review.acf.article_author.post_title}}</p>
</div>
</div>
The selectors in my CSS for .card-body and .card-header work fine, but I cannot style this .card. Adding this, for example does nothing:
.card { background-color: violet: }
How can I create SCSS selectors in the component's SCSS file that also apply to the class applied to the component via #HostBinding? Can I? Should I?

It looks like I need to use :host, is that correct?
:host {
&.card {
padding: 2rem;
}
}

Related

Vue: Possible to import an scss file with deep selector into the component's scoped styles?

I wanted to find out if its possible to separate a vue component's scoped scss with deep selectors into a another file and have it imported back in?
Example:
// Main.vue
<template>
<div id="main">
<h1>Title</h1>
<span>Text</span>
</div>
</template>
<style lang="scss" scoped>
#main::v-deep {
&>h1 {
font-size: 10rem;
}
&>span {
font-size: 5rem;
}
}
</style>
Could I somehow achieve this:
// Main.vue
...
<style lang="scss" scoped>
#import url('./Main.scss');
</style>
// Main.scss
#main::v-deep {
&>h1 {
font-size: 10rem;
}
&>span {
font-size: 5rem;
}
}
without having this style applied to components that may have id/class="main" anywhere else in the project? Mainly just scoped to this component?
You can use :deep() { #import './Main.scss' } to import whole scss file and it will work for your child components too.

Skip Parent Background in Child class while inherit other properties

I don't want child class to inherit the immediate parent class background color which has background color as white. Instead it should skip and take background color from parent component which is bluebackground. When I use the transparent background in child class it should show blue color not white. Rest of the property of parent (whitebackground class) should be inherited just not the white background in child class.
I cannot do any changes on Parent component just I can do changes using css.
app component :
<div class="bluebackground">
<app-test>
</app-test>
</div>
Component: test
BlueBackGround Start
<div class="whitebackground">
Some White Background Stuff that I need
<div class="child">
Here i want background which should skip the parent whitebackground and show blue color same as bluebackground class <br />
</div>
</div>
BlueBackGround End
Here is the Css
.child {
font-size: 2rem;
text-align: center;
color: green;
background:transparent;
}
.bluebackground{
background: blue;
font-size: 3rem;
}
.whitebackground {
background:white;
}
StackBlitz
https://stackblitz.com/edit/angular-ivy-hbfvjs
You could try to change the CSS to the following
.child {
font-size: 2rem;
text-align: center;
}
.bluebackground {
font-size: 3rem;
}
.whitebackground {
background:white;
color:yellow;
}
.bluebackground, .child {
background-color: blue;
}
Working example: Stackblitz
Update
There is a dirty way to include the CSS selectors from the app component to the child component.
test.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css', '../app.component.css'] // <-- include `app.component.css` here
})
export class TestComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
Now you could use the bluebackground selector in the test component.
test.component.html
BlueBackGround Start
<div class="whitebackground">
Some White Background Stuff that I need
<div class="child bluebackground"> <!-- include `bluebackground` here -->
Here i want background which should skip the parent whitebackground and show blue color same as bluebackground class <br />
</div>
</div>
BlueBackGround End
I've modified your Stackblitz
Update: encapsulation
You could set the encapsulation to ViewEncapsulation.None in the app.component and rename the child selector to bluebackground in the child as well. Try the following
app.component.ts
import { Component, ViewEncapsulation } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
encapsulation: ViewEncapsulation.None // <-- set `ViewEncapsulation.None` here
})
export class AppComponent {
...
}
test.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
test.component.css
/* overwrite/introduce values to the `bluebackground` specific to test component */
.bluebackground {
font-size: 2rem;
text-align: center;
}
.whitebackground {
background:white;
color:yellow;
}
test.component.html
BlueBackGround Start
<div class="whitebackground">
Some White Background Stuff that I need
<div class="bluebackground">
Here i want background which should skip the parent whitebackground and show blue color same as bluebackground class <br />
</div>
</div>
BlueBackGround End
Working example: Stackblitz
Try like this:
<div class="bluebackground">
Blue Background Start
<div class="whitebackground">
Some White Background Stuff that I need
<div class="child bluebackground">
Here i want background which should skip the parent whitebackground and show blue color same as mainbackground class <br />
</div>
</div>
Blue Background End
<div>
Working Demo
Thanks to Michael D for his inputs.
This is how I solved it
I had to move the white background color from whitebackground class to new class called newwhitebackground class.
Html
BlueBackGround Start
<div class="whitebackground">
<div class="newwhitebackground">
Some White Background Stuff that I need
</div>
<div class="child">
Here i want background which should skip the parent whitebackground and show blue color same as bluebackground class <br />
</div>
</div>
BlueBackGround End
CSS
.child {
font-size: 2rem;
text-align: center;
background:transparent;
}
.whitebackground {
color:yellow;
}
.newwhitebackground {
background-color:white;
}
Here is the stackblitz
https://stackblitz.com/edit/angular-ivy-pyhqwr

How to overwrite the vue-bootstrap styles in b-modal

I tried to change the background-color in b-modal -> in .modal-header using bootstrap-vue. But the vue doesn't see my styles and I don know why :/
here is the code. I follow by answer in link
HTML:
b-modal(id="card-1" title="CARTÃO DE CRÉDITO" :modal-class="myclass" header-text-variant="light")
VUE
export default {
data: {
myclass: ['myclass']
},
}
CSS
.myclass > .modal-dialog > .modal-content > .modal-header {
background-color: #da2228 !important;
color: white;
}
But I still doesn't see the results. Modal header is white. Any ideas why?
You're probably using a scoped style tag in your .vue file.
If you are, then you need to use a deep-selector to properly target the subcomponent.
The selectors are /deep/, >>> or ::v-deep.
In the below example i use /deep/, but the others should work for you as well.
You can also use the header-class prop on b-modal to directly add the class to the header if you wish.
<template>
<b-modal header-class="my-class">
<template #modal-header>Header</template>
Hello
</b-modal>
<b-modal modal-class="my-second-class">
<template #modal-header>Header</template>
Hello
</b-modal>
</template>
<style scoped>
/deep/ .my-class {
background: black;
color: white;
}
/deep/ .my-second-class > .modal-dialog > .modal-content > .modal-header {
background: black;
color: white;
}
</style>
You can use content-class="your-class" in the vue bootstrap modal.
<b-modal id="myModal" content-class="your-class" title="BootstrapVue">
Body Content
</b-modal>
Or else it is difficult to style the modal cuz the normal class="" does not apply to the code.

How can I resolve bootstrap variables and reuse them in my own classes?

How can I resolve and reuse variables coming from _variables.scss within my own class (.post-body in this case) so I don't have to add a long list of styles to my html?
This is what the relevant html line looks like:
<div class="col px-5 py-4 post-body">{{{ contents }}}</div>
And this is my stylesheet.scss:
#import "../../../node_modules/bootstrap/scss/functions";
#import "../../../node_modules/bootstrap/scss/variables";
// ...
#import "../../../node_modules/bootstrap/scss/bootstrap";
.post-body {
background-color: #252526;
color: #dddddd;
line-height: 26px;
// Following are my attempts to reuse $box-shadow-lg from _variables.scss
box-shadow-lg; // Invalid syntax
#include box-shadow-lg; // Complains with undefined mixin.
}
Sure I could add them directly, like below: But as the number of modifications grows, the list of classes applied to html will grow as well and result in complexity.
<div class="col px-5 py-4 post-body box-shadow-lg">{{{ contents }}}</div>
You just have to use #extend from scss like this :
.post-body {
background-color: #252526;
color: #dddddd;
line-height: 26px;
#extend .box-shadow-lg;
}
So the styles of .box-shadow-lg would be paste to your .post-body class.
I just figured it out by myself. It seems that I need to #import the mixins. And then use that function.
// ...
#import "../../../node_modules/bootstrap/scss/mixins";
// ...
#import "../../../node_modules/bootstrap/scss/bootstrap";
.post-body {
background-color: #252526;
color: #dddddd;
line-height: 26px;
#include box-shadow($box-shadow-lg);
}

VueJS - Apply a specific CSS style inside a component

I defined styles for my website.
I also include specific content, which is written with a WYSIWYG editor by the users.
This content should have a specific style, but not erase the style of the rest of the website.
I tried using but then no style is applied at all. is there any way to apply a specific style to this content?
<template>
<div id="content">
<div class="content" v-html="content"></div>
</div>
</template>
export default {
name:'content',
props: {
content: {
type: String,
default: '<div>Contenu à définir</div>'
}
}
}
<style scoped>
h1, h2, h3 {
color: #94c946;
margin:0;
font-family: 'Montserrat-ExtraBold';
vertical-align:baseline
button{
font-family: 'Montserrat-ExtraBold';
border-radius: 100px;
background-color: #94c946;
color: #1B1B1B;
}
</style>
The scoped styles in view only work for the elements that are present on the component on the template, but not for dynamic content.
I would recommend you to use some id cascade, for example declare an id for your section like this:
<style>
#content button { .... }
#content h1, #myEditor h2 {....}
</style>
This can be accomplish better using some css preprocessor like sass
<style lang="sass">
#content
button
....
h1, h2, h3
....
</style>

Resources