Welcome to our comprehensive course on building modern web applications with Angular 20! In this chapter, we'll create a professional portfolio website that demonstrates the power of combining Angular 20, Angular Material Design, and Tailwind CSS 4.
Our project, karmakanban/devportfolio, will showcase:
- Modern Angular 20 standalone components
- Professional Material Design UI components
- Responsive design with Tailwind CSS 4
- Theme-driven architecture
- Dynamic navigation with scroll-based highlighting
- Responsive, modular, reusable UI components
You can test your knowledge with a small quiz after going through the article, You will find the quiz in the README File
Before we begin, ensure you have:
- Node.js (v22.16 or higher)
- npm or yarn package manager
- Angular CLI (v20+)
Step 1: Project Setup
1.1 Create New Angular Application
First, let's create a new Angular 20 project:
# Create new Angular project
ng new devportfolio --style=scss --zoneless=false --ssr=false
# Navigate to project directory
cd devportfolio
1.2 Install Angular Material
# Add Angular Material to the project
ng add @angular/material
# Choose the following options:
# - Choose a prebuilt theme: I choose "cyan-orange"
# - Set up global Angular Material typography styles: "Yes"
# - Set up browser animations for Angular Material: "Yes"
1.3 Verify Installation
Check that the following files were updated:
-
angular.json
- Material theme and styles added -
src/styles.scss
- Material typography imported -
src/index.html
- Material icons font added
1.4 Install Tailwind CSS 4
# Install Tailwind CSS 4 and PostCSS
npm install tailwindcss @tailwindcss/postcss postcss --force
--force
: This is necessary sometimes to resolve peer dependency issues, especially with newer versions of Angular or other libraries, as Angular CLI might have specific peer dependency requirements.
1.5 Configure PostCSS
Create .postcssrc.json
in the project root: Tailwind CSS 4 relies on PostCSS for processing.
{
"plugins": {
"@tailwindcss/postcss": {}
}
}
1.6 Update Global Styles
In Tailwind CSS 4, the tailwind.config.js file is no longer required by default. Configuration is now primarily CSS-first. If you want to embrace the new CSS-first approach, you'll manage most of your Tailwind configuration directly in your src/styles.css file, Just like we have done.
Update src/styles.scss
This file serves as the global stylesheet for your Angular application, combining Tailwind CSS, Angular Material theming, and custom utility classes.
@use "tailwindcss"
imports Tailwind CSS into your project, making all Tailwind utility classes availableBasic Styling : Sets the HTML and body elements to take up 100% of viewport height, removes default margin from the body and sets Roboto as the primary font with fallbacks to Helvetica Neue and system sans-serif fonts (added by and standard for Material Design)
html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
- CSS Custom Properties (Theme Variables): Defines CSS variables in the
:root
scope (global availability), Includes text color variables for proper contrast on each background
:root {
/* Primary colors from cyan-orange theme */
--primary-color: #00bcd4;
...
--warn-text: #ffffff;
}
- Utility Classes: Uses the CSS variables defined earlier for consistent theming they can be applied directly in HTML templates (e.g.
<div class="primary-bg">
)
.primary-text { color: var(--primary-color); }
...
.accent-border { border-color: var(--accent-color); }
- Material Design Token Fallbacks: Provides fallback classes that match Angular Material's naming convention. Ensures compatibility with some Material components that might expect these class names and can be used to override default Material component styling
Step 2: Component Architecture
Components are the main building blocks of Angular applications. Each component represents a part of a larger web page. Organizing an application into components helps provide structure to your project, clearly separating code into specific parts that are easy to maintain and grow over time.
The Angular CLI provides a powerful way to generate components. The basic syntax is: ng generate component <component-name>
or its shorthand: ng g c <component-name>
Let's analyze one of our command that we are going to use:
ng g c features/profile/components/profile-header --flat --skip-tests --inline-template --inline-style
This command creates a component called profile-header in the specified path with several configuration flags.
-
--flat
: Creates the component files directly in the specified directory. It doesn't create a dedicated folder for the component. Without this flag, Angular would create a profile-header folder inside components. --skip-tests
: Doesn't generate a test file (.spec.ts). It's useful when you're not writing unit tests or will add them later.--inline-template
: Places the HTML template directly in the component TypeScript file using template instead of templateUrl. They are good for small templates that don't need separate files--inline-style
: Places the CSS styles directly in the component TypeScript file using styles instead of styleUrls. They are also useful for component-specific styles that are short
A component Consists of:
- A Component decorator that contains configuration used by Angular.
- An HTML template that controls what renders into the DOM.
- A CSS selector that defines how the component is used in HTML.
- A TypeScript class with behaviors, such as handling user input or making requests to a server.
We have divided the portfolio page into 7 component so they can be maintained separately and independently.
2.1 Create Profile Header Component
ng g c features/profile/components/profile-header --flat --skip-tests --inline-template --inline-style
Let's Understand the Profile Header Component
selector: 'app-profile-header'
: Defines the HTML tag (<app-profile-header>
) to use this component.imports: [MatIconModule]
: MatIconModule is directly imported Used in standalone components, which were introduced in Angular 14 and is default since v17ngOnInit()
: Lifecycle hook for initialization logic. Runs when the component initializes.ngOnDestroy()
: Lifecycle hook for cleanup before component destruction. Not used here but is a good practice.HostListener('window:scroll')
: Decorator to listen to DOM events (here,window:scroll
). CallsupdateActiveSection()
to keep activeSection updated.updateActiveSection()
: Gets scroll position (window.scrollY
). Checks if the scroll position falls within a section’s bounds (offsetTop
,offsetHeight
). Updates activeSection accordingly.
2.2 Create Profile Hero Component
ng g c features/profile/components/profile-hero --flat --skip-tests --inline-template --inline-style
Let's Understand the Profile Hero Component
One new concept the button element that wasn't present in the previous ProfileHeader
component.
-
MatButtonModule:
: Provides Material Design button components. Offers styled, accessible buttons with different variants.mat-raised-button
is for contained button with elevation andmat-stroked-button
for an outlined button with a border and they uses the theme's primary and accent colors.
2.3 Create Profile About, Profile Skills Component
ng g c features/profile/components/profile-about --flat --skip-tests --inline-template --inline-style
ng g c features/profile/components/profile-skill --flat --skip-tests --inline-template --inline-style
The Profile About Component
The Profile Skills Component
No new angular concept is introduced in these component.
2.4 Create Profile Projects Component
ng g c features/profile/components/profile-project --flat --skip-tests --inline-template --inline-style
Let's Understand the Profile Projects Component
One new concept, the button element that weren’t present in the previous components.
-
MatCardModule:
: Provides Material Design card components. Wheremat-card
is a container element,mat-card-image
is a special directive for card images,mat-card-content
is for the main content area andmat-card-actions
is for the footer area for actions or buttons.
2.5 Create Profile Contact Component
ng g c features/profile/components/profile-contact --flat --skip-tests --inline-template --inline-style
Let's Understand the Profile Contact Component
Two new concept that weren’t present in the previous components.
MatFormFieldModule:
: Provides styled form field containers with floating labels.mat-form-field
is the container for the label and input.mat-label
is the floating label that animates when focused.MatInputModule:
: Adds Material Design input fields and textareas.matInput
is the material styled input field andtextarea
supports multiline text input with same material styling
2.6 Create Footer About
ng g c features/profile/components/profile-footer --flat --skip-tests --inline-template --inline-style
The Profile Footer Component
No new angular concept is introduced in these component.
Step 3: Portfolio Page Assembly
Why we structured the project this way
Modular Architecture: Each portfolio section is developed independently and can be reused in other contexts also its easier to maintain and update individual sections
Performance Benefits: Angular can lazy-load or preload these components independently, change detection is more efficient with component boundaries. We can add routing between sections later
Development Workflow: Different team members can work on different sections simultaneously and much easier for testing
Future Flexibility: We can easily reorder sections by changing the template or conditionally show/hide sections with *ngIf
3.1 Create Portfolio Page
ng g c features/profile/pages/portfolio/portfolio
The Portfolio Component
The Portfolio Template
This Portfolio component serves as the container/layout component that assembles all the individual profile sections into a complete portfolio page. Each section is designed with alternating background colors (white and subtle gradients) to create visual separation, with a sticky header for persistent navigation
3.2 Update Main App Component
The main AppComponent serves as the root container that initializes and mounts the standalone PortfolioComponent, creating a clean entry point for the Angular application. It follows Angular's best practices by keeping the root minimal and delegating all rendering logic to feature components, enabling future scalability.
The Main Component
The Main Template
Step 4: Assets and Images
Create a public/images/
directory and add your profile and project images. This follows standard web convention where the public folder contains static assets directly accessible via URL.
Congratulations! You've successfully built a modern, professional portfolio website using Angular 20, Material Design, and Tailwind CSS. This project demonstrates modern web development practices by implementing a component-based architecture with standalone components, responsive design, and a clean separation of concerns. This foundation will serve as the basis for more advanced features in the upcoming chapters.
Top comments (0)