ng-select multiple - Change height - css

This is related to the question at ng-select - Change height . I want to do the exact same but with a ng-select that enables multiple items to be selected.
Here is my code of the ng-select:
<label class="col-sm-4 text-sm-right col-form-label">Payout Format</label>
<div class="col-sm-8">
<ng-select
[items]="payoutFormats"
[multiple]="true"
[closeOnSelect]="true"
[searchable]="true"
bindValue="payoutBatchFormatID"
bindLabel="name"
placeholder="All"
[(ngModel)]="filter.payoutFormats"
name="payoutFormats">
</ng-select>
</div>
In my component I have added the following styles:
#Component({
templateUrl: './test.component.html',
styles: [`
.ng-select{
font-size:0.85em;
}
.ng-select .ng-select-container {
min-height: 3px;
}
.ng-select.ng-select-multiple .ng-select-container {
height: 3px;
}
`],
})
I was able to get this working with a non multiple select box by using
.ng-select.ng-select-single .ng-select-container {
height: 20px;
}
But changing it from .ng-select.ng-select-single to .ng-select.ng-select-multiple when multiple is enabled has no effect on the height.
Here is how my select looks like after the CSS:
I need it to be smaller.
UPDATE
In dev tools I can change min-height in .ng-select .ng-select-container as follows:
And my select box appears smaller:
However adding the same style to my component styling does not pick this up:
#Component({
templateUrl: './list-exceptions-handling-payments.component.html',
styles: [`
.ng-select{
font-size:0.85em;
}
.ng-select .ng-select-container{
min-height: 3px;
}
.ng-select.ng-select-multiple .ng-select-container {
height: 3px;
}
`],
})

You have overriden .ng-select-container and .ng-select-multiple which is correct but you hadn't overriden it's children elements.
Multiple select checkboxes have additional elements compared to select element (deselect button, view selected choices, etc)
These are in
<div class="ng-value-container">
<div class="ng-value>
....
ng-value divs contain mendoza and franklin elements:
You need to adjust the height/line-height/margin/padding defined in these children elements.
EDIT:
You need to make your child elements smaller also before the parent element will decrease in size. E.g. in GIF:

Related

MDBootstrap 5 - Class styles not applied to content projected elements

I am working in an Angular 14 app using MDBootstrap 5 and I am building some base components. For this example I am trying to build the List Group.
I have a list-group parent component:
#Component({
selector: 'list-group',
standalone: true,
imports: [CommonModule],
template: `
<ul class="list-group list-group-flush">
<ng-content></ng-content>
</ul>
`,
styles: [],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ListGroupComponent {
}
Along with a list-group-item child component:
#Component({
selector: 'list-group-item',
standalone: true,
imports: [CommonModule],
template: `
<li class="list-group-item">
<ng-content></ng-content>
</li>
`,
styles: [],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ListGroupItemComponent {
}
And I am using them in a card component template:
<list-group>
<list-group-item>
<span class="text-muted">Id: </span>
<span>placeholder</span>
</list-group-item>
<list-group-item>
<span class="text-muted">Name: </span>
<span>placeholder</span>
</list-group-item>
...
</list-group>
The issue is that when using content projection like this, the bootstrap class for list-group-flush does not get applied correctly, or at all. It should remove the top border from the first element and the bottom border from the last element.
If I get rid of the projection and instead place the list items directly inside the list group, then it will apply the css properly.
Additionally, if I try something like adding the following css to the list-group:
::ng-deep li:first-of-type {
border-top-width: 0;
}
::ng-deep li:last-of-type {
border-bottom-width: 0;
}
It will remove the top and bottom border from every element in the list.
I dont understand whats happening and am at a loss here as to why the css will not get applied and am wondering if anyone else has encountered such an issue when using content projection with MDBootstrap or another UI library.
Research Update
This is not the ideal solution, as i want to be able to just apply the list-group-flush class and use its styling instead of having to override and apply my own.
However, by adding the following to the list-group-item component:
:host {
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid rgba(0,0,0,.125);
}
:host:last-of-type {
border-bottom: 0;
}
It has accomplished what I wanted, and it will suffice for now. For anyone else on this path, this article was very insightful.
I would still like any feedback though if there are solutions to get the bootstrap class to apply to my projected content.

CSS media query print:

Doing a page, html result like:
<div class="container table-page">
<div class="selected-block"> some info here </div>
<h1>Table header</h1>
<div class="notice-calc print-shown">Notices !</div>
<table class="input-data">...</table>
<button class="js-btn-add-row">Add row to a input table</button>
<button class="js-calculate">Calculate table values</button>
<div class="js-waiting" style="display: none;">Progress bar</div>
<table class="calc-result" style="display:none;">...</table>
</div>
Main idea of styles below - hide every direct children of '.container' except tables and some table elements with class="print-hidden" will be hidden too. For print version of page using rule:
#media print {
.container> :not(table),
.print-hidden {
display: none;
}
.print-shown {
display: block;
}
}
Later added notices must be shown at print version too, but it does not appear. Nevertheless if edit '.print-shown' rule like:
.container .print-shown {
display: block;
}
Then it shows. Tested in Chrome 88.0.4324.190 (Official Build) (64-bit)/ Dev.Firefox 86.0b9 (64x)/ Opera 74.0.3911.107. And Edge shows it in both cases.
Why single class selector does not work here?
It is because of this selector:
.container > :not(table)
It targets all direct children of .container (which is not a table). This also includes children with the .print-shown-class.
So, when you have a .print-shown element as a child of .container, the .container > :not(table) has presedence over the .print-shown class (because the first selector is more specific than the latter)

