📧 Reste informé(e) !

Reçois les derniers articles et conseils EasyAngularKit directement dans ta boîte mail.

S'inscrire gratuitement

~2 min de lecture

Angular : Supprime Les Div Inutiles, Utilise Le Host Élément

Tu wraps tous tes composants dans une <div> ? Ton DOM est rempli de containers inutiles ?

Il existe une meilleure façon : utiliser l'élément host du composant directement.

Dans cet article, je vais te montrer comment éliminer les div superflues et styler le host élément.


Le Problème Avec Les Div Wrappers

❌ Ce que font les juniors :

Ils ajoutent une div wrapper dans chaque template.


@Component({
  selector: 'app-user-card',
  template: `
    <!-- ❌ Div wrapper inutile -->
    <div class="user-card">
      <h3>{{ user().name }}</h3>
      <p>{{ user().email }}</p>
    </div>
  `,
  styles: `
    .user-card {
      padding: 16px;
      border: 1px solid #ddd;
      border-radius: 8px;
    }
  `
})
export class UserCard {
  readonly user = input.required<User>();
}

Résultat dans le DOM :


<app-user-card>
    <div class="user-card">  <!-- ❌ Div inutile -->
        <h3>John</h3>
        <p>[john@example.com](mailto:john@example.com)</p>
    </div>
</app-user-card>

🚨 Pourquoi c'est problématique ?

  1. DOM pollué : élément HTML inutile
  2. Styles complexes : un niveau de nesting de plus
  3. Flexbox/Grid : complique les layouts
  4. Performance : plus d'éléments = plus lent
  5. Lisibilité : code moins clair

La Solution Pro : Utiliser Le Host

✅ Ce que font les pros :

Ils stylent directement l'élément host.


@Component({
  selector: 'app-user-card',
  standalone: true,
  template: `
    <!-- ✅ Pas de div wrapper -->
    <h3>{{ user().name }}</h3>
    <p>{{ user().email }}</p>
  `,
  styles: `
    /* ✅ Style sur le host directement */
    :host {
      display: block;
      padding: 16px;
      border: 1px solid #ddd;
      border-radius: 8px;
    }
  `
})
export class UserCard {
  readonly user = input.required<User>();
}

Résultat dans le DOM :


<app-user-card style="...">
    <!-- ✅ Pas de div inutile -->
    <h3>John</h3>
    <p>[john@example.com](mailto:john@example.com)</p>
</app-user-card>

💡 Pourquoi c'est mieux ?

  • DOM plus propre : moins d'éléments
  • Styles simplifiés : moins de nesting
  • Layouts faciles : Flexbox/Grid direct
  • Performance : moins de nodes
  • Plus maintenable : code plus clair

Le Sélecteur :host

Syntaxe de base

styles: `
  /* Style par défaut du host */
  :host {
    display: block;
    padding: 16px;
  }
  
  /* Host avec classe */
  :host(.highlighted) {
    background: yellow;
  }
  
  /* Host avec attribut */
  :host([disabled]) {
    opacity: 0.5;
  }
`

Display du host

// ✅ Toujours définir le display
styles: `
  :host {
    display: block;  // ou flex, grid, inline-block...
  }
`

Pourquoi ? Par défaut, le host est display: inline, ce qui peut causer des bugs de layout.


Cas d'Usage Réels

Exemple 1 : Card Component


@Component({
  selector: 'app-card',
  template: `
    <h3><ng-content select="[header]" /></h3>
    <div class="content">
      <ng-content />
    </div>
  `,
  styles: `
    :host {
      display: block;
      background: white;
      border: 1px solid #ddd;
      border-radius: 8px;
      padding: 16px;
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }
    
    :host(:hover) {
      box-shadow: 0 4px 8px rgba(0,0,0,0.15);
    }
  `
})
export class Card {
}

Exemple 2 : Button Component


@Component({
  selector: 'app-button',
  host: {
    '[class.primary]': 'variant() === "primary"',
    '[class.secondary]': 'variant() === "secondary"',
    '[class.disabled]': 'disabled()'
  },
  template: `<ng-content />`,
  styles: `
    :host {
      display: inline-block;
      padding: 8px 16px;
      border-radius: 4px;
      cursor: pointer;
      border: none;
      font-size: 14px;
    }
    
    :host(.primary) {
      background: #007bff;
      color: white;
    }
    
    :host(.secondary) {
      background: #6c757d;
      color: white;
    }
    
    :host(.disabled) {
      opacity: 0.5;
      cursor: not-allowed;
    }
  `
})
export class Button {
  readonly variant = input<'primary' | 'secondary'>('primary');

