Featured resource
2026 Tech Forecast
2026 Tech Forecast

1,500+ tech insiders, business leaders, and Pluralsight Authors share their predictions on what’s shifting fastest and how to stay ahead.

Download the forecast
  • Lab
    • Libraries: If you want this lab, consider one of these libraries.
    • Core Tech
Labs

Implement Application Styling in Angular

In this Code Lab, learners style an Angular application using component-scoped SCSS and a maintainable styling architecture. They configure component styles and view encapsulation behavior, organize global and component-level styling concerns with Sass, apply predictable low-specificity styling practices, and theme reusable components using host-based selectors and CSS custom properties. The lab focuses on practical implementation of scalable styling patterns in Angular applications.

Lab platform
Lab Info
Level
Intermediate
Last updated
Jul 06, 2026
Duration
45m

Contact sales

By clicking submit, you agree to our Privacy Policy and Terms of Use, and consent to receive marketing emails from Pluralsight.
Table of Contents
  1. Challenge

    Introduction

    Welcome to the Implement Application Styling in Angular lab.

    In this hands-on lab, you build out the styling architecture for a multi-component dashboard application by sealing component styles behind view encapsulation, organizing shared Sass into reusable partials, refactoring selectors into a low-specificity BEM structure, and exposing a theme-based surface through :host and CSS custom properties.

    When you complete each task, you run the app and see your work pay off directly in the browser: styles that stay isolated to their own components, a responsive layout driven by a single shared mixin, and a profile form that flips into a dark theme the instant an ancestor class changes.

    Concepts involved

    View encapsulation is Angular's mechanism for scoping a component's styles to its own template.

    Sass partials are .scss files prefixed with an underscore (e.g., _variables.scss) that exist only to be loaded into other files, never compiled on their own.

    Sass mixins and functions both let you define reusable logic once and call it from anywhere. A mixin (@mixin/@include) outputs a block of CSS, whereas a function (@function/@return) computes and returns a single value.

    BEM (Block, Element, Modifier) is a class-naming convention: block, block__element, block__element--modifier, keeping every selector a single flat class with equal low specificity.

    :host and :host-context() are pseudo-classes available only inside a component's own stylesheet. :host styles the component's own root element from the outside-in, whereas :host-context() goes further: it lets a component look outward at its ancestors and change its own styling based on a condition met anywhere above it in the DOM.

    Prerequisites

    Before starting this lab, you should be comfortable with:

    • Angular basics: components, templates, and the @Component decorator's metadata
    • CSS/Sass basics: selectors, specificity, and standard properties
    • Basic file-system navigation: creating files and folders inside a given directory structure

    The lab environment is ready to use. Your Angular 22 workspace is already scaffolded with four components: Card, Dashboard, Navbar, and ProfileForm, all wired into a working Dashboard view. Each task validates your work by running its corresponding spec file.

    The scenario

    You are a frontend developer building the styling layer for Angular Styling App, a small internal app composed of a navbar, a card grid, and a profile-editing form.

    Right now, every component renders correctly but carries no real styling discipline: stylesheets are empty or inconsistent, spacing values are hardcoded in px, class names do not yet follow a shared convention, and nothing in the app supports more than one visual theme.

    Your job is to bring this app up to a production-grade styling standard, from sealing each component's styles, through building a shared Sass architecture, to exposing a theme-based dark-mode surface on the profile form.

    The application structure

    Key files in the lab environment:

    • src/app/components/card/: a card component rendered three times inside the dashboard grid
    • src/app/components/navbar/: the app's top navigation bar, used to demonstrate the difference between ViewEncapsulation.Emulated and ViewEncapsulation.None
    • src/app/components/profile-form/: a form component composed inside the dashboard
    • src/app/components/dashboard/: the page that composes Card and ProfileForm together
    • src/styles/: the shared Sass directory that you will build
    • angular.json: the workspace build configuration

    Run the application

    To visually inspect your changes, start the app by running the following in the terminal:

    ng serve --host 0.0.0.0 --port 4200
    

    As long as the app is running without errors, your changes update automatically in the browser. You can also open the app in a new browser.

    If the app stops running or you need to restart it, press Ctrl+C in the terminal to stop the server, then run the command again.

    info> Complete the tasks in order. Each task builds on the previous one.

  2. Challenge

    View encapsulation

    Every component you write in Angular gets its own stylesheet, but by default, those styles do not automatically stay contained. You must understand how Angular seals them off, and what happens when that seal is removed.

    In this step, you will connect real Sass styles to the Card component for the first time and confirm Angular's default ViewEncapsulation.Emulated mode is actually scoping them. Then you will deliberately switch a component to ViewEncapsulation.None to see what happens when that scoping is turned off, watching one component's styles leak into a completely unrelated part of the app. With your first scoped style in place, you have seen Angular's default sealing behavior (ViewEncapsulation.Emulated) from the inside.

    Next, you will step outside that seal entirely by switching to ViewEncapsulation.None and watching a style escape its component. You have now seen both sides of view encapsulation: styles that stay locked to their component, and styles that do not.

    That difference is the foundation everything else in this lab builds on because once you start sharing values like colors and spacing across components in Step 2, you will require that sharing to happen deliberately, through a proper Sass architecture, not by accident through a leaky ViewEncapsulation.None.

    warning> Before moving to the next step, remove the ViewEncapsulation.None configuration from navbar.ts and the .card__title color rule from card.scss.

  3. Challenge

    Sass architecture

    So far, every style you have written has lived entirely inside one component's own stylesheet, which works fine until two components need to agree on the same color, the same spacing scale, or the same breakpoint. Repeating those values by hand in five different files is how design systems drift apart silently, one small inconsistency at a time.

    In this step, you will build the shared foundation that prevents that: a dedicated styles/ directory of Sass partials, wired together through a single forwarding file, and registered with Angular's build so any component can pull from it with one short import. Then you will fill that foundation with shared variables and a responsive mixin. With the styles/ folder created and registered, the plumbing is in place, but every partial inside it is still empty.

    Next, you will fill _variables.scss and _mixins.scss with real values and a real responsive mixin, then apply both directly inside Card. You now have a working Sass architecture: shared variables and a reusable mixin, both accessible from any component via a single import, with Card already proving the pattern works end-to-end.

    With that foundation in place, the next problem is selector discipline, making sure the classes you write stay predictable and low-specificity as the app grows.

  4. Challenge

    Styling practices

    With a shared Sass architecture in place, the next thing that can make a stylesheet difficult to maintain isn't missing variables; it's selectors that slowly become harder to override. As nested selectors, long class chains, and inconsistent naming patterns accumulate, specificity keeps increasing. Eventually, even a small style change can turn into a battle that requires !important just to make an override work.

    In this step, you will use two techniques to keep your styles simple and predictable. First, you will apply BEM's modifier convention to your component class names so variations, such as a "primary" button, can be handled with a single class instead of nested selectors.

    Then, you will move away from hardcoded px values and introduce a rem conversion function, allowing spacing and sizing to scale consistently and respect users' accessibility settings.

    By the end of this step, both your selectors and your measurements will follow the same idea: define a rule once, keep it easy to reuse, and let every component reference it consistently. With a real BEM modifier in place on Card's button, your class naming follows a consistent, low-specificity pattern.

    Next, you will apply that same discipline to measurements by replacing hardcoded px values with a reusable px-to-rem conversion function, so spacing scales consistently everywhere it is used. Your selectors are now flat and predictable, and your spacing scales through a single shared conversion function instead of hardcoded pixels scattered across files. Together, BEM and rem-based tokens mean future style changes like a new button variant or a new spacing scale stay simple with one-place edits.

    With low-specificity practices in place, the last piece is making components theme-based.

  5. Challenge

    Theme reusable components

    Every style you have written so far has targeted something inside a component's template, but you have never directly styled the component's own root element, the actual tag that Angular renders into the DOM. That gap matters more than it seems: a component dropped into a CSS grid or flex layout behaves unpredictably if its own outer tag has no declared display behavior.

    In this step, you will first use :host to give two components, Card and ProfileForm sensible baseline structural styles from the outside-in. Then you will go further, exposing real CSS custom properties on ProfileForm so its colors become overridable at runtime; something compiled Sass variables can never do.

    You will use :host-context() to let ProfileForm detect a dark-theme class anywhere in its ancestor tree and retheme itself automatically. You will not require any JavaScript toggle or component-level logic. You have now declared baseline layout behavior on both Card and ProfileForm using :host. Each component takes responsibility for its own root element instead of relying on whatever happens to be styled inside it.

    Next, you will build on that foundation: exposing real CSS custom properties on ProfileForm and using :host-context() to let a single ancestor class switch it into a dark theme at runtime. ProfileForm now exposes its own colors as CSS custom properties and overrides them automatically whenever a .dark-theme class appears anywhere above it in the DOM.

    You have just completed a real runtime theme switch which is driven entirely by CSS, with zero JavaScript and no rebuild required to change the active theme.

    Conclusion

    Across all four steps, you took Angular Styling App from a set of components with empty stylesheets to a properly architected styling system.

    • You confirmed Angular's default ViewEncapsulation.Emulated keeps every component's styles sealed off from the rest of the app, and saw firsthand what breaks when that seal is removed under ViewEncapsulation.None.
    • You built a real Sass architecture: partials forwarded through a single entry point, registered with Angular's build so variables, mixins, and functions live in one shared place instead of being repeated across files.
    • You adopted BEM's naming convention and a rem-based conversion function to keep selectors flat and measurements scalable.
    • And finally, you used :host and :host-context() to make components responsible for their own root-element styling and theme-aware without any external logic driving the change.

    Putting it all together

    These steps are not isolated tricks. They work together. A scoped component that uses shared tokens and low-specificity selectors is easier to maintain. It can safely expose a theme-based API without styles leaking into other parts of the application. It is also less likely to be overridden by unrelated styles.

    That is the real goal of a styling architecture. It is not about any single rule. It is about building a set of practices that remain predictable as an application grows far beyond a handful of components.

About the author

Written content author.

Real skill practice before real-world application

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Learn by doing

Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.

Follow your guide

All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.

Turn time into mastery

On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.

Get started with Pluralsight