Vanilya özü ile TypeScript'te CSS

Kaynak Düğüm: 1121024

vanilya özü yeni bir çerçeveden bağımsız CSS-in-TypeScript kitaplığıdır. Stillerinizi yazmanın hafif, sağlam ve sezgisel bir yoludur. vanilya özü, kuralcı bir CSS çerçevesi değil, esnek bir geliştirici aracı parçasıdır. CSS araçları, son birkaç yılda nispeten istikrarlı bir alan olmuştur. CSS sonrası, şımarıklık, CSS Modülleri, ve biçimli bileşenler hepsi 2017'den önce çıkıyor (bazıları bundan çok önce) ve onlar popüler kalmak bugün. Tailwind son birkaç yılda CSS araçlarında işleri sarsan birkaç araçtan biridir.

vanilya özü, işleri tekrar sarsmayı amaçlıyor. Bu yıl piyasaya sürüldü ve aşağıdakiler de dahil olmak üzere bazı son trendlerden yararlanma avantajına sahiptir:

  • JavaScript geliştiricileri TypeScript'e geçiyor
  • CSS özel özellikleri için tarayıcı desteği
  • İlk kullanım stili

Vanilya özünde onu büyük bir mesele haline getirdiğini düşündüğüm bir sürü akıllı yenilik var.

sıfır çalışma zamanı

CSS-in-JS kitaplıkları genellikle çalışma zamanında belgeye stiller ekler. Bu, aşağıdakileri de içeren avantajlara sahiptir: kritik CSS çıkarma ve dinamik stil.

Ama genel bir kural olarak, ayrı bir CSS dosyası daha performanslı olacaktır. Bunun nedeni, JavaScript kodunun daha pahalı ayrıştırma/derleme işlemlerinden geçmesi gerekmesidir, oysa ayrı bir CSS dosyası önbelleğe alınabilirken HTTP2 protokolü ekstra isteğin maliyetini düşürür. Ayrıca, özel özellikler artık ücretsiz olarak birçok dinamik stil sağlayabilir.

Bu nedenle, çalışma zamanında stilleri enjekte etmek yerine, vanilya özütü sonra alır Linarya ve halı saha. Bu kitaplıklar, oluşturma sırasında kopyalanan ve bir CSS dosyası oluşturmak için kullanılan JavaScript işlevlerini kullanarak stiller yazmanıza olanak tanır. Vanilya özütü TypeScript'te yazsanız da, üretim JavaScript paketinizin genel boyutunu etkilemez.

daktilo ile yazılmış yazı

Büyük bir vanilya özü değer önerisi, yazarak elde etmenizdir. Kod tabanınızın geri kalanını güvenli tutmak için yeterince önemliyse, neden aynı şeyi stilleriniz için yapmıyorsunuz?

TypeScript bir dizi avantaj sağlar. İlk olarak, otomatik tamamlama var. TypeScript uyumlu bir düzenleyicide “fo” yazarsanız, açılır menüde yazı tipi seçeneklerinin bir listesini alırsınız — fontFamily, fontKerning, fontWeight, ya da başka neyle eşleşirse - seçim için. Bu, CSS özelliklerini düzenleyicinizin rahatlığında keşfedilebilir hale getirir. adını hatırlayamıyorsanız fontVariant ama "font" kelimesiyle başlayacağını bilin, yazın ve seçenekler arasında gezinin. VS Kodunda, bunun gerçekleşmesi için herhangi bir ek araç indirmeniz gerekmez.

Bu, stillerin yazılmasını gerçekten hızlandırır:

Ayrıca, editörünüzün sinir bozucu hatalara neden olabilecek herhangi bir yazım hatası yapmadığınızdan emin olmak için omzunuzun üzerinden izlediği anlamına gelir.

vanilya özü türleri, tür tanımlarında sözdiziminin bir açıklamasını da sağlar. ve için bir bağlantı MDN belgeleri düzenlemekte olduğunuz CSS özelliği için. Bu, stiller beklenmedik şekilde davrandığında çılgınca Googling adımını ortadan kaldırır.

