KEMBAR78
Componentization css angular | PDF
Componentization:
CSS & Angular
David Amend @
Typical Angular project
https://angular.io/guide/styleguide#overall-structural-guidelines
> ng generate component mycomponent
CREATE src/app/componentB/componentB.component.html (30 bytes)
CREATE src/app/componentB/componentB.component.spec.ts (663 bytes)
CREATE src/app/componentB/componentB.component.ts (290 bytes)
CREATE src/app/componentB/componentB.component.scss (0 bytes)
UPDATE src/app/app.module.ts (10744 bytes)
CSS
- Where?
- Reuse?
- Componentize?
CSS in angular business component
#contact-form {
.navigation-buttons {
height: 71px;
padding-top: 30px;
position: relative;
.c-FormLinkButton {
line-height: 41px;
}
> div {
display: inline-block;
vertical-align: middle;
&:last-child {
position: absolute;
right: 0;
}}}
@media only screen and
(max-width: $mobile-max-width) {
.navigation-buttons {
height: 160px;
.c-FormLinkButton {
height: 50px;
line-height: 50px;
}
.c-MobileButton--secondary {
bottom: 10px;
position: absolute;
> a > span {
display: none;
}}
.c-FormButton--next {
top: 30px;
}}}
.target-form /deep/ {
button {
background-color: #1980d0;
border: 0;
border-radius: 3px;
color: #fff;
cursor: pointer;
font-size: 14px;
font-weight: bold;
font-family: Arial, sans-serif;
height: 39px;
min-width: 156px;
padding: 0 20px;
width: 290px;
}
.cta {
margin: 15px 0 15px 0;
}
}
@media screen and
(max-width: $mobile-max-width) {
button {
font-size: 18px;
font-weight: normal;
height: 50px;
width: 100%;
}
.pq .aw-wrapper-webui-de header.aw-pagehead
.aw-pagehead-meta.aw-bg-is-complex .aw-pagehead-metanav .aw-delimiter button {
color: #FE2E2E
}
Bad CSS quality & no reuse
Agenda
1. Style isolation/WC support by Angular
2. CSS Basic Rules
3. Summary
What is your level of CSS skills?
???
???
???
???
Novice
Expert
Angulars
Emulated View Encapsulation
(no Shadow DOM)
- _nghost-c*
- host-(element)
- host-context(.theme)
- ::ng-deepNative
Emulated
None
Angulars
Emulated View Encapsulation
(no Shadow DOM)
Example: setup
@Component({
selector: 'blue-button',
template: ` <h2>Blue</h2>
<button class="blue-button">click </button>`,
styles: [`
.blue-button {
color: blue;
}
h2 { font-size: 2rem;}
`]
}) export class BlueButtonComponent { }
@Component({
selector: 'app-root',
styleUrls:['./app.component.css'],
template: ` <h2>Buttons</h2>
<button class="red-button">click</button>
<blue-button></blue-button>
`})
export class AppComponent {
...
}
Example: Compiled, ngcontent
<app-root _nghost-c0="">
<h2 _ngcontent-c0="">Buttons</h2>
<button _ngcontent-c0="" class="red-button">Button</button>
<blue-button _nghost-c1="" _ngcontent-c0="">
<h2 _ngcontent-c1="">Blue</h2>
<button _ngcontent-c1="" class="blue-button">click</button>
</blue-button>
</app-root>
<style>
.blue-button[_ngcontent-c1] {
color: blue;
}
h2[_ngcontent-c1] {
font-size: 2rem;
}
</style>
.blue-button {
color:blue;
}
h2 { font-size: 2rem;}
:host(.red) h2 {
color: red;
}
<app-root _nghost-c0="">
<h2 _ngcontent-c0="">Button</h2>
<blue-button class=”red” _nghost-c1="" _ngcontent-c0="">
<h2 _ngcontent-c1="">Button</h2>
...
</app-root>
[_nghost-c1] h2[_ngcontent-c1] {
color: red;
}
:host {
padding: 20px;
}
[_nghost-c1] {
padding: 20px;
}
@Component({
selector: 'themeable-button',
template: `
<button>Themeable Button </button>`
, styles: [`
:host-context(.red-theme) button{
background: red;
}
:host-context(.blue-theme) button {
background: blue;
}`]
}) export class ThemeableButtonComponent {}
<root-context class="blue-theme">
<childs> …
<childs>
<themeable-button></themeable-button>
<childs>
</childs>
</root-context>
.blue-theme[_nghost-c1] button[_ngcontent-c1],
.blue-theme [_nghost-c1] button[_ngcontent-c1] {
background: blue;
}
ng-deep
:host ::ng-deep h2
{
color: black;
}
[_nghost-c1] h2 {
color: black;
}
Native
<app-root _nghost-c0="">
<h2 _ngcontent-c0="">Button</h2>
<blue-button class=”red” _nghost-c1="" _ngcontent-c0="">
<h2 _ngcontent-c1="">Button</h2>
...
</app-root>
Shadow Piercing combinators
https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/13348719/
https://medium.com/@andreygoncharov/edge-hates-you-attributes-d15faf162939
mike k. Oct 10, 2017
Please, increase the priority of the issue.
The thing is Angular 2+ uses attributes to apply emulated
view encapsulation.
So the application performance may slow down when scaling.
Francois R. Jan 8, 2018 MICROSOFT EDGE TEAM
FYI, some performance improvements in this scenario should start to appear in the next release of Edge as we
improved some key scenarios. We don’t want to claim this issue is fixed yet because we aren’t on par with the other
browsers in all scenarios yet, so we will keep this issue open despite the current improvements, and will report any
further improvement towards our goal in the future as we get the opportunity to work on this further.
Web Components: Acceptance & Performance
<input type="date" name="bday">
<gold-cc-cvc-input card-type="amex"></gold-cc-cvc-input>
<progress value="1" max="4"></progress>
Step 2/4
→ iFrame alternative
→ framework-independant components
→ non corporate design
<video>
http://vic.github.io/prefix-css/
.angular-cli.json
"defaults": {
"component": {
"viewEncapsulation":
"None"
}
CSS Encapsulation: When?
.btn .btn-primary
.btn-xs-block
.btn btn-secondary
.cancel-button
.btn
.loading-contact-button
Problems
→ DOM specific rendering
→ no control of your styles
→ unstructured style components
- CSS first components
- Modular & Extendable by SCSS/Less
→ OOCSS
→ BEM
→ SMACSS
OOCSS
Object Oriented CSS
https://css-tricks.com/methods-organize-css/
Keep structure and skin separate
OOCSS: Structure & Style
<a href="#" class="btn btn-primary btn-lg disabled">click</a>
<a href="#" class="login-submit-button-disabled">Yes</a>
Style Structure
.btn {
display: inline-block;
font-weight: $btn-font-weight;
text-align: center;
white-space: nowrap;
vertical-align: middle;
user-select: none;
border: $btn-border-width solid transparent;
@include button-size($btn-padding-y, $btn-padding-x, $font-size-base, $btn-line-height, $btn-border-radius);
@include transition($btn-transition);
@each $color, $value in $theme-colors {
.btn-#{$color} {
@include button-variant($value, $value);
}
}
&.disabled,
&:disabled {
opacity: $btn-disabled-opacity;
@include box-shadow(none);
}
.row {
@include make-row();
}
> .col,
> [class*="col-"] {
padding-right: 0;
padding-left: 0;
}
}
+ Flex
Separate container and content
<div class=”row”>
<span class=”col-8”>Are you sure?</span>
<a href="#" class="col-4 btn btn-primary btn-lg disabled">click</a>
</div>
ContentContainer
<div>
<span style=”width:60%;”>Are you sure?</span>
<a href="#" class="login-submit-button-disabled">Yes</a>
</div>
OOCSS: Container & Content
Depth of Applicability (DOA) → parent dependencies
Specifity → Which rule is actually applied?
button {
padding: 5px;
}
.btn {
padding: 10px;
}
.btn-lg {
padding: 10px;
}
.btn-xxl {
padding: 20px;
}
https://specificity.keegan.st/
https://jonassebastianohlsson.com/specificity-graph/
https://getbootstrap.com/docs/4.0/dist/css/bootstrap.min.css
https://www.hypovereinsbank.de/etc/designs/hypovereinsbank/css/public.min.css
#sidebar div > button {
padding: 10px;
}
#sidebar div > div.border button.lg {
padding: 20px;
}
BEM
Block, Element, Modifier
<button class="btn">
<div class="btn__dropdown">
<a class="btn__dropdown__li
btn--disabled"
href="#">delete</a>
</div>
</button>
.block {}
.block__element {}
.block--modifier {}
<button class="btn">
<div class="btn__dropdown">
<a class="btn__li
btn--disabled"
href="#">delete</a>
</div>
</button>
.btn {}
.btn__dropdown {}
.btn--disabled {}
SMACSS
Scalable & Modular
Architecture for CSS
SMACSS—Scalable and Modular Architecture for CSS
● vendor/
○ _bootstrap.scss
● base/
○ _functions.scss
○ _mixins.scss
○ _variables.scss
○ _base.scss
■ state
● layout/
○ _grid.scss
○ _header.scss
○ _sidebar.scss
● main.scss
● module/
○ _navigations.scss
■ main-nav
● state
■ sub-nav
■ side-nav
○ _buttons.scss
■ state
○ _forms.scss
→ Separation of Style-Components
→ Style-State-directives
→ ViewEncapsulation.None
Use case considerations of CSS architecture
- Small application
- CSS-skills vary in team
- Integrate multiple frameworks
- Static content pages
Recap
- Corporate Design required. Performance restricted.
.angular-cli.json
"defaults": {
"component": {
"viewEncapsulation":
"None"
}
- Separation of Concerns
- /src/shared/styles/grid[fonts] Style Only Components
- /src/core/functions Angular Functional Components
- /src/core/styles/button/button.scss Style Component
- /src/core/styles/button/button.direcive.ts Angular Style-Support Component
- /src/app/ Angular Business Components
- Write Clean CSS code by OOCSS, BEM, SMACSS
Any Questions?

Componentization css angular

  • 1.
  • 2.
    Typical Angular project https://angular.io/guide/styleguide#overall-structural-guidelines >ng generate component mycomponent CREATE src/app/componentB/componentB.component.html (30 bytes) CREATE src/app/componentB/componentB.component.spec.ts (663 bytes) CREATE src/app/componentB/componentB.component.ts (290 bytes) CREATE src/app/componentB/componentB.component.scss (0 bytes) UPDATE src/app/app.module.ts (10744 bytes) CSS - Where? - Reuse? - Componentize?
  • 3.
    CSS in angularbusiness component #contact-form { .navigation-buttons { height: 71px; padding-top: 30px; position: relative; .c-FormLinkButton { line-height: 41px; } > div { display: inline-block; vertical-align: middle; &:last-child { position: absolute; right: 0; }}} @media only screen and (max-width: $mobile-max-width) { .navigation-buttons { height: 160px; .c-FormLinkButton { height: 50px; line-height: 50px; } .c-MobileButton--secondary { bottom: 10px; position: absolute; > a > span { display: none; }} .c-FormButton--next { top: 30px; }}} .target-form /deep/ { button { background-color: #1980d0; border: 0; border-radius: 3px; color: #fff; cursor: pointer; font-size: 14px; font-weight: bold; font-family: Arial, sans-serif; height: 39px; min-width: 156px; padding: 0 20px; width: 290px; } .cta { margin: 15px 0 15px 0; } } @media screen and (max-width: $mobile-max-width) { button { font-size: 18px; font-weight: normal; height: 50px; width: 100%; }
  • 4.
    .pq .aw-wrapper-webui-de header.aw-pagehead .aw-pagehead-meta.aw-bg-is-complex.aw-pagehead-metanav .aw-delimiter button { color: #FE2E2E } Bad CSS quality & no reuse
  • 5.
    Agenda 1. Style isolation/WCsupport by Angular 2. CSS Basic Rules 3. Summary
  • 6.
    What is yourlevel of CSS skills? ??? ??? ??? ??? Novice Expert
  • 7.
  • 8.
    - _nghost-c* - host-(element) -host-context(.theme) - ::ng-deepNative Emulated None Angulars Emulated View Encapsulation (no Shadow DOM)
  • 9.
    Example: setup @Component({ selector: 'blue-button', template:` <h2>Blue</h2> <button class="blue-button">click </button>`, styles: [` .blue-button { color: blue; } h2 { font-size: 2rem;} `] }) export class BlueButtonComponent { } @Component({ selector: 'app-root', styleUrls:['./app.component.css'], template: ` <h2>Buttons</h2> <button class="red-button">click</button> <blue-button></blue-button> `}) export class AppComponent { ... }
  • 10.
    Example: Compiled, ngcontent <app-root_nghost-c0=""> <h2 _ngcontent-c0="">Buttons</h2> <button _ngcontent-c0="" class="red-button">Button</button> <blue-button _nghost-c1="" _ngcontent-c0=""> <h2 _ngcontent-c1="">Blue</h2> <button _ngcontent-c1="" class="blue-button">click</button> </blue-button> </app-root> <style> .blue-button[_ngcontent-c1] { color: blue; } h2[_ngcontent-c1] { font-size: 2rem; } </style> .blue-button { color:blue; } h2 { font-size: 2rem;}
  • 11.
    :host(.red) h2 { color:red; } <app-root _nghost-c0=""> <h2 _ngcontent-c0="">Button</h2> <blue-button class=”red” _nghost-c1="" _ngcontent-c0=""> <h2 _ngcontent-c1="">Button</h2> ... </app-root> [_nghost-c1] h2[_ngcontent-c1] { color: red; } :host { padding: 20px; } [_nghost-c1] { padding: 20px; }
  • 12.
    @Component({ selector: 'themeable-button', template: ` <button>ThemeableButton </button>` , styles: [` :host-context(.red-theme) button{ background: red; } :host-context(.blue-theme) button { background: blue; }`] }) export class ThemeableButtonComponent {} <root-context class="blue-theme"> <childs> … <childs> <themeable-button></themeable-button> <childs> </childs> </root-context> .blue-theme[_nghost-c1] button[_ngcontent-c1], .blue-theme [_nghost-c1] button[_ngcontent-c1] { background: blue; }
  • 13.
    ng-deep :host ::ng-deep h2 { color:black; } [_nghost-c1] h2 { color: black; } Native <app-root _nghost-c0=""> <h2 _ngcontent-c0="">Button</h2> <blue-button class=”red” _nghost-c1="" _ngcontent-c0=""> <h2 _ngcontent-c1="">Button</h2> ... </app-root> Shadow Piercing combinators
  • 14.
    https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/13348719/ https://medium.com/@andreygoncharov/edge-hates-you-attributes-d15faf162939 mike k. Oct10, 2017 Please, increase the priority of the issue. The thing is Angular 2+ uses attributes to apply emulated view encapsulation. So the application performance may slow down when scaling. Francois R. Jan 8, 2018 MICROSOFT EDGE TEAM FYI, some performance improvements in this scenario should start to appear in the next release of Edge as we improved some key scenarios. We don’t want to claim this issue is fixed yet because we aren’t on par with the other browsers in all scenarios yet, so we will keep this issue open despite the current improvements, and will report any further improvement towards our goal in the future as we get the opportunity to work on this further.
  • 15.
    Web Components: Acceptance& Performance <input type="date" name="bday"> <gold-cc-cvc-input card-type="amex"></gold-cc-cvc-input> <progress value="1" max="4"></progress> Step 2/4
  • 16.
    → iFrame alternative →framework-independant components → non corporate design <video> http://vic.github.io/prefix-css/ .angular-cli.json "defaults": { "component": { "viewEncapsulation": "None" } CSS Encapsulation: When? .btn .btn-primary .btn-xs-block .btn btn-secondary .cancel-button .btn .loading-contact-button Problems → DOM specific rendering → no control of your styles → unstructured style components
  • 17.
    - CSS firstcomponents - Modular & Extendable by SCSS/Less → OOCSS → BEM → SMACSS
  • 18.
  • 19.
  • 20.
    OOCSS: Structure &Style <a href="#" class="btn btn-primary btn-lg disabled">click</a> <a href="#" class="login-submit-button-disabled">Yes</a> Style Structure
  • 21.
    .btn { display: inline-block; font-weight:$btn-font-weight; text-align: center; white-space: nowrap; vertical-align: middle; user-select: none; border: $btn-border-width solid transparent; @include button-size($btn-padding-y, $btn-padding-x, $font-size-base, $btn-line-height, $btn-border-radius); @include transition($btn-transition); @each $color, $value in $theme-colors { .btn-#{$color} { @include button-variant($value, $value); } } &.disabled, &:disabled { opacity: $btn-disabled-opacity; @include box-shadow(none); } .row { @include make-row(); } > .col, > [class*="col-"] { padding-right: 0; padding-left: 0; } } + Flex
  • 22.
    Separate container andcontent <div class=”row”> <span class=”col-8”>Are you sure?</span> <a href="#" class="col-4 btn btn-primary btn-lg disabled">click</a> </div> ContentContainer <div> <span style=”width:60%;”>Are you sure?</span> <a href="#" class="login-submit-button-disabled">Yes</a> </div>
  • 23.
    OOCSS: Container &Content Depth of Applicability (DOA) → parent dependencies Specifity → Which rule is actually applied? button { padding: 5px; } .btn { padding: 10px; } .btn-lg { padding: 10px; } .btn-xxl { padding: 20px; } https://specificity.keegan.st/ https://jonassebastianohlsson.com/specificity-graph/ https://getbootstrap.com/docs/4.0/dist/css/bootstrap.min.css https://www.hypovereinsbank.de/etc/designs/hypovereinsbank/css/public.min.css #sidebar div > button { padding: 10px; } #sidebar div > div.border button.lg { padding: 20px; }
  • 24.
  • 25.
    <button class="btn"> <div class="btn__dropdown"> <aclass="btn__dropdown__li btn--disabled" href="#">delete</a> </div> </button> .block {} .block__element {} .block--modifier {} <button class="btn"> <div class="btn__dropdown"> <a class="btn__li btn--disabled" href="#">delete</a> </div> </button> .btn {} .btn__dropdown {} .btn--disabled {}
  • 26.
  • 27.
    SMACSS—Scalable and ModularArchitecture for CSS ● vendor/ ○ _bootstrap.scss ● base/ ○ _functions.scss ○ _mixins.scss ○ _variables.scss ○ _base.scss ■ state ● layout/ ○ _grid.scss ○ _header.scss ○ _sidebar.scss ● main.scss ● module/ ○ _navigations.scss ■ main-nav ● state ■ sub-nav ■ side-nav ○ _buttons.scss ■ state ○ _forms.scss
  • 28.
    → Separation ofStyle-Components → Style-State-directives → ViewEncapsulation.None
  • 29.
    Use case considerationsof CSS architecture - Small application - CSS-skills vary in team - Integrate multiple frameworks - Static content pages
  • 30.
    Recap - Corporate Designrequired. Performance restricted. .angular-cli.json "defaults": { "component": { "viewEncapsulation": "None" } - Separation of Concerns - /src/shared/styles/grid[fonts] Style Only Components - /src/core/functions Angular Functional Components - /src/core/styles/button/button.scss Style Component - /src/core/styles/button/button.direcive.ts Angular Style-Support Component - /src/app/ Angular Business Components - Write Clean CSS code by OOCSS, BEM, SMACSS
  • 31.