I'm new Angular, CSS and Html.
I have used MatTabsModule(import { MatTabsModule } from '#angular/material/tabs';) to create tabs but I'm able to adjust/change height, background etc. In short I'm not able to override default properties of MatTabsModule's classes. Please help me.
Below is my CSS and Html code. I hope Typescript code is not needed.
HTML: -
<mat-card>
<mat-card-content>
<mat-tab-group class="tab-group" dynamicHeight>
<mat-tab *ngFor="let obj of tags">
<ng-template mat-tab-label>{{ obj.name }}</ng-template>
<div class="tab-content">
{{ obj.name }}
</div>
</mat-tab>
</mat-tab-group>
</mat-card-content>
CSS: -
.tab-group {
border: 1px solid #e8e8e8;
margin-bottom: 30px;
.unicorn-dark-theme & {
border-color: #464646;
}
}
.tab-content {
padding: 16px;
}
mat-card{
padding: 0px;
}
.mat-tab-label .mat-ripple {
min-width: 0;
height: 30px;
}
I'm not able to change height width background colour of these tabs.. :(
You cannot access the styles of child components from your css-file as the ViewEncapsulation.Emulated prevents styles from leaking to the rest of the app (as it should, don't change it).
If you use the ng-deep-selector like this: :host ::ng-deep mat-tab { ... } you can override default material styles that cannot be configured in any other way. I say that because making css leak from a component is considered a bad practice and if possible you should use #Input to pass on styles.
By the way, the :host is there so the styles leak only to this components children and not to the rest of the app
To override default style of angular material elements you need to prefix ::ng-deep in CSS style.
This is how you can control height and width of tabs
::ng-deep .mat-tab-label{
height: 27px !important;
min-height: 0px!important;
margin: 3px!important;
}
Related
I am using angular material sidenav for some application settings functionality to achieve something like we have in Google.
The difference is I am calling this sidenav from another component and wrapping the router too so that it should open below the application Header.
<mat-sidenav-container class="main-sidenav">
<app-sidenav></app-sidenav>
<router-outlet></router-outlet>
</mat-sidenav-container>
The problem is when I open the sidenav It does not disable the background. It should automatically implement the backdrop style. Is there any way I can explicitly provide some style for the same or should we consider some different component? Please suggest. Below is the sample stackblitz example for the same scenario
Stackblitz link
Set the hasBackdrop flag to true in your html:
<mat-sidenav-container class="main-sidenav" hasBackdrop="true">
<app-sidenav></app-sidenav>
<router-outlet></router-outlet>
</mat-sidenav-container>
Per Material doc of sidenav:
Using your stackblitz, I have confirmed the backdrop renders by inspecting the elements:
But you are not seeing the dark shadow, because of missing css. To fix this, add following in your styles.css file.
.mat-drawer-backdrop {
background-color: rgba(0, 0, 0, 0.6);
}
Also, to make the sidenav appear like the screenshot in your question, you need to add some css properties in sidenav class.
.sidenav {
margin-top: 35px;
margin-left: 25px;
display: block;
width: 200px;
height: 100%;
position: fixed;
background: #FFF;
}
Result:
Stackblitz Demo
I am using an imported component which I can't change.
This component has a lot of nested divs.
Somewhere deep in these divs, I need to add a bottom margin to it.
Via Chrome DevTools, I am able to add the margin in one of the divs and achieve the
margin I want. But unable to get it to work when I try to add my css into my scss file.
How can I do this?
const MyComponent = props => {
return (
<div>
{/* This component is not in my control. I can't modify this component*/}
<ImportedComponent/>
</div>
);
};
When I see it in Chrome DevTools, the CSS is something like this.
If I were to add a margin style near the aCssClass or within the block of aCssClass via Chrome,
I get the margin I need. But as said, able to achieve in Chrome DevTools, but not via my scss file.
<div class="my-own-class">
<!-- This is all coming from ImportedComponent, each div has some css class -->
<div>
<div>
<div class="aCssClass anotherClass"> <!-- i want to be able to add my margin here, able to do it but only via Chrome dev tools-->
<div>
<div>
Some data
</div>
</div>
</div>
</div>
</div>
</div>
These are the styles I tried which makes no difference.
.my-own-class {
margin-bottom : 1em;
}
.my-own-class > div:nth-child(3) {
margin-bottom : 22px;
}
.my-own-class body .aCssClass {
margin-bottom: 22px;
}
body .aCssClass {
margin-bottom: 22px;
}
body > .aCssClass {
margin-bottom: 22px;
}
.my-own-class .aCssClass {
margin-bottom: 22px;
}
.my-own-class > .aCssClass {
margin-bottom: 22px;
}
Screenshot
At the highlighted portion, I added margin-bottom 10px under body .sc_marginRight_0 on the right panel which works.
i think it's just a specificity problem, try adding !important and it will work just fine.
.my-own-class .aCssClass {
margin-bottom: 22px !important;
}
I am trying to modify the primeng p-calendar, but it is not working properly.
For example:
I want it to be like this:required changes
But original it looks like this:original image
What i have tried so far:
HTML
<div class="nxui-form-group">
<label for="planEndDate">
<img src="assets/images/calendar.svg" class="nxui-icon-small nxui-icon-align-bottom">
{{ 'i18n.all-damage-reports.label.plan-end-date' | translate }}
</label>
<p-calendar formControlName="planEndDate"
class="calendar-control"
id= "planEndDate"
[title]="'i18n.all-damage-reports.label.plan-end-date' | translate"
[dateFormat]="'i18n.common.dateformat.shortdate-p-calendar' | translate"
[locale]="'i18n.common.dateformat.calendar' | translate"
></p-calendar>
</div>
CSS
p-calendar.calendar-control {
opacity: 1;
color: black;
background: #eeeeee;
}
looking forward to inputs.
Thanks
I think that you should use the special selectors of angular to change a component style like :host or ::ng-need, you can check that in the official documentation:
https://angular.io/guide/component-styles
::ng-deep body .ui-datepicker .ui-datepicker-header .ui-datepicker-title {
margin: 0;
padding: 0;
line-height: 1;
color: goldenrod;
}
::ng-deep .ui-datepicker .ui-datepicker-group {
background-color: cadetblue;
}
Hope that'll help you !
In my case, I want to style the calendar icon, html is below
<div class="main-container">
<p-calendar showTime="true" hourFormat="12" [showIcon]="true"></p-calendar>
</div>
Then I added style below but it is not working:
.main-container ::ng-deep .ui-datepicker-trigger.ui-button {
// add style here
}
Then I added p-calendar after ::ng-deep it worked
.main-container ::ng-deep p-calendar .ui-datepicker-trigger.ui-button {
// add style here
}
Did you try to change the styling classes?
See https://www.primefaces.org/primeng/#/calendar (section styling)
Like for example
.ui-calendar .ui-inputtext {
// place text styling here
}
Select element class via using Inspect then add ::ng-deep selector to force style on child components
::ng-deep .ui-inputtext {
/* Example */
opacity: 1 !important;
}
The code you see in the templates is not what actually is in browser's DOM. There are some other elements injected, like <input> for text input.
Try something like
p-calendar.calendar-control input {
border: 1px solid black;
background: #eeeeee;
}
And anyway, look at the actual elements in your browser with Inspect Element and write CSS according to the real situation.
I am trying to make a hover effect on a div with a Angular ngClass directive. In the template file I have a div element with class "list-item-container' which contains a div with class "list-item" that is iterated with a *ngFor directive. Inside the "list-item" div element I have three divs with class "list-item-column" which are placed horizontally like a table row with inline display. in the div with "list-item" class I have placed a mouseenter and mouseleave event listeners which calls hoverListItem() in my .ts file. the hoverListItem() function changes the value of listItemHovered variable to true or false. In the "list-item" class I have a ngClass directive which triggers a css class 'list-item-highlight' based on the value of listItemHovered boolean value which then changes to background to a different color.
The problem I'm facing is that upon hovering mouse pointer on the "list-item" div all my "list-item" divs are affected instead of the one I am hovering over. How to solve this problem?
.html file
<div class="list-item-container">
<ng-container *ngFor="let opportunity of dealService.opportunities">
<div [ngClass]="{'list-item-highlight': listItemHovered}" class="list-item" (mouseenter)="hoverListItem()"
(mouseleave)="hoverListItem()"
(click)="selectOpportunity(opportunity)">
<div
class="list-item-column">{{opportunity.account?.name === null ? "N/A" : opportunity.account.name}}</div>
<div class="list-item-column">{{opportunity.requirementTitle}}</div>
<div class="list-item-column">{{opportunity.salesValue | number: '1.0-2'}}</div>
</div>
</ng-container>
</div>
.css file
.list-item-container{
overflow: auto;
width: 100%;
max-height: 500px;
}
.list-item{
font-size: 15px;
border-radius: 10px ;
margin-top: 5px;
height: 50px;
background: lightgray;
color: black;
}
.list-item-highlight{
background: #7e00cc;
color: white;
}
.list-item-column{
height: inherit;
vertical-align: center;
display: inline-block;
width: 33.33%;
padding-left: 40px;
}
.ts file
hoverListItem() {
this.listItemHovered = !this.listItemHovered;
}
Right now you're creating and modifying listItemHovered flag inside component context, rather you should maintain a flag for each item level, which could help to easily identify wheather component has been highlighted or not.
[ngClass]="{'list-item-highlight': opportunity.listItemHovered}"
(mouseenter)="hoverListItem(opportunity)"
(mouseleave)="hoverListItem(opportunity)"
Component
hoverListItem(opportunity) {
opportunity.listItemHovered = !opportunity.listItemHovered;
}
Though I'd recommend to use :hover pseudo class if requirement is just to highlight the element on hover. That can be easily doable by changing CSS rule. This way could save several change detection cycle to be ran.
.list-item:hover {
background: #7e00cc;
color: white;
}
I would suggest use a directive to listen to the hover event on the target element and attach the class:
#Directive({
selector: '[hoverDir]'
})
export class HoverOverDirective {
#HostListener('mouseenter') onMouseEnter() {
this.elementRef.nativeElement.class = 'list-item-highlight';
}
#HostListener('mouseleave') onMouseLeave() {
this.elementRef.nativeElement.class = 'list-item-not-highlight';
}
}
Or the easiest way is to make use of CSS pseudo property :hover and use it as below:
.list-item:hover {
background: #7e00cc;
color: white;
}
In my polymer project , i use a vaadin-combobox in two page like this:
- page1: i create a custom combobox style file and import to my page:
<link rel="import" href="../elements/base/vaadin-text-field-custom-radius-theme.html">
content of this file:
<dom-module id="vaadin-text-field-custom-radius-theme" theme-for="vaadin-text-field">
<template>
<style>
[part="input-field"] {
border-radius: 2px;
background-color: white;
border: 1px solid #808080;
height: 100%;
font-family: "Roboto", sans-serif !important;
color: #4c4c4c !important;
padding-left: 10px;
font-size: 14px;
box-sizing: border-box;
max-height: 100%;
background-color: transparent;
background-image: none !important;
}
[part="value"] {
border: 0px !important;
box-shadow: none !important;
height: 100%;
box-sizing: border-box;
max-height: 100%;
background-color: transparent;
text-align: var(--cmb-align,left);
}
.vaadin-text-field {
height: 100%;
box-sizing: border-box;
max-height: 100%;
}
.vaadin-text-field-container {
height: 100%;
box-sizing: border-box;
max-height: 100%;
}
#media(max-width:1024px){
[part="input-field"] {
font-size: 12px !important;
padding-left: 5px;
}
[part="value"] {
font-size: 12px !important;
}
}
</style>
</template>
In page2 ,I have another custom style file with some other css properties.
I use
this.set('route.path',"/page2")
to redirect from page1 to page2 and then use
this.set('route.path',"/page1")
in page2 to return page1.
At this time my combobox in page1 is styled by css defined in custom file that i have imported to page 2 ( while i expected it's still styled by css in vaadin-text-field-custom-radius-theme.html").
Can some one tell me why?
p/s:I tried implement the suggestion of Anton Platonov, but i found that if my page 2 don't import any custom style file, When i return from page2 to page1, the default style of vaadin-text-field that defined in ..\bower_components\vaadin-text-field\vaadin-text-field.html is used for my combobox instead of my vaadin-text-field-custom-radius-theme.html.
If i remove style default in vaadin-text-field.html, my combobox revice css from browser's default style, still not my vaadin-text-field-custom-radius-theme.html.
It's treated like my vaadin-text-field-custom-radius-theme no longer exists.
And if i refesh my page 1, everything become normal.
this is my combobox code:
<vaadin-combo-box-light style="width:100%;height:30px" id="cmdCompanyName" class="fix-size combobox" label="" allow-custom-value items='[[companies]]'
value="" item-label-path="name" item-value-path="id" attr-for-selected="id" on-keyup="searchData"
on-custom-value-set="searchData2" on-value-changed="searchData2">
<vaadin-text-field style="width:100%;height:30px;" class="cmb-text-field" maxlength="150">
<iron-icon class="prefix" icon="icons:search" slot="prefix"></iron-icon>
<iron-icon class="suffix toggle-button" slot="suffix" icon="icons:expand-more"></iron-icon>
</vaadin-text-field>
</vaadin-combo-box-light>
I assume, your project is a Single Page Application, and you use <app-route>/<iron-pages> or a similar routing. This way the browser actually uses a single real document, which is then manipulated to achieve "pages" and navigation.
Due to technical limitations, theme style modules for Vaadin components are not dynamic in the way you expect. Once themes and components are loaded and initialised, their styles become memoized in the classes of their corresponding components.
Suppose you load "page2" first. After loading, <vaadin-text-field> memoizes its styles, and more theme modules can be applied. That is why when you navigate to "page1", <vaadin-text-field> will continue using the memoized style from "page2".
This means, you have to use same set styles in all the instances of, e. g.,
<vaadin-text-field>, in the document. Therefore, you have to use other means to make them look differently, instead of swapping styles. Here are some options.
Scoping :host() selectors
Prefix all the custom theme styles with a scoping :host() selector, for example:
<dom-module id="my-text-field" theme-for="vaadin-text-field">
<template>
<style>
:host(.no-radius) [part="input-field"] {
border-radius: 0;
}
</style>
</template>
</dom-module>
Then use in the html:
<h3>Default appearance</h3>
<vaadin-text-field></vaadin-text-field>
<h3>No-radius class</h3>
<vaadin-text-field class="no-radius"></vaadin-text-field>
Custom CSS properties
Define a custom CSS property in the <vaadin-text-field>’s parent DOM scope, e. g., in a page component:
<dom-module id="page-1">
<template>
<style>
:host {
--custom-radius: 4px;
}
</style>
<vaadin-text-field></vaadin-text-field>
</template>
</dom-module>
<script>
Polymer({is: 'page-1'});
</script>
You can also define some other value for the main document scope:
<custom-style>
<style>
html {
--custom-radius: 0;
}
</style>
</custom-style>
Use the defined custom CSS property in the theme style module for <vaadin-text-field>:
<dom-module id="my-text-field" theme-for="vaadin-text-field">
<template>
<style>
[part="input-field"] {
border-radius: var(--custom-radius);
}
</style>
</template>
</dom-module>
Then see the results:
<h3>Main document appearance:</h3>
<vaadin-text-field></vaadin-text-field>
<h3>Page 1 appearance:</h3>
<page-1></page-1>
See also: https://github.com/vaadin/vaadin-themable-mixin/wiki/4.-Scoping-Styles-in-a-Theme-Module