Angular’da CSS Pratikleri
Angular’ın temel yapı taşlarından biri ve en önemlisi component’lerdir. Çünkü herşey component’ler üzerine inşa ediliyor. Angular component’leri belli bir işi yapan ve yeniden kullanılabilen yapılardır. Bir component sayfanın farklı yerlerinde kullanılabilir. O yüzden her bir component’in kendine özgü bir template’i, kendi yürüttüğü bir iş mantığı ve stilleri vardır. İşte bu saydığımız özelliklerin kendi içinde tutarlı ve dış etkilerden etkilenmemesi gerekir. Angular bu etkileri en aza indirmek için kendi içinde yöntemler barıdırıyor. Bunlardan birisi önceki yazıda bahsettiğimiz “View Encapsulation” dır.
Angular Projelerinde CSS Kullanımı
Angular uygulamalarında varsayılan olarak stiller oluşturmak için CSS dili kullanılır. Bu da CSS ile ilgili ne kadar kural varsa, Angular uygulamarında kullanılabilir demektir. Ayrıca, Angular projelerinde CSS dışında “Sass” veya “Less ”gibi CSS ön işlemcileri kullanılabilir. Angular CLI ile yeni proje oluştururken bu seçenek sorulmaktadır. Eğer projede stiller için CSS kullanılıyorsa, stil dosyalarının uzantısı “.css” dir. Eğer “Sass” kullanılıyorsa, dosya uzantıları “.scss” dir.
Component’ler stillerini kendi içlerinde hapsederek birbirlerini etkilemezler. Böylece, birbirini kullanan component’lerin stilleri birbirlerini ezmemiş olur. Fakat Angular’ın kendi içinde sahip olduğu özellikler sayesinde bu kurallar genişletilebilir ve ihtiyaca göre tasarımlar elde edilebilir.
Öncelikle bir Angular projesinin root dizininde "style.css" veya "style.scss" adında bir dosya bulunur. Bu dosya global stil dosyasıdır. Bu dosyadaki stiller sayfadaki tüm component'leri etkiler.
Component’te CSS Kullanımı ve Pratikleri
Bir component oluşturulurken stilleri iki farklı şekilde verilebiliyor. Component decorator’ünün parametre objesinde “styles” ile dahili olarak verilebiliyorken, “styleUrl” ile farklı bir dosyada tanımlanan stiller verilebilir.
@Component({
selector: 'app-root',
template: `
<h1>Tour of Heroes</h1>
<app-hero-main [hero]="hero"></app-hero-main>
`,
styles: ['h1 { font-weight: normal; }'] // styles ile dahili verilmiş.
})
export class HeroAppComponent {
/* . . . */
}
Veya stiller harici bir dosyada tutulabilir.
@Component({
selector: 'app-root',
template: `
<h1>Tour of Heroes</h1>
<app-hero-main [hero]="hero"></app-hero-main>
`,
styleUrl: './hero-app.component.css' // styleUrl ile harici verilmiş.
})
export class HeroAppComponent {
/* . . . */
}
CSS Custom Properties (Özel CSS Property’ileri)
Angular’ın 9. versiyonundan sonra “style-binding” ile CSS’lere custom attribute’ler oluşturulabilir ve bu custom attribute’ler güncellenebilir hale geldi. Bunu uygulamak için CSS’in “CSS-variables” olarak bilinen özelliğinden faydalanılır. Component kendi içinde tanımlanan özel “CSS-variables” ile parametreler alarak tasarımı dinamik olarak güncellemektedir. Bu component kullanıldığı yerde, bu parametrelere değerler verilerek istenildiği tasarım ve görüntüde kullanılır.
Aşağıdaki örnekte daha iyi anlaşılacaktır. Bir tane <div>
için iki tane --title-color
, --subtitle-font-size.px
adında CSS değişkeni tanımlanmış. Daha sonra bu değişkenler component’in sınıfında tanımlı olan değişkenlere bağlanmıştır. Son olarak style içerisinde “var()” metodu ile ilgili CSS değişkenleri gerçek stillere bağlanmıştır. Dolayısıyla component sınıfında bulunan bu yerel değişkenler değiştikçe CSS değerleri de değişmiş olacaktır.
import { Component } from "@angular/core";
@Component({
selector: "app-root",
template: `
<div
[style.--title-color]="titleColor"
[style.--subtitle-font-size.px]="subtitleFontSize"
>
<h1>Angular</h1>
<h2 class="subtitle">CSS Custom Properties Demo</h2>
</div>
`,
styles: [
`
h1 {
color: var(--title-color);
}
.subtitle {
font-size: var(--subtitle-font-size);
}
`
]
})
export class AppComponent {
titleColor = "crimson";
subtitleFontSize = 18;
}
“@mixin” İle Global CSS Tanımlama
Angular’ın “ViewEncasulation.Emuled” kapsüllemesi, stillerin bir component’ten çıkıp, diğer component’leri etkilemesi engellese de, global CSS’lerin sayfanın tamamını etkilemesini engelleyemez. Bu yüzden global CSS’lerin doğrudan tüm bileşenleri etkilemesi istenmediği için, Sass gibi bir CSS ön işlemcisi aracılığıyla desteklenen özelliklerin kullanılması gerektiği savunulur. Bu özelliklerden bir tanesi @mixin
dir.
Angular uygulamalarında @mixin
, genellikle Sass (Syntactically Awesome Stylesheets) ile birlikte kullanılan bir kavramdır. Angular, CSS'in yanı sıra Sass gibi CSS ön işlemcilerini destekler ve Sass'in mixin özelliği, stil kurallarını daha yönetilebilir ve yeniden kullanılabilir hale getirir. İşte @mixin
kullanımının ana nedenlerinden birisi yeniden kullanılabilirtir. Aynı stil kurallarının birden fazla yerde tekrar tekrar yazılmasını önler. Bir mixin tanımlanır ve gerektiğinde diğer stillerde kullanılabilir. Parametre alabilir, bu da aynı stil kurallarının farklı varyasyonlarını kolayca oluşturmayı sağlar. Örneğin, bir mixin’e renk veya boyut gibi parametreler geçirilebilir ve bu parametreler stil kurallarını dinamik olarak değiştirebilir.
Örnek kullanım: Bu örnekte, @mixin button-styles
mixin'i iki parametre alır: bg-color
ve text-color
. Bu mixin, iki farklı buton stilinde (.button-primary
ve .button-secondary
) kullanılır ve her iki buton için de stil kurallarını tekrar yazmak yerine mixin kullanarak daha temiz ve yönetilebilir bir stil kodu oluşturulur.
// Mixin tanımlama
@mixin button-styles($bg-color, $text-color) {
background-color: $bg-color;
color: $text-color;
border: none;
padding: 10px 20px;
cursor: pointer;
&:hover {
opacity: 0.8;
}
}
// Mixin kullanma
.button-primary {
@include button-styles(#007bff, #fff);
}
.button-secondary {
@include button-styles(#6c757d, #fff);
}
Bir component’in stil dosyasında tanımlanan @mixin
’ler, global stil dosyasında veya başka component’lerde de kullanılabilir. Bunun için @mixin
’lerin tanımlandığı dosyalar import edilmelidir.
// src/styles/mixins.scss
@mixin shared-button-styles($bg-color, $text-color) {
background-color: $bg-color;
color: $text-color;
border: none;
padding: 10px 20px;
cursor: pointer;
&:hover {
opacity: 0.8;
}
}
// src/styles.scss
@import 'styles/mixins';
.button-global {
@include shared-button-styles(#17a2b8, #fff);
}
// src/app/component/component.scss
@import 'styles/mixins';
.button-local {
@include shared-button-styles(#ffc107, #fff);
}
CSS ::part İle Özelleştirme
Eğer component “ViewEncasulation.ShadowDom” kullanıyorsa, “ShadowDom ”içerisinde bulunan template’in belirli kısımlarını stillendirmek için kullanılır.
Angular’da ::part
pseudo-elementini kullanarak bir Shadow DOM içindeki belirli bir kısmın stillerini özelleştirilebilir. ::part
, Shadow DOM'un dışındaki stiller ile içerideki elementlerin belirli bölümlerini hedeflemenize olanak tanır. Bu, özellikle web component'lerle çalışırken kullanışlıdır.
Not: Web component’ler oluşturulup paylaşılan ve başka Angular projelerinde kullanılan hazır component’lerdir.
Bu::part
özelliğini anlamak için örnek:
Öncelikle, ::part
kullanarak stillendirmek istediğimiz bir web component oluşturalım.
// src/assets/my-element.js
class MyElement extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>
.container {
background-color: lightgray;
}
.content::part(paragraph) { // paragraph parçası için renkler mavi olacak
color: blue;
}
</style>
<div class="container">
<p part="paragraph">This is a paragraph inside shadow DOM.</p> /
</div>
`;
}
}
customElements.define('my-element', MyElement); // web componentin selector
Bu kodda, part="paragraph"
attribute'u ile p
elementini belirledik ve ::part(paragraph)
ile bu kısmı stillendirdik. Bu web component’in build edilip paylaşıldığını varsayalım. Başka bir projeye dahil edildikten sonra aşağıdaki gibi kullanılabilir.
/* src/styles.css */
my-element::part(paragraph) {
font-size: 20px;
color: red;
}
Special Selectors(Özel Selektörler)
Angular’da component stillerin sahip olduğu, “:host”, “:host-context” ve “::ng-deep” gibi bazı özel selektörler vardır.
“:host” Kullanımı
Her component’in ilişkili olduğu bir element vardır. Ve bu ilişki bir selector üzerinden sağlanır. Örnek: <app-root></app-root> selectörü app component ile ilişkili olduğu gibi. CSS tarafında “:host” ile verilen stiller bu component’in tanımladığı alan içerinde geçerlidir. Kendi içerisinde child component’leri var ise ve child component’lerin içerisindeki stillerde, “:host” ile tanımlanmış olsalar bile parent component’i etkilemezler. Örnek:
/* host-selector.component.ts*/
@Component({
selector: 'app-main',
template: `
<h1>It Works!</h1>
<div>
Start editing to see some magic happen :)
</div>
`
})
export class HostSelectorExampleComponent {
}
/* host-selector.component.scss */
:host {
font-style: italic;
}
Yukarıdaki örnekte <app-main></app-main> etikelteri içerisindeki bütün yazıları italik yapar.
“:host” İle Şartlı Still Kullanımı
“:host”un fonskiyon formu “:host()” ile şartlı stiller verilir. Sadece o şartı sağlayan stiller etkilenecek sekilde verilebilir. Örnek:
:host {
font-style: italic;
}
:host(.active) {
font-weight: bold;
}
Burada <app-main></app-main> etikelteri içerisindeki bütün yazıları italik yaptığı gibi “.active” CSS sınıfı olan elementleri “bold” yapar. Veya :host h2
ile component’in içerisindehi tüm h2'
leri etkiler.
“:host-context” Kullanımı
Angular’da :host-context
pseudo-class'ı, bir component’in stilini, component’in belirli bir ortamda (örneğin, belirli bir sınıfa sahip bir üst elementte) bulunduğu durumda değiştirmeye olanak tanır. Bu, component’lerin stillerini, component’in içinde bulunduğu bağlama göre uyarlamak için kullanışlıdır. İşte :host-context
kullanımına dair örnek:
/* Eğer üst element .dark-theme sınıfına sahipse */
:host-context(.dark-theme) {
background-color: black;
color: white;
}
/* Eğer üst element .light-theme sınıfına sahipse */
:host-context(.light-theme) {
background-color: white;
color: black;
}
Aynı “:host” gibi parantez içerisinde verilen sınıf elemtlerine de uygulanabilir.
:host-context(.active) {
font-style: italic;
}
“::ng-deep” Kullanımı
Angular’da ::ng-deep
pseudo-class'ı, bileşenlerin encapsulated (kapsüllü) stillerini devre dışı bırakarak stil kurallarını child (çocuk) bileşenlere uygulamak için kullanılır. ::ng-deep
kullanımı, stil kurallarının bileşen sınırlarını aşmasını sağlar ve belirli durumlarda stilleri daha kapsamlı bir şekilde kontrol etmenize olanak tanır. Ancak, ::ng-deep
yeni Angular sürümlerinde kullanımdan kaldırılmıştır, bu yüzden kullanımı dikkatle yapılmalıdır.
/* parent.component.css */
::ng-deep app-child p {
color: red;
font-weight: bold;
}
Yukarıdaki örnekte ng-deep ile child component’in stilleri değiştiriliyor.
CSS “@import” Kullanımı
Angular projelerinde CSS @import
ifadesini kullanarak dış stil dosyalarını içeri aktarılabilir. Bu yöntem, özellikle stil dosyalarını modüler ve yönetilebilir hale getirmek için faydalıdır.
/* additional-styles.css */
body {
background-color: lightblue;
}
h1 {
color: darkblue;
}
/* styles.css */
@import './styles/additional-styles.css';
body {
font-family: Arial, sans-serif;
}
h1 {
text-align: center;
}
yukarıdaki örnekte “style.css” dosyası “additional-styles.css” dosyasını import etmektedir.
Bu makalede, Angular’da CSS dosyalarının nasıl yapılandırılacağını, component’ler arasında nasıl paylaştırılacağını ve global stillerle nasıl entegre edileceğini ele aldık. Ayrıca, @import
ifadesi ile stilleri daha modüler ve yönetilebilir hale getirmenin yollarını inceledik. Doğru CSS uygulamaları, kullanıcı deneyimini büyük ölçüde iyileştirir ve uygulamanızın profesyonel bir görünüme sahip olmasını sağlar. Angular'ın sunduğu esnek stil yönetimi ile projelerinizi daha estetik ve kullanışlı hale getirebilirsiniz.
Yazıyı, yeni başlayanlar veya İngilizcesi yeterli olmayanlar için mümkün olduğunca anlaşılır bir şekilde yazmaya çalıştım. Umarım faydalı olmuştur. Aklınıza takılan herhangi bir soruyu çekinmeden yorumlarda sorabilirsiniz.
Yaralanılan Kaynaklar: