Stacked icon compositions for creating layered icons with foreground and background elements. Icon stacks are perfect for creating complex visual indicators, status icons, and multi-layered designs.
Container component for stacked icon arrangements with size control.
@Component({
selector: 'fa-stack',
template: '<ng-content />',
host: {
'[class]': 'classes()',
}
})
class FaStackComponent {
/**
* Size of the stacked icon container
* Note: Stacked icons are 2x larger by default
* Use custom CSS like `fa-stack { font-size: 0.5em; }` to align with regular icons
*/
readonly size = input<SizeProp>();
}Directive for controlling icon sizes within stacks, applied to individual icons.
@Directive({
selector: 'fa-icon[stackItemSize],fa-duotone-icon[stackItemSize]'
})
class FaStackItemSizeDirective {
/**
* Specify icon size within stack
* '1x' for regular size, '2x' for larger background icons
* @default '1x'
*/
readonly stackItemSize = input<'1x' | '2x'>('1x');
/**
* Internal size input (throws error if used with stackItemSize)
* @internal
*/
readonly size = input<SizeProp>();
}import { Component } from '@angular/core';
import {
FaStackComponent,
FaStackItemSizeDirective,
FaIconComponent
} from '@fortawesome/angular-fontawesome';
@Component({
selector: 'app-stack-example',
template: `
<!-- Basic stack with circle background -->
<fa-stack size="2x">
<fa-icon [icon]="['fas', 'circle']"
stackItemSize="2x"
style="color: gold;"></fa-icon>
<fa-icon [icon]="['fas', 'flag']"
stackItemSize="1x"
style="color: darkred;"
[inverse]="true"></fa-icon>
</fa-stack>
<!-- Square background with icon -->
<fa-stack size="2x">
<fa-icon [icon]="['fas', 'square']"
stackItemSize="2x"
style="color: #3b82f6;"></fa-icon>
<fa-icon [icon]="['fas', 'home']"
stackItemSize="1x"
style="color: white;"></fa-icon>
</fa-stack>
`,
imports: [FaStackComponent, FaStackItemSizeDirective, FaIconComponent]
})
export class StackExampleComponent {}@Component({
selector: 'app-status-stacks',
template: `
<!-- Online status indicator -->
<fa-stack>
<fa-icon [icon]="['fas', 'circle']"
stackItemSize="2x"
style="color: #22c55e;"></fa-icon>
<fa-icon [icon]="['fas', 'user']"
stackItemSize="1x"
style="color: white;"></fa-icon>
</fa-stack>
<!-- Error notification -->
<fa-stack size="2x">
<fa-icon [icon]="['fas', 'circle']"
stackItemSize="2x"
style="color: #ef4444;"></fa-icon>
<fa-icon [icon]="['fas', 'times']"
stackItemSize="1x"
style="color: white;"></fa-icon>
</fa-stack>
<!-- Warning indicator -->
<fa-stack size="2x">
<fa-icon [icon]="['fas', 'triangle']"
stackItemSize="2x"
style="color: #f59e0b;"></fa-icon>
<fa-icon [icon]="['fas', 'exclamation']"
stackItemSize="1x"
style="color: white;"></fa-icon>
</fa-stack>
<!-- Success checkmark -->
<fa-stack size="2x">
<fa-icon [icon]="['fas', 'circle']"
stackItemSize="2x"
style="color: #10b981;"></fa-icon>
<fa-icon [icon]="['fas', 'check']"
stackItemSize="1x"
style="color: white;"></fa-icon>
</fa-stack>
`,
imports: [FaStackComponent, FaStackItemSizeDirective, FaIconComponent]
})
export class StatusStacksComponent {}@Component({
selector: 'app-creative-stacks',
template: `
<!-- Banned/prohibited sign -->
<fa-stack size="3x">
<fa-icon [icon]="['fas', 'ban']"
stackItemSize="2x"
style="color: #dc2626;"></fa-icon>
<fa-icon [icon]="['fas', 'smoking']"
stackItemSize="1x"
style="color: #666;"></fa-icon>
</fa-stack>
<!-- Social media notification -->
<fa-stack size="2x">
<fa-icon [icon]="['fas', 'square']"
stackItemSize="2x"
style="color: #1da1f2;"></fa-icon>
<fa-icon [icon]="['fab', 'twitter']"
stackItemSize="1x"
style="color: white;"></fa-icon>
</fa-stack>
<!-- File type indicator -->
<fa-stack size="2x">
<fa-icon [icon]="['fas', 'file']"
stackItemSize="2x"
style="color: #e5e7eb;"></fa-icon>
<fa-icon [icon]="['fas', 'code']"
stackItemSize="1x"
style="color: #374151;"></fa-icon>
</fa-stack>
<!-- Shield with checkmark -->
<fa-stack size="2x">
<fa-icon [icon]="['fas', 'shield-alt']"
stackItemSize="2x"
style="color: #059669;"></fa-icon>
<fa-icon [icon]="['fas', 'check']"
stackItemSize="1x"
style="color: white;"></fa-icon>
</fa-stack>
`,
imports: [FaStackComponent, FaStackItemSizeDirective, FaIconComponent]
})
export class CreativeStacksComponent {}Understanding stack sizing behavior and alignment with regular icons.
// Stack sizing behavior
// - Stacks are 2x larger than regular icons by default
// - Use CSS to normalize: fa-stack { font-size: 0.5em; }
// - Or use explicit sizing: size="1x" makes stack same size as regular iconSizing Examples:
@Component({
template: `
<div class="icon-comparison">
<!-- Regular icon for comparison -->
<fa-icon [icon]="['fas', 'home']" size="2x"></fa-icon>
<!-- Default stack (appears 4x size) -->
<fa-stack size="2x">
<fa-icon [icon]="['fas', 'circle']" stackItemSize="2x"></fa-icon>
<fa-icon [icon]="['fas', 'home']" stackItemSize="1x"></fa-icon>
</fa-stack>
<!-- Normalized stack (same as 2x icon) -->
<fa-stack size="2x" style="font-size: 0.5em;">
<fa-icon [icon]="['fas', 'circle']" stackItemSize="2x"></fa-icon>
<fa-icon [icon]="['fas', 'home']" stackItemSize="1x"></fa-icon>
</fa-stack>
</div>
`,
styles: [`
.icon-comparison {
display: flex;
align-items: center;
gap: 1rem;
}
`]
})
export class SizingExampleComponent {}Important rules for stack item sizing and validation.
// Stack item size validation
// - Icons in stacks MUST specify stackItemSize
// - Cannot use 'size' property on icons within stacks
// - Use '2x' for background/larger elements
// - Use '1x' for foreground/smaller elements
// This will throw an error:
// <fa-icon size="2x" stackItemSize="1x" />
// Error: "fa-icon is not allowed to customize size when used inside fa-stack"Correct Stack Structure:
@Component({
template: `
<!-- Correct: stackItemSize only -->
<fa-stack size="2x">
<fa-icon [icon]="['fas', 'square']" stackItemSize="2x"></fa-icon>
<fa-icon [icon]="['fas', 'terminal']" stackItemSize="1x"></fa-icon>
</fa-stack>
<!-- Error: Don't use size property inside stacks -->
<!--
<fa-stack>
<fa-icon [icon]="['fas', 'circle']"
size="2x"
stackItemSize="2x"></fa-icon> // Will error
</fa-stack>
-->
`
})
export class CorrectStackComponent {}CSS techniques for enhancing stack appearance.
/* Stack container styling */
.custom-stack {
filter: drop-shadow(2px 2px 4px rgba(0,0,0,0.3));
transition: transform 0.2s ease;
}
.custom-stack:hover {
transform: scale(1.1);
}
/* Gradient backgrounds */
.gradient-stack .fa-stack-2x {
background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Animation effects */
@keyframes pulse-stack {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
.pulse-stack {
animation: pulse-stack 2s infinite;
}Making stacks work across different screen sizes.
@Component({
template: `
<div class="responsive-stacks">
<!-- Mobile-first stack sizing -->
<fa-stack [size]="stackSize" class="responsive-stack">
<fa-icon [icon]="['fas', 'circle']" stackItemSize="2x"></fa-icon>
<fa-icon [icon]="['fas', 'mobile-alt']" stackItemSize="1x"></fa-icon>
</fa-stack>
</div>
`,
styles: [`
.responsive-stacks {
display: flex;
justify-content: center;
padding: 1rem;
}
.responsive-stack {
font-size: 0.5em; /* Normalize base size */
}
@media (min-width: 768px) {
.responsive-stack {
font-size: 0.75em;
}
}
@media (min-width: 1024px) {
.responsive-stack {
font-size: 1em;
}
}
`]
})
export class ResponsiveStackComponent {
stackSize: SizeProp = '2x';
constructor() {
// Dynamic sizing based on screen size
if (window.innerWidth < 768) {
this.stackSize = '1x';
} else if (window.innerWidth < 1024) {
this.stackSize = '2x';
} else {
this.stackSize = '3x';
}
}
}Common stack-related errors and solutions.
// Error prevention checklist:
// 1. Always use stackItemSize on icons in stacks
// 2. Don't mix size and stackItemSize properties
// 3. Ensure background icons use stackItemSize="2x"
// 4. Ensure foreground icons use stackItemSize="1x"
// Example error handler
@Component({
template: `
<fa-stack size="2x">
<fa-icon [icon]="backgroundIcon"
stackItemSize="2x"
[style.color]="backgroundIcon ? 'blue' : 'gray'"></fa-icon>
<fa-icon [icon]="foregroundIcon"
stackItemSize="1x"
[style.color]="foregroundIcon ? 'white' : 'black'"></fa-icon>
</fa-stack>
`
})
export class ErrorHandlingStackComponent {
backgroundIcon: IconProp | null = ['fas', 'circle'];
foregroundIcon: IconProp | null = ['fas', 'user'];
// Validate icons exist before rendering
ngOnInit() {
if (!this.backgroundIcon || !this.foregroundIcon) {
console.warn('Stack icons not properly configured');
}
}
}