İmlecin fontKerning özelliği üzerinde gezindiği VSCode görüntüsü ve özelliğin Mozilla belgelerine bir bağlantıyla özelliğin ne yaptığını açıklayan bir açılır pencere

TypeScript'te yazmak, aşağıdaki gibi CSS özellikleri için büyük harfli adlar kullandığınız anlamına gelir. backgroundColor. Bu, örneğin normal CSS sözdizimi kullanan geliştiriciler için biraz değişiklik olabilir. background-color.

Entegrasyonlar

vanilya özütü, en yeni paketleyicilerin tümü için birinci sınıf entegrasyonlar sağlar. İşte tam listesi entegrasyonlar şu anda destekler:

  • webpack
  • inşa etmek
  • Hayatları
  • birikintileri
  • SonrakiJS
  • Gatsby

Aynı zamanda tamamen çerçeveden bağımsızdır. Yapmanız gereken tek şey, derleme zamanında bir dizeye dönüştürülen Vanilla-Extract'ten sınıf adlarını içe aktarmaktır.

kullanım

Vanilya Özü kullanmak için bir .css.ts bileşenlerinizin içe aktarabileceği dosya. Bu işlevlere yapılan çağrılar, derleme adımında karma ve kapsamlı sınıf adı dizelerine dönüştürülür. Bu kulağa şuna benzer gelebilir CSS Modülleri, ve bu tesadüf değil: Vanilya Özü'nün yaratıcısı, Mark Dalgleish, ayrıca CSS Modüllerinin ortak yaratıcısıdır.

style()

kullanarak otomatik olarak kapsamlı bir CSS sınıfı oluşturabilirsiniz. style() işlev. Öğenin stillerini iletirsiniz, ardından döndürülen değeri dışa aktarırsınız. Bu değeri kullanıcı kodunuzda bir yere aktarın ve kapsamlı bir sınıf adına dönüştürülür.

// title.css.ts
import {style} from "@vanilla-extract/css"; export const titleStyle = style({ backgroundColor: "hsl(210deg,30%,90%)", fontFamily: "helvetica, Sans-Serif", color: "hsl(210deg,60%,25%)", padding: 30, borderRadius: 20,
});
// title.ts
import {titleStyle} from "./title.css"; document.getElementById("root").innerHTML = `<h1 class="${titleStyle}">Vanilla Extract</h1>`;

Medya sorguları ve sözde seçiciler de stil bildirimlerine dahil edilebilir:

// title.css.ts
backgroundColor: "hsl(210deg,30%,90%)",
fontFamily: "helvetica, Sans-Serif",
color: "hsl(210deg,60%,25%)",
padding: 30,
borderRadius: 20, "@media": { "screen and (max-width: 700px)": { padding: 10 }
}, ":hover":{ backgroundColor: "hsl(210deg,70%,80%)"
}

Bunlar style işlev çağrıları, CSS üzerinde ince bir soyutlamadır - tüm özellik adları ve değerleri, aşina olduğunuz CSS özellikleri ve değerleriyle eşlenir. Alışılması gereken bir değişiklik, değerlerin bazen bir sayı olarak bildirilebilmesidir (örn. padding: 30) varsayılan olarak bir piksel birim değeridir, ancak bazı değerlerin bir dize olarak bildirilmesi gerekir (örn. padding: "10px 20px 15px 15px").

Stil işlevinin içine giren özellikler yalnızca tek bir HTML düğümünü etkileyebilir. Bu, bir öğenin alt öğeleri için stiller bildirmek için iç içe yerleştirmeyi kullanamayacağınız anlamına gelir; bu, alışkın olabileceğiniz bir şeydir. şımarıklık or CSS sonrası. Bunun yerine, çocukları ayrı ayrı stillendirmeniz gerekir. Bir alt öğenin farklı stillere ihtiyacı varsa merkezli ebeveyn üzerinde, kullanabilirsiniz selectors ebeveyne bağlı stiller ekleme özelliği:

// title.css.ts
export const innerSpan = style({ selectors:{[`${titleStyle} &`]:{ color: "hsl(190deg,90%,25%)", fontStyle: "italic", textDecoration: "underline" }}
});
// title.ts
import {titleStyle,innerSpan} from "./title.css";
document.getElementById("root").innerHTML = `<h1 class="${titleStyle}">Vanilla <span class="${innerSpan}">Extract</span></h1>
<span class="${innerSpan}">Unstyled</span>`;

