8

Plunker with the problem I'm having. "If you comment out the styles in the ThirdComponent you can see it affect the parent and sibling components' styles." – adriancarriger (Thank you Adrian)

In my component I'm using...

styles: ['
    @import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";
    @import "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/css/bootstrap-datetimepicker.min.css";
']

but it seems to ruin the style of any component that call this one. I only need the style in this one component. I thought Angular 2 components were totally independent, can't figure out why this one changes my whole web app.

Component:

import { Component, OnInit } from '@angular/core';
import datetimepicker from 'eonasdan-bootstrap-datetimepicker';
import moment from 'moment';


@Component({
    selector: 'date-time-picker',
    styleUrls: ['../../../css/datetimepicker.css'],
    template:` 
                    <div class="input-group">
                        <input class="form-control" 
                        a2e-datetimepicker
                        [date]="date"
                        [options]="a2eOptions"
                        (onChange)="dateChange($event)"
                        (onClick)="dateClick()"
                        />
                        <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
                    </div>
    `
})
export class DateTimePicker implements OnInit {

  date: moment.Moment;
  a2eOptions: any;

  dateChange(date) {
    this.date = date;
  }

  dateClick() {
    console.log('click click!')
  }

  getTime() {
    alert('Selected time is:' + this.date);
  };

  addTime(val, selector) {
    this.date = moment(this.date.add(val, selector));
  };

  clearTime() {
    this.date = null;
  };

  constructor(){
        this.date = moment();
        this.a2eOptions = {
            format: 'dddd, MMMM Do YYYY, h:mm a',
            //sideBySide: true,
            stepping: 5
        };
  }

  ngOnInit(): void {
    console.log(datetimepicker);
  }

}

datetimepicker.css

@import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";
@import "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/css/bootstrap-datetimepicker.min.css";

Same results if I do it this way:

template:` 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/css/bootstrap-datetimepicker.min.css">

Using systemJS

15
  • Can you post your component as well ? Commented Dec 23, 2016 at 22:56
  • Your component encapsulation should be Emulated or Native Commented Dec 23, 2016 at 22:56
  • There's the component at the moment. Commented Dec 23, 2016 at 23:02
  • No way this is bleeding out , are you sure you haven't imported this styles anywhere else ? Like in your app or index.html or somewhere else ? Commented Dec 23, 2016 at 23:18
  • 1
    Here's a minimal plunker example.. if you comment out the styles in the ThirdComponent you can see it affect the parent and sibling components' styles. Commented Dec 24, 2016 at 0:50

1 Answer 1

4

View encapsulation in regards of component styles works by extending your existing selectors with a custom attribute added by angular.

Example:

The host element becomes <my-thrid-component _nghost-dra-1>.
All its children become e.g. <h3 _ngcontent-dra-1>.

Angular now takes your css selectors and extends them:

h3 { ... } becomes h3[_ngcontent-dra-1] { ... }, so your styles only apply to elements in the component itself.

Now back to the extending your existing selectors part.
When you @import an external file, its content is not fetched - the file will be loaded as an external resource and therefore angular can not modify it.

Taking a look at the generated style tag, reveals, what's actually happening:

<style>
  @import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";
  @import "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/css/bootstrap-datetimepicker.min.css";

  h1[_ngcontent-dra-1],
  h2[_ngcontent-dra-1],
  h3[_ngcontent-dra-1] {
    background: red;
  }
</style>

Conclusion: There is no such thing as nested imports, therefore imported styles are applied globally. If your really want to include the styles only for a specific component, you need to have them locally available, so angular can read its content and extend the selectors.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.