0

I am working on an Angular 7/8 application. I have made a custom input component and its selector is called <app-input></app-input>. This input has some specific stylings that I may want to change somewhere else for example, by default the border-color is blue, and in another component, I want to change its style to red. The problem is I am unable to access the input element within the <app-input></app-input>.

In the parent component, I am applying the styles as :

I am Using SCSS

//Styles from parent component

app-input{
    & .an-input{
        width: 100%;
        & input{
            border-color: red;
        }
    }
}

The Input <app-input></app-input> component code

//Template
<div class="an-input">
    <input 
        [type]="type" 
        [id]="id" 
        [name]="name" 
        (focus)="inputFocus($event)" 
        (blur)="inputBlur($event)" 
        (input)="userTyping($event)"
        class="an-input-el"
    />
    <label [for]="id">
        {{label}}
    </label>
</div>


//Styles
.an-input{
    display: inline-block;
    position: relative;
    width: 100%;
    margin-bottom: 30px;
    & input, & textarea{
        padding: 15px;
        color: $an-color;
        border: none;
        outline: none;
        border: 2px solid $font-darker;
        border-radius: 2px;
        width: 100%;
        &.input-fly{
            border-color: $an-color;
        }
        &.input-fly-error{
            border-color: maroon;
        }
    }
    & label{
        position: absolute;
        left: 0;
        padding: 0 10px;
        font-size: 13px;
        transition: .1s;
        cursor: text;
        color: $font-darker; 
        font-size: 11px;

        &.label-fly{
            padding: 0px;
            color: $an-color;
        }
    }
}
Nadeem Ahmad
  • 665
  • 3
  • 17
  • 40
  • 1
    I found answer [here](https://stackoverflow.com/questions/36527605/how-to-style-child-components-from-parent-components-css-file), this may help you. – Ihor Yanovchyk Aug 02 '19 at 15:21
  • You can use ::ng-deep to access descendants, however soon it will be removed. However, you can declare a `host-context()` inside your child styles to apply some styles when the parent is what in host-context. https://stackoverflow.com/questions/48071237/what-is-the-use-case-of-host-context-selector-in-angular – Sergey Aug 02 '19 at 15:31
  • @Sergey See https://angular.io/guide/component-styles. ::ng-deep is depricated – Saksham Aug 02 '19 at 15:35
  • @Saksham deprecated but not removed so still can be used. Please note, that I've also noticed that in my comment and suggested an alternative to that. – Sergey Aug 02 '19 at 15:37
  • @Sergey I used that, but that doesn't go that deep. – Nadeem Ahmad Aug 02 '19 at 15:38
  • @Sergey alternative is the solution I posted – Saksham Aug 02 '19 at 15:38
  • @Saksham I don't think so. Looks kind of weird – Sergey Aug 02 '19 at 15:39
  • @Saksham 1) you didn't show what you got in the end. 2) it should be like `host ::ng-deep any-component you want to style` – Sergey Aug 02 '19 at 15:40
  • @Saksham read about `host-context` in Angular and you will understand how you can make different styles from children depending on the parent it is in. – Sergey Aug 02 '19 at 15:41

2 Answers2

1

You're applying the wrong syntax in the SCSS, the amperstand (&) is used when you want to select an element that has both selectors, when you do this:

app-input{
    & .an-input{
        width: 100%;
    }
}

you're selecting all the elements of type app-input that also have the .an-input class, not the app-input child elements that have the .an-input class.

So, remove the & :

app-input{
    .an-input{
        width: 100%;
        input{
            border-color: red;
        }
    }
}

More info: https://css-tricks.com/the-sass-ampersand/

Rafael Duarte
  • 569
  • 6
  • 21
1

An angular approach would be to pass the styles as an input property to your custom input as

@Input() styles: any;

and bind it to the ngStyle property as

[styles]="styles"

Demo at: https://stackblitz.com/edit/angular-ngstyle-as-input-property

PS: As one of the user mentioned to use ::ng-deep, it is not advised to do so and will soon be depricated. More info HERE

Saksham
  • 9,037
  • 7
  • 45
  • 73
  • I think I should use this approach it is handier but a headache, though I would be required to pass different styles for each element. – Nadeem Ahmad Aug 02 '19 at 15:39
  • Although this works, I don't think this is the best approach since you'd have to use this logic every time you want to apply a style to an element. – Rafael Duarte Aug 02 '19 at 15:42