Veya, alt düğümler tarafından tüketilen ana öğede özel özellikler oluşturmak için Tema API'sini de kullanabilirsiniz (bir sonraki adıma geçeceğiz). Bu kısıtlayıcı gelebilir, ancak daha büyük kod tabanlarında sürdürülebilirliği artırmak için kasıtlı olarak bu şekilde bırakılmıştır. Bu, projenizdeki her öğe için stillerin tam olarak nerede bildirildiğini bileceğiniz anlamına gelir.

Temalar

Sen kullanabilirsiniz createTheme bir TypeScript nesnesinde değişkenler oluşturma işlevi:

// title.css.ts
import {style,createTheme } from "@vanilla-extract/css"; // Creating the theme
export const [mainTheme,vars] = createTheme({ color:{ text: "hsl(210deg,60%,25%)", background: "hsl(210deg,30%,90%)" }, lengths:{ mediumGap: "30px" }
}) // Using the theme
export const titleStyle = style({ backgroundColor:vars.color.background, color: vars.color.text, fontFamily: "helvetica, Sans-Serif", padding: vars.lengths.mediumGap, borderRadius: 20,
});

Ardından vanilya özü, temanızın bir çeşidini yapmanızı sağlar. TypeScript, varyantınızın aynı özellik adlarının tümünü kullanmasını sağlamasına yardımcı olur, böylece eklemeyi unutursanız bir uyarı alırsınız. background temanın özelliği.

Bir temanın bildirildiğini, ancak arka plan özelliğinin eksik olduğunu gösteren, özelliğin unutulduğunu uyarmak için büyük miktarda kırmızı dalgalı çizgiye neden olan VS Kodunun görüntüsü

Normal bir temayı ve karanlık modu şu şekilde oluşturabilirsiniz:

// title.css.ts
import {style,createTheme } from "@vanilla-extract/css"; export const [mainTheme,vars] = createTheme({ color:{ text: "hsl(210deg,60%,25%)", background: "hsl(210deg,30%,90%)" }, lengths:{ mediumGap: "30px" }
})
// Theme variant - note this part does not use the array syntax
export const darkMode = createTheme(vars,{ color:{ text:"hsl(210deg,60%,80%)", background: "hsl(210deg,30%,7%)", }, lengths:{ mediumGap: "30px" }
})
// Consuming the theme export const titleStyle = style({ backgroundColor: vars.color.background, color: vars.color.text, fontFamily: "helvetica, Sans-Serif", padding: vars.lengths.mediumGap, borderRadius: 20,
});

Ardından, JavaScript'i kullanarak, temalar arasında geçiş yapmak için Vanilla-extract tarafından döndürülen sınıf adlarını dinamik olarak uygulayabilirsiniz:

// title.ts
import {titleStyle,mainTheme,darkMode} from "./title.css"; document.getElementById("root").innerHTML = `<div class="${mainTheme}" id="wrapper"> <h1 class="${titleStyle}">Vanilla Extract</h1> <button onClick="document.getElementById('wrapper').className='${darkMode}'">Dark mode</button>
</div>`

Bu, kaputun altında nasıl çalışır? içinde beyan ettiğiniz nesneler createTheme işlev, öğenin sınıfına eklenmiş CSS özel özelliklerine dönüştürülür. Bu özel özellikler, çakışmaları önlemek için karma hale getirilir. Bizim için çıktı CSS mainTheme örnek şuna benziyor:

.src__ohrzop0 { --color-brand__ohrzop1: hsl(210deg,80%,25%); --color-text__ohrzop2: hsl(210deg,60%,25%); --color-background__ohrzop3: hsl(210deg,30%,90%); --lengths-mediumGap__ohrzop4: 30px;
}

Ve CSS çıktımızın darkMode tema şuna benziyor:

.src__ohrzop5 { --color-brand__ohrzop1: hsl(210deg,80%,60%); --color-text__ohrzop2: hsl(210deg,60%,80%); --color-background__ohrzop3: hsl(210deg,30%,10%); --lengths-mediumGap__ohrzop4: 30px;
}

Bu nedenle, kullanıcı kodumuzda değiştirmemiz gereken tek şey sınıf adıdır. Uygulamak darkmode üst öğeye sınıf adı ve mainTheme özel mülkler takas edilir darkMode olanlar.

Tarifler API'sı

The style ve createTheme işlevler, bir web sitesini kendi başlarına biçimlendirmek için yeterli gücü sağlar, ancak vanilya özü, yeniden kullanılabilirliği teşvik etmek için birkaç ekstra API sağlar. Tarifler API'si, bir öğe için işaretleme veya kullanıcı kodunuzdan seçebileceğiniz bir dizi varyant oluşturmanıza olanak tanır.

İlk olarak, ayrı olarak kurulması gerekir:

npm install @vanilla-extract/recipes

İşte nasıl çalıştığı. sen ithal et recipe işlev ve özelliklere sahip bir nesneyi iletin base ve variants:

// button.css.ts
import { recipe } from '@vanilla-extract/recipes'; export const buttonStyles = recipe({ base:{ // Styles that get applied to ALL buttons go in here }, variants:{ // Styles that we choose from go in here }
});

içeride base, uygulanacak stilleri bildirebilirsiniz herşey varyantlar. İçeri variants, öğeyi özelleştirmek için farklı yollar sağlayabilirsiniz:

// button.css.ts
import { recipe } from '@vanilla-extract/recipes';
export const buttonStyles = recipe({ base: { fontWeight: "bold", }, variants: { color: { normal: { backgroundColor: "hsl(210deg,30%,90%)", }, callToAction: { backgroundColor: "hsl(210deg,80%,65%)", }, }, size: { large: { padding: 30, }, medium: { padding: 15, }, }, },
});

Ardından, işaretlemede hangi varyantı kullanmak istediğinizi bildirebilirsiniz:

// button.ts
import { buttonStyles } from "./button.css"; <button class=`${buttonStyles({color: "normal",size: "medium",})}`>Click me</button>

Vanilya özütü, TypeScript için otomatik tamamlama özelliğinden yararlanır. kendi varyant isimleri!

Varyantlarınızı istediğiniz gibi adlandırabilir ve bunlara istediğiniz özellikleri şu şekilde koyabilirsiniz:

// button.css.ts
export const buttonStyles = recipe({ variants: { animal: { dog: { backgroundImage: 'url("./dog.png")', }, cat: { backgroundImage: 'url("./cat.png")', }, rabbit: { backgroundImage: 'url("./rabbit.png")', }, }, },
});

Yeniden kullanılabilir bileşenler oluşturabildiğiniz ve bunların değişiklik yollarını kontrol edebildiğiniz için bunun bir tasarım sistemi oluşturmak için nasıl inanılmaz derecede yararlı olacağını görebilirsiniz. Bu varyasyonlar TypeScript ile kolayca keşfedilebilir hale gelir - yazmanız gereken tek şey CMD/CTRL + Space (çoğu düzenleyicide) ve bileşeninizi özelleştirmenin farklı yollarının bir açılır listesini alırsınız.

Sprinkles ile Fayda-Önce

Sprinkles, vanilya özü üzerine inşa edilmiş, yardımcı program öncelikli bir çerçevedir. Vanilya özü belgeleri bu şekilde bunu açıkla:

Temel olarak, kendi sıfır çalışma zamanına sahip, tür güvenli sürümünüzü oluşturmak gibidir. Tailwind, Tarz Sistemi, vb.

Öyleyse, bir şeyleri adlandırmanın hayranı değilseniz (hepimizin bir şeyler yaratma kabusları vardır). outer-wrapper div sonra onu bir . . . outer-outer-wrapper ) Vanilya özü kullanmak için tercih ettiğiniz yol serpme olabilir.

Sprinkles API'sinin de ayrıca yüklenmesi gerekir:

npm install @vanilla-extract/sprinkles

