CSS styles from Angular 2 components spilling outside of their boundaries

Check out the Plunker where I'm facing an issue. "If you comment out the styles in the ThirdComponent, you can see it affecting the parent and sibling components' styles." – adriancarriger (Special thanks to Adrian)

Within my component, I am incorporating...

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";
']

However, it appears to disrupt the styling of any component that references this one. I only intend for the style to apply to this specific component. I was under the impression that Angular 2 components were completely independent, so I am puzzled as to why this particular component is impacting the entire 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";

Similar outcomes occur if implemented 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">

Utilizing systemJS

Answer №1

Component styles in Angular utilize view encapsulation to modify existing selectors by adding a custom attribute.

For example:

The host element is transformed into

<my-thrid-component _nghost-dra-1>
.
All child elements become like <h3 _ngcontent-dra-1>.

Angular adapts your css selectors by extending them:

h3 { ... } becomes h3[_ngcontent-dra-1] { ... }, ensuring the styles are only applied within the component.

Focusing on the aspect of modifying existing selectors,
When you @import an external file, its content remains untouched - as it's treated as an external resource and cannot be altered by angular.

An examination of the resulting style tag sheds light on this process:

<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>

In conclusion: Nested imports don't exist, hence imported styles are globally applied. To restrict styles to a specific component, they must be available locally for angular to access and extend the selectors accordingly.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Arrange the side by side display of uploaded image previews

Could someone please assist me with aligning my image upload preview in a row, similar to a brand/partners slider? The current preview output is not displaying as desired. Here is the code I have: <div class="image-gallery"> <div class ...

Incorporating Angular module into the mean.io bundle

Need help with adding the angular-ui-grid module to a mean.io package: $ cd packages/custom/mypackage $ npm install angular-ui-grid --save To import the JS, add this line to packages/custom/mypackage/public/index.js: import 'angular-ui-grid'; ...

What is the best way to merge multiple nested angular flattening operators together?

I am facing a challenge in utilizing the outcomes of Observables from various functions. Some of these functions must be executed sequentially, while others can run independently. Additionally, I need to pass the result of the initial function to some nest ...

The impact of angles on drop shadows in CSS3

Is there a way to replicate the shadow effect seen on the slider at using pure CSS? I've managed to recreate it in Photoshop, but I'm hoping to achieve the same result through CSS for a cleaner solution. ...

Tips on rearranging the location of a div element within a directive

I have created a custom directive that displays two divs, Div1 and Div2, with a splitter in the middle: Splitter Image Now, I am looking for a way to swap the positions of these two divs dynamically using an Angular directive. I thought about using ng-swi ...

Tips for making markers act responsively

Recently, I put together a collection of rain radar images that can quickly show whether rain is on the way or not. As you resize the URL window, the two pictures positioned side by side will also shrink. For an illustration, check it out here ... Each p ...

Error encountered while running "ionic cordova run android" command

Recently, I revisited my Ionic Cordova app after a few months and encountered an unexpected dependency issue when attempting to make a minor adjustment to the app. Although the app previously functioned correctly, even reverting all changes failed to addre ...

Looking for a way to add shadow effects to mat-rows in Angular

Is it possible to bring box shadow while hovering in a table using CSS? I noticed that the bottom border seems to block the shadow from displaying, except for the last one. Has anyone tried using mat-elevation in this scenario, and if so, were you able to ...

Unable to get 100% height to work properly in HTML5 ASP.net because of the DOCTYPE

I'm currently working on creating an Asp.net website with a unique single-page portfolio style for the homepage. Each project or section should be 100% height of the viewport, stacked underneath each other to make use of anchor tags. However, I'm ...

Customize Swiper js: How to adjust the Gap Size Between Slides using rem, em, or %?

Is there a way to adjust the spacing between slides in Swiper js using relative units such as 2rem? The entire page is designed with relative units. All measurements are set in rem, which adjusts based on the viewport size for optimal adaptability. For i ...

Angular2 - Access to fetch at 'https://example.com' from

Requesting some guidance on integrating the forecast API into my angular2 application. Currently facing a Cross-Origin Error while attempting to access the API. Any suggestions on resolving this issue? search(latitude: any, longitude: any){ consol ...

"Dealing with Angular 9's mat-table and the pesky ExpressionChangedAfterItHasBeenChecked

I am facing an issue with my Angular 9 component that has multiple mat-tables. One of the tables contains rows with input fields bound to a reactive form array. While binding the table to the form array works well, I encounter an error when loading the for ...

Enhance your HTML5 video by incorporating strategically placed buttons (images) as an overlay

Recently, I embedded a video: <video preload muted autoplay loop id="sty"> <source src="content/1/sty.mp4" type="video/mp4"> </video> To make this video full-width, I made sure to set the CSS properti ...

Converting a file into a string using Angular and TypeScript (byte by byte)

I am looking to upload a file and send it as type $byte to the endpoint using the POST method My approach involves converting the file to base64, and then from there to byte. I couldn't find a direct way to convert it to byte, so my reasoning may be ...

What is the best way to transfer information within the same webpage?

https://i.sstatic.net/umfln.pnghttps://i.sstatic.net/9W6ZE.pngI'm just starting out with angular 2/4 projects and I have a popup search tab in the interface that displays an editable list. However, I am unsure about how to transfer data to the main i ...

Having issues with my Angular 4 + MVC web application not functioning properly in Internet Explorer

After creating an application using Angular 4 and MVC, I noticed a problem specifically with Internet Explorer. The application runs smoothly on Chrome, Firefox, and other browsers except for IE. Does anyone have any suggestions on how to resolve this br ...

Alter the CSS display based on the user's userAgent if they are using an iPhone and window.navigator.standalone is set to true

Looking to create a unique webAPP with different content displays based on how it is accessed. If the user opens the webAPP through their Safari browser Or if they open the webAPP from a webclip on their home screen The detection is functioning, as conf ...

Overriding a CSS property with !important proves ineffective

I need to make adjustments to an old internal page that currently has the following CSS styling: table { font-family: "Arial"; font-size: 13px; text-align: left; border-collapse: collapse; border: 1px solid black; vertical-align: m ...

The utilization of ~ (tilde) for SCSS file imports seems to be malfunctioning in Angular 6

Having some issues with importing SCSS files in Angular6, need clarification on a couple of things: If I import my partials once in the global src/sass/styles.scss, do I still need to import them individually in all component.scss files? Is there a way t ...

"Prior to authenticating the user, the Angular route guard is triggered

A route guard was successfully implemented to redirect users to the login page if they are not authenticated, with the login check being of type Observable. Everything works fine when a user is logged in and navigates to a protected page: { path: 'pr ...