In my styles.scss i am importing the bootstrap variables, and did a testing it works.
#import '~bootstrap/scss/_functions.scss';
#import '~bootstrap/scss/_variables.scss';
#import '~bootstrap/scss/mixins/_breakpoints';
$grid-breakpoints: (
sm: 768px,
md: 768px,
lg: 1024px
);
$container-min-widths: (
sm: 768px,
md: 768px,
lg: 1024px
);
#import "~bootstrap/scss/bootstrap";
#include media-breakpoint-down (sm) {
body{
background: green;
}
}
#include media-breakpoint-between (md, lg) {
body{
background: blue;
}
}
#include media-breakpoint-up (lg) {
body{
background: gray;
}
}
But my question is, if i use the app.component.scss - still is it require to import all the variables again?
without import i tried, like:
#import '../../styles.scss'
#include media-breakpoint-down (sm) {
body{
background: green;
}
}
#include media-breakpoint-between (md, lg) {
body{
background: blue;
}
}
#include media-breakpoint-up (lg) {
body{
background: gray;
}
}
But got error like :
ERROR in ./src/app/app.component.scss
Module build failed (from ./node_modules/sass-loader/lib/loader.js):
#include media-breakpoint-down (sm) {
^
Media query expression must begin with '('
in D:\IBO\POC\ibo\src\app\app.component.scss (line 3, column 1)
i 「wdm」: Failed to compile.
can't we download all app specific requirement at once? or what is the correct approach?
This is how css encapsulation works in Angular, if you want to use SASS functions (like #include, #extend) in your scss with external #mixins or styles, you'll need to import these external files every time.
This is not a great practice though as it bubbles the amount of produced css in the final html page (every time you #import a file, it's whole content is copied). So a better approach would be to put some common styles in your styles.scss and use them through the whole app.
In your example I don't understand why you need to do the same in app.component.scss? Is it just for testing? You shouldn't need to - it should be enough putting common styles (like yours) in styles.scss and they should be applied to the whole application. Just make sure your style.scss is added to your angular.json file under the styles section. Something like:
"styles": [
"src/styles.scss"
]
Hope that helps.
Related
I am developing a Twilio Flex plugin using Flex Ui version 2 (beta.1 and beta.2).
I wanted to add multiple tabs to TaskCanvasTabs and tried to write the following code.
import React from 'react';
import { Tab } from '#twilio/flex-ui';
import { FlexPlugin } from '#twilio/flex-plugin';
import SmsPanel from './components/SmsPanel/SmsPanel';
import IncomingVideo from './components/IncomingVideo/IncomingVideo';
const PLUGIN_NAME = 'SendSmsV2Plugin';
export default class SendSmsV2Plugin extends FlexPlugin {
constructor() {
super(PLUGIN_NAME);
}
/**
* This code is run when your plugin is being started
* Use this to modify any UI components or attach to the actions framework
*
* #param flex { typeof import('#twilio/flex-ui') }
*/
async init(flex, manager) {
const options = {
align: 'end',
};
flex.TaskCanvasTabs.Content.add(
<Tab label='SMS' key='sms-panel-tab-key'>
<SmsPanel key='sms-panel-component' />
</Tab>,
options,
);
flex.TaskCanvasTabs.Content.add(
<Tab label='Video' key='video-panel-tab-key'>
<IncomingVideo key='incoming-video-component' />
</Tab>,
options,
);
}
}
When executed, the first Tab (SMS) added will be duplicated as shown below. Thereafter, each time I select the first Tab, Call tab, etc., the first Tab added will be increased.
Can someone please tell me if the specification does not allow adding multiple tabs to TaskCanvasTabs or how to solve this problem?
I also tried with Flex Ui version 2 (beta.3) but the behavior is the same.
It seems that this issue only happens when you try to add multiple tabs on TaskCanvasTabs
To resolve this issue you could add a Tab Group which contains Tabs
flex.TaskCanvasTabs.Content.add(
<Flex.Tabs key="custom-tabs-group">
<Flex.Tab key="conversation-note-tab" label="Conversation Notes">
<ConversationNote key="conversation-note" />
</Flex.Tab>
<Flex.Tab key="label-to-conversation" label="Conversation Label">
<AttachLabelToConversation key="add-label-to-conversation" />
</Flex.Tab>
</Flex.Tabs>,
{}
);
Use this css to adjust the tab group text
/* Added CSS for merged TaskCanvasTabs into Tabs group start */
.Twilio-TaskCanvas .Twilio-TaskCanvas-default .Twilio-TaskCanvasTabs div[data-test="customer-tab-header"]:has(> div > button) button {
width: 100%;
height: 100%;
}
.Twilio-TaskCanvas .Twilio-TaskCanvas-default .Twilio-TaskCanvasTabs div[data-test="customer-tab-header"]:has(> div > button) button:hover {
background-color: unset;
}
.Twilio-TaskCanvas .Twilio-TaskCanvas-default .Twilio-TaskCanvasTabs div[data-test="customer-tab-header"]:has(> div > button) button div svg {
display: none;
}
.Twilio-TaskCanvas .Twilio-TaskCanvas-default .Twilio-TaskCanvasTabs div[data-test="customer-tab-header"]:has(> div > button) button div:after {
content: "Conversation Actions";
font-size: 14px;
font-weight: 600;
color: rgb(96, 107, 133);
padding-bottom: 6px;
}
/* Added CSS for merged TaskCanvasTabs into Tabs group end */
I heard the best solution.
TabPros is using the optional uniqueName prop instead of the key for identifying the selected tab.
So, I changed my code below. It was fixed.
flex.TaskCanvasTabs.Content.add(
<Tab label='SMS' key='sms-panel-tab-key' uniqueName='sms-panel-tab'>
<SmsPanel key='sms-panel-component' />
</Tab>,
options,
);
flex.TaskCanvasTabs.Content.add(
<Tab label='Video' key='video-panel-tab-key' uniqueName='video-panel-tab'>
<IncomingVideo key='incoming-video-component' />
</Tab>,
options,
);
The link referenced is below.
https://github.com/twilio/flex-plugin-builder/issues/327
I'm trying to customize mat-select with multiple checkboxes.
for some reason the panel get wrong min-width as below:
and I don't know where its calculating this min-width.
also I tried to add panelClass and override the min-width from this class,
for example:
<mat-select #multipleSelect (selectionChange)="selectItem($event.value)" panelClass="multiple-panel" multiple>
&.multiple-panel {
min-width: 200px !important;
}
but when opening the dropdown its open with the original width (like in the pic) and after few millisecond"jump" to the custom min-width defined on the panel class.
I find the mat-select very hard to style. anybody knows how to solve this problem?
You can style your mat-select dialog box by giving a panel class (as you mentioned).
Please follow this demo : https://stackblitz.com/edit/angular-matselect-style?file=src/styles.css
to see the styled mat-select components.
Reason :
Reason for the delay is that angular for dialog-boxes, create a cdk-overlay-pane inside the cdk-overlay-container container, So in case of mat-select it provides a min-width of 180px, which is overridden by our panel class in the slight delay.
Yes, there is a slight delay in opening of dialog box and customizing its width to the specified width provided in the panel class. But the delay is acceptable in the project that i was working on. So, you can find the demo for styling the mat-select component, as i have provided 2 components and you can modify any css properties.
Try to use styles using ::ng-deep or :host >>>, if not finding any luck, please paste the styles in style.css.
Update 1 :
Tried css animations, and opacity for making smooth opening of the mat-select options.
.panel-class-applied-on-mat-select {
animation-name: opacityDelay !important;
animation-duration: 0.3s !important;
}
#keyframes opacityDelay {
0% {opacity: 0;}
25% {opacity: 0;}
50% {opacity: 0;}
75% {opacity: 0;}
100% {opacity: 1;}
}
Updated StackBlitz Demo
I used another approach.
Just added this piece of code to global style.
.mat-select-panel {
// some your code
&.ng-animating {
visibility: hidden;
}
}
You can try this solution on
DEMO StackBlitz.
Hack with opacity did not fix jumping width when select is closing.
You'll need to change viewEncapsulation to none at your component decorator.and then add following css to remove the transition effect.Have a look at viewencapsulation in angular docs https://angular.io/guide/component-styles#view-encapsulation.
#Component({
selector: 'app-selector',
templateUrl: './template.html',
styleUrls: ['./template.css'],
encapsulation: ViewEncapsulation.None
})
//CSS
.cdk-overlay-connected-position-bounding-box .cdk-overlay-pane .mat-select-panel.ng-animating {
display: none;
}
Try this way : define a panel class for your mat-select in the code and then in the global/app styling file just add:
.panel-class-name .mat-select-panel {
// add your styling here
}
It worked for me to add some component specific styling for material components.
Please go easy on me S.O. This is my first time contributing. :)
After debugging the console, and running into this issue. Solutions were not clear online. So I'm posting mine here in case someone else runs into this.
I found that there is a width permanently set for the infix class. If you unset it, and optionally add some padding to the right of the value, you'll find that will resolve the issue. Add :host for encapsulation when using ::ng-deep.
Important to Note: ::ng-deep is being permanently deprecated after Angular v14.
There is a property in the #Component() annotation called encapsulation which can be used to turn off the view encapsulation for the component instead of using ::ng-deep.
Solution for the deprecation of ::ng-deep:
#Component({
selector: 'app-selector-name',
template: `<div>Hello World!</div>`,
encapsulation: ViewEncapsulation.None,
styles: [
`
:host mat-form-field .mat-form-field-infix {
width: unset;
}
:host mat-form-field .mat-select-value {
padding-right: 0.5rem; /* 8px */
/* Alternatively, for TailwindCSS: #apply pr-2 */
}
:host .random-class {
/* some encapsulated styling... */
}
.another-random-class {
/* some non-encapsulated styling... */
}
`
]
})
Solution if you do not care about the deprecation of ::ng-deep:
:host ::ng-deep mat-form-field .mat-form-field-infix {
width: unset;
}
:host ::ng-deep mat-form-field .mat-select-value {
padding-right: 0.5rem; /* 8px */
}
rails 4.1.8, sass-rails 5.0.1, sass 3.4.10, sprockets-rails 2.2.4, sprockets 2.12.3
this is what the top of my application.scss looks like:
/*
*= require_self
*= depend_on_asset "myicons.eot"
*= depend_on_asset "myicons.woff"
*= depend_on_asset "myicons.ttf"
*= depend_on_asset "myicons.svg"
*= depend_on_asset "foo/bar.jpg"
*/
#import "normalize-rails";
#import "bourbon";
#import "grid_settings";
#import "neat";
#import "bitters/base";
This is what bitters/base looks like:
#import "variables";
#import "extends";
#import "typography";
#import "forms";
#import "tables";
#import "lists";
#import "flashes";
#import "buttons";
this is what the top of _typography.scss looks like
#import url(https://fonts.googleapis.com/css?family=Roboto:400,300,500,700);
#import url(https://fonts.googleapis.com/css?family=Roboto+Slab:400,300,500,700);
body {
color: $base-font-color;
font-family: $base-font-family;
font-size: $base-font-size;
-webkit-font-smoothing: antialiased;
line-height: $base-line-height;
font-family: $sans-serif;
}
And this is what the top of the generated application.css looks like
#charset "UTF-8";
/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
/**
* 1. Set default font family to sans-serif.
* 2. Prevent iOS text size adjust after orientation change, without disabling
* user zoom.
*/
#import url(https://fonts.googleapis.com/css?family=Roboto:400,300,500,700);
#import url(https://fonts.googleapis.com/css?family=Roboto+Slab:400,300,500,700);
/* line 9, /Users/john/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/normalize-rails-3.0.1/vendor/assets/stylesheets/normalize-rails/normalize.css */
html {
font-family: sans-serif;
/* 1 */
-ms-text-size-adjust: 100%;
/* 2 */
-webkit-text-size-adjust: 100%;
/* 2 */
}
Problem: note how in the generated css, the two #import url(... font lines are injected amongst the normalize.css
What could be causing this? I don't even know where to begin investigating.
According to the CSS spec, #import rule must be the first rule in the document (except the #charset rule).
And Sass likes to produce valid CSS files, so it pushes all #imports to the top.
i am trying to convert the background images currently being used within my navigation to a sprite to save on http requests, though im getting the following error
content: "\000a Sass::SyntaxError: Undefined mixin 'navigation-sprite'.\000a (in \002f home\002f html\002f teammngt\002f app\002f assets\002f stylesheets\002f navigation.css.scss)";
scss file
#import "compass";
#import "navigation/main/*.png";
a {
display: table-cell;
/* #header_main height + 1, to move it 1px into the header_main strip */
height: 61px;
width: 120px;
#include navigation-sprite(bg-normal);
//background: url('navigation/main/bg-normal.png') no-repeat;
/* Concerning fonts/text */
line-height: 26px;
/* Concerning text align */
text-align: center;
vertical-align: bottom;
for sure im doing something wrong here, but im not having much luck working it out
#import "compass";
#import "navigation/main/*.png";
#include all-main-sprites;
use like this:
#include main-sprite(bg-normal);
I'm quite new to this, but i cannot figure out the problem.
In twitter bootstrap i would use :
<div class="row-fluid">
<div class="span2">Column1</div>
<div class="span6">Column2</div>
</div>
And it all works fine. But i do not want to write spanX and spanY directly into my html file, rather i would like to give meaningful class names, for example:
<div class="user-container">
<div class="user-filter">First Column</div>
<div class="user-list">Second Column</div>
</div>
Given the fact, that i'm using https://github.com/thomas-mcdonald/bootstrap-sass, how should i write my scss file? I've tried the following, and it does not work (two columns are not displayed):
#import "bootstrap";
#import "bootstrap-responsive";
.user-container {
#extend .row-fluid;
}
.user-filter {
#extend .span2;
}
.user-list {
#extend .span10;
}
If i look at the generated code, it seems to me that everything should be ok:
/* line 164, ../../../../../.rvm/gems/ruby-1.9.3-p125/gems/bootstrap-sass-2.0.0/vendor/assets/stylesheets/bootstrap/_mixins.scss */
.span2, .user-filter {
width: 140px;
}
and so on.
What am i doing wrong?
UPDATE:
ok, just to be clear what is wrong - the columns are laid out as rows (one after another) rather like true columns (one next to each other), eg.:
with bootstrap: Column1 Column2
with my custom classes:
First Column
Second Column
I've inspected the elements layout in Chrome and it seems that bootstrap classes have float property, and mine - no. Looking at css source i see classes like this:
[class*="span"] {
float: left;
margin-left: 20px;
}
So in my case i think it should generate something like :
[class*="user-filter"] {
float: left;
margin-left: 20px;
}
or not?
It's your use of #extend, or rather, Sass' inability to deal with wildcard class matching, which is rather unsurprising, since it gets rather complex.
Bootstrap uses a number of what I might refer to as 'nonstandard' methods to address some classes. You've mentioned one of those in your post above - [class*="span"].
Naturally, when you use #extend x, Sass is extending the x class. Unfortunately, it (currently) has no way of knowing that a wildcard matcher also affects the output of the class. So yes, in an ideal world, [class*="span"] would also be extended to define [class*="span"], .user-filter, but Sass can't currently do that.
While extending .row-fluid is enough to include the rules nested underneath it wrt. the span classes, as per above, it won't adjust the wildcards for extended spans.
bootstrap-sass already had a mixin for fixed width columns/rows, makeRow() and makeColumn(). I've just pushed a makeFluidColumn() mixin, that, well, makes a fluid span. Your code would then become:
.user-container {
#extend .row-fluid;
}
.user-filter {
#include makeFluidColumn(2);
}
.user-list {
#include makeFluidColumn(10);
}
Unfortunately (as per usual) it's not quite so simple. Bootstrap uses this snippet to reset the margin on the first spanx class that is a child of the row.
> [class*="span"]:first-child {
margin-left: 0;
}
However, we cannot redefine this for each call of makeFluidColumn, and so we must manually set no margin-left on any element that will be the first child of a fluid row. It's also worth noting that mixing spanx classes and makeFluidColumn classes will cause the first spanx class to have its margin reset, regardless of whether it's actually the first column in the row.
Your code would therefore be
.user-container {
#extend .row-fluid;
}
.user-filter {
#include makeFluidColumn(2);
margin-left: 0; // reset margin for first-child
}
.user-list {
#include makeFluidColumn(10);
}
It's not a particularly pretty solution, but it works, and is all to do with how Bootstrap uses wildcard class matching, as you gathered in your question update. I've only just pushed this to the 2.0.2 branch, so you'll have to use Bundler with Git to install it, but I'm hoping for a release in the next couple of days.
You are right. Twitter is pushing an ani-patter here. See this article.
http://ruby.bvision.com/blog/please-stop-embedding-bootstrap-classes-in-your-html
Using boostrap-sass 2.3.2.2 gem I had to create my own mixin based on bootstrap's mixins to make CSS classes act like bootstrap .span classes.
// private mixin: add styles for bootstrap's spanX classes
#mixin _makeFluidSpan($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth) {
#include input-block-level();
float: left;
margin-left: $fluidGridGutterWidth;
*margin-left: $fluidGridGutterWidth - (.5 / $gridRowWidth * 100px * 1%);
#include grid-fluid-span($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth);
}
// thats what you should use
#mixin makeFluidSpan($gridColumns) {
#media (min-width: 980px) and (max-width: 1199px) {
#include _makeFluidSpan($gridColumns, $fluidGridColumnWidth, $fluidGridGutterWidth);
}
#media (min-width: 1200px) {
#include _makeFluidSpan($gridColumns, $fluidGridColumnWidth1200, $fluidGridGutterWidth1200);
}
#media (min-width: 768px) and (max-width: 979px) {
#include _makeFluidSpan($gridColumns, $fluidGridColumnWidth768, $fluidGridGutterWidth768);
}
&:first-child {
margin-left: 0;
}
#media (max-width: 767px) {
float: none;
display: block;
width: 100%;
margin-left: 0;
box-sizing: border-box;
margin-bottom: 20px;
&:last-child {
margin-bottom: 0;
}
}
}
example:
.like-span3 { // this class acts like .span3
#include makeFluidSpan(3);
}