Şimdi, yardımcı işlevlerimizin kullanması için bazı yapı taşları oluşturabiliriz. Birkaç nesne bildirerek bir renk ve uzunluk listesi oluşturalım. JavaScript anahtar adları istediğimiz her şey olabilir. Değerlerin, bunları aşağıdakiler için kullanmayı planladığımız CSS özellikleri için geçerli CSS değerleri olması gerekir:

// sprinkles.css.ts
const colors = { blue100: "hsl(210deg,70%,15%)", blue200: "hsl(210deg,60%,25%)", blue300: "hsl(210deg,55%,35%)", blue400: "hsl(210deg,50%,45%)", blue500: "hsl(210deg,45%,55%)", blue600: "hsl(210deg,50%,65%)", blue700: "hsl(207deg,55%,75%)", blue800: "hsl(205deg,60%,80%)", blue900: "hsl(203deg,70%,85%)",
}; const lengths = { small: "4px", medium: "8px", large: "16px", humungous: "64px"
};

Bu değerlerin hangi CSS özelliklerine uygulanacağını aşağıdaki komutu kullanarak bildirebiliriz. defineProperties işlevi:

  • ile bir nesne iletin properties özelliği.
  • In properties, bir nesne ilan ediyoruz. anahtarlar kullanıcının ayarlayabileceği CSS özellikleridir (bunların geçerli CSS özellikleri olması gerekir) ve değerlerimiz daha önce yarattığımız nesnelerdir (listelerimiz colors ve lengths).
// sprinkles.css.ts
import { defineProperties } from "@vanilla-extract/sprinkles"; const colors = { blue100: "hsl(210deg,70%,15%)" // etc.
} const lengths = { small: "4px", // etc.
} const properties = defineProperties({ properties: { // The keys of this object need to be valid CSS properties // The values are the options we provide the user color: colors, backgroundColor: colors, padding: lengths, },
});

Ardından son adım, dönüş değerini geçmektir. defineProperties için createSprinkles işlev ve döndürülen değeri dışa aktarın:

// sprinkles.css.ts
import { defineProperties, createSprinkles } from "@vanilla-extract/sprinkles"; const colors = { blue100: "hsl(210deg,70%,15%)" // etc.
} const lengths = { small: "4px", // etc. } const properties = defineProperties({ properties: { color: colors, // etc. },
});
export const sprinkles = createSprinkles(properties);

Ardından, bileşenlerimizi arayarak satır içi şekillendirmeye başlayabiliriz. sprinkles class özniteliğinde işlev ve her öğe için hangi seçenekleri istediğimizi seçme.

// index.ts
import { sprinkles } from "./sprinkles.css";
document.getElementById("root").innerHTML = `<button class="${sprinkles({ color: "blue200", backgroundColor: "blue800", padding: "large",
})}">Click me</button>
</div>`;

JavaScript çıktısı, her stil özelliği için bir sınıf adı dizesi tutar. Bu sınıf adları, çıktı CSS dosyasındaki tek bir kuralla eşleşir.

<button class="src_color_blue200__ohrzop1 src_backgroundColor_blue800__ohrzopg src_padding_large__ohrzopk">Click me</button>

Gördüğünüz gibi, bu API, önceden tanımlanmış bir dizi kısıtlama kullanarak işaretlemenizin içindeki öğelere stil vermenizi sağlar. Ayrıca, her öğe için sınıf adları bulmak gibi zor bir görevden de kaçınırsınız. Sonuç, Tailwind'e çok benzeyen bir şey ama aynı zamanda TypeScript etrafında oluşturulmuş tüm altyapıdan da yararlanıyor.

Sprinkles API ayrıca yazmanıza da olanak tanır. koşullar ve stenografi yardımcı program sınıflarını kullanarak duyarlı stiller oluşturmak için.

Tamamlayan

vanilya özü, CSS araçlarında yeni ve büyük bir adım gibi geliyor. Statik yazmanın sağladığı tüm gücü kullanan stil için sezgisel, sağlam bir çözüm oluşturmak için çok düşünüldü.

Ek okuma

Kaynak: https://css-tricks.com/css-in-typescript-with-vanilla-extract/

Zaman Damgası:

Den fazla CSS Püf Noktaları