  readonly disabled = input<boolean>(false);
}

Exemple 3 : Layout avec Flexbox


@Component({
  selector: 'app-row',
  template: `<ng-content />`,
  styles: `
    :host {
      display: flex;
      gap: 16px;
      align-items: center;
    }
  `
})
export class Row {
}

@Component({
  selector: 'app-column',
  template: `<ng-content />`,
  styles: `
    :host {
      display: flex;
      flex-direction: column;
      gap: 16px;
    }
  `
})
export class Column {
}

// Utilisation
@Component({
  template: `
    <app-row>
      <app-column>
        <app-card>Card 1</app-card>
        <app-card>Card 2</app-card>
      </app-column>
      <app-column>
        <app-card>Card 3</app-card>
      </app-column>
    </app-row>
  `
})
export class Dashboard {
}

Exception : Les Formulaires

⚠️ Cas où la div wrapper est nécessaire

Pour les formulaires avec <form>, il faut garder la balise <form> dans le template.

// ✅ Bon : <form> dans le template
@Component({
  selector: 'app-user-form',
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
      <input formControlName="name" />
      <button type="submit">Save</button>
    </form>
  `,
  styles: `
    :host {
      display: block;
    }
    
    form {
      padding: 16px;
    }
  `
})
export class UserForm {
  readonly form = inject(FormBuilder).group({
    name: ['']
  });

  onSubmit(): void {
    console.log(this.form.value);
  }
}

Pourquoi garder <form> ?

  1. Sémantique HTML : <form> a une signification
  2. Validation HTML5 : formulaires natifs
  3. Accessibilité : lecteurs d'écran
  4. Submit natif : Enter key, etc.

Host Bindings

Avec la propriété host


@Component({
  selector: 'app-badge',
  standalone: true,
  host: {
    '[class.success]': 'type() === "success"',
    '[class.error]': 'type() === "error"',
    '[attr.role]': '"status"',
    '[style.backgroundColor]': 'backgroundColor()'
  },
  template: `<ng-content />`,
  styles: `
    :host {
      display: inline-block;
      padding: 4px 8px;
      border-radius: 4px;
    }
    
    :host(.success) { background: #28a745; color: white; }
    :host(.error) { background: #dc3545; color: white; }
  `
})
export class Badge {
  readonly type = input<'success' | 'error'>('success');

  readonly backgroundColor = input<string>();
}

Avec @HostBinding (ancien style)


@Component({
  selector: 'app-card',
  template: `<ng-content />`
})
export class Card {
  @HostBinding('class.elevated')
  readonly elevated = input<boolean>(false);

  @HostBinding('style.padding.px')
  readonly padding = input<number>(16);
}

Les Pièges À Éviter

Oublier le display

// ❌ Mauvais : pas de display
styles: `
  :host {
    padding: 16px;
  }
`

// ✅ Bon : display défini
styles: `
  :host {
    display: block;
    padding: 16px;
  }
`

Conclusion : DOM Plus Propre

Utiliser le host élément rend ton code plus propre et performant.

Ce que tu dois retenir :

:host pour styler le composant

display toujours défini

Pas de div wrapper sauf exceptions

Exceptions : formulaires, animations, layouts complexes

host bindings pour classes dynamiques

La règle d'or :

Supprime la div wrapper. Si tu as vraiment besoin d'un container, demande-toi pourquoi. Dans 80% des cas, :host suffit.


Envie de découvrir EasyAngularKit et son programme ?

Découvre EasyAngularKit : https://www.easyangularkit.com/easyangularkit

📧 Reste informé(e) !

Reçois les derniers articles et conseils EasyAngularKit directement dans ta boîte mail.

S'inscrire gratuitement

AngularKit

Suite d'outils pour développeurs Angular francophones. Apprends, modernise tes réflexes, audite ta codebase.

Produits

Contact

Légal

© 2026 AngularKit. Tous droits réservés.