I have a couple Angular components spread out over multiple files, created using ng generate.
Some components have inline styles, since the html/styles can be quite small so it makes sense to use inline templates here.
The issue is that I'd like to translate a couple of these 'multi-file' components to inline styles - is there a way to do this within the Angular ecosystem?
You should go in .ts file of the component and inside of the #Component decorator change the templateUrl to template, and styleUrls to styles. Then you can delete .html and .scss files and transfer their code in .ts file.
#Component({
selector: 'app-custom-component',
template: `<div>Your component inline HTML.</div>`,
styles: ['div { text-align: center; }']
})
If you want to generate a component with inline templates and styles, you can do that with passing --inlineTemplate=true --inlineStyle=true option to the CLI when generating the component:
ng generate component custom-component --inlineTemplate=true --inlineStyle=true
Related
How can we apply css files or import css files conditionally in angular.
Note: We should have multiple css files and on condition it should apply the css file to the angular component.
In how many ways can we achieve it? any approach could be usable.
You can use ngClass directive:
<div id="mydiv" [ngClass]="{'myCSSclass' : condition}"></div>
I'm trying to do something specific but can't find any information about it.
What I'm trying to do is make a common angular library with my styled components (size, font, ..) and then import this library in 2 different projects, so far so good.
But now I want the 2 projects to have different color/font/icon themes.
So I need a way to define the theme in the parent projects, and then gets applied to the styling of the library components.
This way al my components in the library can stay the same (single code base) and it can be used in different applications with there house style.
Is there a way to do this?
Kind regards,
P90K
Create an Angular Library
To create a Angular library you can follow the guide here. You've to publish it on npm and install on your projects.
Style your Library
1. Change Style Encapulation with ViewEncapsulation
Read More
Defines template and style encapsulation options available for Component’s Component. By using ViewEncapsulation.None you are exposing your styles to outer components.
import { Component, ViewEncapsulation } from '#angular/core';
#Component({
...
encapsulation: ViewEncapsulation.None,
...
})
Note: This can help to override any component CSS but be sure to use proper selectors
2. Use :host
Read More
The host can help to override CSS without touching the view encapsulations.
CSS pseudo-class function selects the shadow host of the shadow
DOM containing the CSS it is used inside
Lib in your parent template
<your-component class="custom-component-cls"></your-component>
Lib style in your parent style
:host{
::ng-deep .custom-component-cls{
color: white;
}
}
Problem:
I have an angular app with a lot of components and sub components. These were generated by running ng generate component <component-name> so each one has the same style of component tag:
#Component({
selector: 'app-<component-name>',
templateUrl: './<component-name>.component.html',
styleUrls: ['./<component-name>.component.css']
})
My understanding is that all CSS related to this component should be placed in src/<component-name>/<component-name>.component.css and should be automatically applied to the component when it is rendered.
This does not seem to be the case however, as when I put certain instructions in that CSS file they are seemingly ignored. The ones that are the most notable offenders so far are things like text-align and any kind of color tag, while tags like font-family or vw/vh work just fine.
On the other hand, when I put my CSS in a file like src/styles.css and place an import in index.html for this file, any CSS I have there applies correctly but applies itself to ALL components. This wouldn't be a problem except some components necessarily share naming conventions, and I have no way to specify that I don't mean [col-id="car"] in table2.component.ts but rather [col-id="car"] in table5.component.ts.
EDIT:
Here is an example of what I'm talking about:
My current grid looks like this:
All cells in a given column share the value of the col-id tag:
My slab-grid.component.css file contains sizing instructions for the grid itself, and a font specifier:
.slab-grid {
width: 45vw;
height: 80vh;
font-family: monospace;
}
I know these apply properly because if I remove the size definition, the grid becomes 1px by 1px, and if I remove the font-family, the whole grid turns back to the normal font as seen below. Column "Thk" does not change back because another grid in another part of the app has the same col-id and the overarching styles.css file contains a definition for [col-id="thk"]:
So in my understanding if I were to add the following statement to slab-grid.component.css
[col-id="yard_seq"] {
text-align: right;
}
I expect I would see column Yard Seq which has col-id="yard_seq" become right aligned. In reality when I add this statement to slab-grid.component.css, nothing changes. If I however go to the primary css file for the project located in src/styles.css and add the same statement, I get the below result:
Question:
Why does my CSS not always apply to the relevant component if placed in src/<component-name>/<component-name>.component.css?
OR
Is there a way to make the elements of src/styles.css only apply to the page when certain components are rendered?
Solution:
I've found an acceptable solution to this issue. If I modify my own /src styles selectors from [col-id="thk"] to use the descendant selector .slab-grid [col-id="thk"], then I can make my styles override the conflicting ones with a !important without editing the conflicting files.
Every component has hes on styles if you want to share the same styles between multiple components you must create a shared CSS file and then import the file on the styles.css or much better solution add the shared CSS files on the angular.json config files.
the styles from the parent component do not apply to the child components.
only and only if you add the same styles on the styles.css or include the file on the angular.json
example
"styles": [
"src/styles.scss",
"src/scss/theme.d.scss",
"src/scss/global-scrollbar.d.scss",
"src/scss/acrylic.scss",
"src/scss/buttons.scss",
],
"scripts": [
"./node_modules/moment/min/moment.min.js"
]
I decided to convert a landing page to an AngularJS website, because I needed to add an admin section. To separate the website section from the admin section, I created two modules: website and admin.
The original website has been made with Bootstrap 3, and has a style.css that is custom CSS for all the Bootstrap and the website in general.
On the Angular version, I can load the website properly after I installed Bootstrap 3, and in the root-level style.css I do the following :
#import './app/website/assets/css/style.css';
The issue is that I don't want this CSS to be loaded for the full website (website + admin). With this configuration, the admin section is also affected by the CSS.
The import only works if it is in style.css. If I move the import to the website module in the root component.css styles won't load at all.
I know it must have something to do something with style scoping and ng-deep.
EDIT: The only way I can have the website load properly with the CSS imports within its own module is :
encapsulation: ViewEncapsulation.None
As of right now, there is no way to import css at the module level. Global styles are applied globally, and the default ViewEncapsulation makes it so that component specific styles don't bleed out to the rest of the app.
If I move the import to the website module in the root component.css
styles won't load at all.
Importing that css at the modules root component only applies the styles to that one component. I also wouldnt look too hard at ng-deep as it is / will be deprecated https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep
Without knowing how many components are in WebsiteModule or what styles.css looks like, I'll present two options.
1) Rename styles.css (could get confusing since it's not going to be global anymore), import it in each of the components in WebsiteModule.
If that turns out to be too tedious (one bazillion components in WebsiteModule), then
2) I would take a good hard look at the styles.css in question, and see what styles should be applied globally.
Turning off ViewEncapsulation should be a last resort IMO.
I was from angularjs, now picking up react. Even I was using angular 1.x which is already component based, but it still has template. But in react the file structure and the way we use to code front end has changed, like instead of spiting files by pages, u make files by component now. It promotes reusability but does that means how we apply the css also changed?
I saw this import { navBar } from 'styles/navbar.css' in navBar.jsx. Hmm how does css work together with JSX? doest navBar css load that file? What webpack plugin is needed for that? does it come from default? I'm using react-create-app by facebook so I didn't know much about config.
You use css-loader and style-loader to include CSS files in your webpack bundle. By default it generates some JavaScript code that creates a style element with the contents of the imported CSS file and appends it to the head element in your index.html.
So you can definitely use external CSS files to style your React components, just make sure that every CSS class is properly namespaced to avoid naming conflicts with the classes of other components.
For example you could adopt the BEM naming scheme. If your component is called NavBar, then the root element of that component might have a className of x-nav-bar (the x prefix is there to avoid clashing with frameworks like bootstrap), and all child elements, if they need to be styled, will then have class names like x-nav-bar__${childName}.
This kind of import { navBar } from 'styles/navbar.css' is not relevant to JSX but to css-loader. This is a webpack loader that handles css, and it supports cssModules, that allows you to encapsulate selector names in order to avoid css leaks.
So, shortly, that import exposes an object with mapping between your selector to unique string (usually an a hash).
For example:
// styles.css
.foo {
color: red;
}
.bar {
color: green;
}
// Component.jsx
import styles from './styles.css';
console.log(styles);
/* This will print something like
{
foo: '_h234jh',
bar: '_234m23'
}
*/