Select "toolbar-title" within shadow root of ion-title via css

In Ionic, the ion-title component has the content encapsulated in an extra div within its shadow-dom.
This div has the class .toolbar-title set. How can i select this div via scss-selector to change its overflow behavior?
I tried:
.toolbar-title { ... }
ion-title .toolbar-title
ion-title::shadow .toolbar-title { ... }
ion-title::shadow(div) { ... }
and a lot other combinations including :host & ::ng-deep selectors.
And, yes i know , ::shadow and ng-deep is deprectaded.
I also know that ionic has introduced css-variables for this purposes, but unfortunatley not for the overflow attribute.
THX in advance!
The concept of shadowDOM is you can't touch its content with CSS from the outside.
It is an open shadowDOM, so you can change it with JavaScript.
document.querySelector("ion-title")
.shadowRoot
.querySelector(".toolbar-title")
.style
.overflow = "initial";
Ionic v6 allows you to target and modify shadowDOM contents with CSS. See https://ionicframework.com/docs/theming/css-shadow-parts
However, the element you want to select inside the shadowDOM needs to expose a part attribute. For instance the ion-select element:
<ion-select>
#shadow-root
<div part="placeholder" class="select-text select-placeholder"></div>
<div part="icon" class="select-icon"></div>
</ion-select>
You can select the placeholder element with:
ion-select::part(placeholder) {
color: blue;
opacity: 1;
}
Unfortunately, the ion-title element does not expose any shadow parts. You need to wrap the contents of ion-title in a container to be able to modify them:
<ion-title>
<div class="content">
<img src="..." />
Hello World!
</div>
</ion-title>
CSS:
.content {
display: flex;
align-items: center;
}
StackBlitz example: https://stackblitz.com/edit/ionic-title-modification-8a1qst

How styling works over components in angular?

Question is not clear but I'll break it down. In angular we can write isolated css for styling. It works pretty well for native html elements. But unlike react, angular wrap our html with custom elements like <app-card>...</app-card>. When I write css for those wrapper elements, it doesn't work .
If I have a post list like
<div class="post-list">
<app-card [post]="post" *ngFor="let post of posts"></app-card>
</div>
If I write css to apply some vertical gap between app-card components in PostListComponent. Well nothing happens.
.post-list app-card:not(:last-child) {
margin-bottom: 2rem;
}
How can I make it work? Or with angular logic, how can I apply vertical gap between angular components
Just add display: block; on your app-card component & it will work as expected.
.post-list app-card {
display: block;
}
.post-list app-card:not(:last-child) {
margin-bottom: 2rem;
}
<div class="post-list">
<app-card>Card 1</app-card>
<app-card>Card 2</app-card>
<app-card>Card 3</app-card>
</div>
You can define encapsulation: ViewEncapsulation.None in your Component like this:
#Component({
selector: 'foo',
template: './foo.component.html',
styleUrls: ['./foo.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class FooComponent { }
Which will treat your .css as the same if you were putting it in the global scope.
To be more accurate, it won't append .fooComponent to each css rule in foo.component.scss.
You can make the iteration in div tag then add your class
<div class="post-list">
<div class="post" *ngFor="let post of posts">
<app-card [post]="post"></app-card>
</div>
</div>
And in your css
.post-list .post:not(:last-child) {
margin-bottom: 2rem;
}
There is no reason it shouldn't work. Just tried to put in some of your code here. https://stackblitz.com/edit/angular-scss-demo-icqrye
app.component.html
<div class="post-list">
<app-new *ngFor="let item of [1,2,3,4]"></app-new>
</div>
styles.scss
.post-list app-new:not(:last-child) p {
margin-top: 2rem;
color: green;
}
And it works perfectly. Are you looking for something else?
And if you want to add the style (margins) to the component directly, you will first need to set the display of the component to block/flex as per requirement.
.post-list app-new:not(:last-child) {
display: flex;
}

Selector Specificity Not Overriding Bootstrap

I am trying to override the right property for a h1 element that it is inheriting from the carousel-caption bootstrap class. It inherits right:15% and I am trying to set it to 0%. I found another post that led me to add id="bootstrap-overrides"to the tag and then use the selector: #bootstrap-overrides h1.second but this still doesn't remove the property. I check also in the inspect element and this property is not crossed out. When I uncheck this property in the inspect element I am left with the behaviour I desire.
code from React component:
<div id="initialImage">
<img src={logo} alt="Failed to load Image" class="img-fluid" />
<div class="carousel-caption greeting">
<h1 class="first">First.</h1>
<h1 class="second">Second.</h1>
</div>
</div>
CSS:
#bootstrap-overrides h1.second {
right: 0%;
float: right;
font-family: "Rock Salt", cursive;
color: #fff2f4;
}
and as mentioned I have an id #bootstrap-overrides in the body tag of my index.html. Could it have something to do with the location of the import for boostrap?
Just to confirm, are you adding id="bootstrap-overrides" directly to the h1?
If so, your css should look like this: h1#bootstrap-overrides otherwise, if you are applying it to the parent of h1, then try adding important to your css like so: #bootstrap-overrides h1 { right: 0!important; }

Resources