Search code examples
htmlcssangulartypescriptng2-bootstrap

Override CSS-Property of child div in angular2


Currently I'm using the progressbar of ng2-bootstrap in the GUI of my website. The HTML which I use for this step is very simple:

  <div class="col-lg-8 col-md-4">
    <progressbar  max="100" class="progress-striped" [value]="progress">{{progress}}%</progressbar>
  </div>

This gets rendered into the following HTML:

<div class="col-lg-8 col-md-4">
    <progressbar class="progress-striped" max="100">
        <div progress="" max="100" class="progress" style="height: 30px;">
            <bar>
                <div aria-valuemin="0" class="progress-bar" role="progressbar" style="min-width: 0px; width: 0%;" ng-reflect-initial-classes="progress-bar" aria-valuenow="0" aria-valuetext="0%">
                    0%
                </div>
            </bar>


        </div>
    </progressbar>
</div>

I removed some angular directives to improve the readability

The height of the progressbar is set in the second div within the css-class progress, which I can not access, because it is set in the provided source code of the component. Also the innermost div is the one I would need to access if I want to change the font-size.

I tried to override the style in the parent to set the height, but the progress class is more specific and therefore I could not override it.

I found a not very pretty solution which uses ElementRef and Renderer, but this scales very bad and will get messy if there are multiple progressbars(ATM I'm trying to access a second progressbar):

  ngAfterViewInit() {
    this.renderer.setElementStyle(this.el.nativeElement.querySelector('progressbar').querySelector('div'), 'height', '30px');
    this.renderer.setElementStyle(this.el.nativeElement.querySelector('progressbar').querySelector('div').querySelector('bar').querySelector('div'), 'font-size', '15px');
  }

Are there better approaches to solve this problem? As last resort I could try to adjust the source code of the component to access both values, but actually I want to avoid this.


Solution

  • You mention specificity as the problem. If that's the case, using !important is a solution. Anything marked with !important will gain top-specificity and cannot be overridden by any other non-!important CSS rule or inline styles. When put in your global.css file this should work for all progressbars. It might not work from within your component.css due to view encapsulation.

    progressbar > div[progress] {
      height: 30px !important;
    }
    
    progressbar > div[progress] > bar > .progress-bar {
      font-size: 15px !important;
    }