SMACSS'yi Keşfetmek: CSS için Ölçeklenebilir ve Modüler Mimari

Yayınlanan: 2022-03-11

Büyük projeler üzerinde veya geliştirici gruplarıyla çalışırken, genellikle kodumuzun dağınık, okunması zor ve genişletilmesi zor olduğunu görürüz. Bu özellikle zaman geçtikten sonra geçerlidir ve geri dönüp ona tekrar bakarız - onu yazarken bulunduğumuz zihniyette olmaya çalışmalıyız.

Pek çok insan, CSS'nin daha okunabilir hale gelmesi için kodlarını biçimlendirmeye yardımcı olacak CSS mimarileri yarattılar. SMACSS —yani, CSS için Ölçeklenebilir ve Modüler Mimari — tam da bunu yapmayı amaçlar. Jonathan Snook'tan benimsediğim belirli bir CSS mimarisi yönergeleri seti.

Şimdi, SMACSS'nin mimari yaklaşımı, Bootstrap veya Foundation gibi bir CSS çerçevesinden biraz farklıdır. Bunun yerine, daha çok bir şablon veya kılavuz gibi bir dizi kuraldır. Öyleyse, kodumuzu daha iyi, daha temiz, okunması daha kolay ve daha modüler hale getirmek için bunları nasıl kullanabileceğimizi öğrenmek için bazı CSS tasarım kalıplarına dalalım.

Her SMACSS proje yapısı beş kategori kullanır:

  1. Temel
  2. Düzen
  3. Modüller
  4. Belirtmek, bildirmek
  5. Tema

Temel

SMACSS'de temel stiller, bir öğenin sayfanın herhangi bir yerinde nasıl görünmesi gerektiğini tanımlar. Onlar varsayılanlardır. Bir sıfırlama stil sayfası kullanıyorsanız, bu, dahili, sabit kodlanmış temel CSS varsayılanları arasındaki farklılıklara rağmen ortaya çıkan stillerinizin tarayıcılar arasında aynı olmasını sağlar.

Bir temel stilde, yalnızca çıplak öğe seçicilerini veya sözde sınıfları olanları dahil etmelisiniz, ancak sınıf veya kimlik seçicileri dahil etmemelisiniz. (İçine sınıf veya kimlik koymak için gerçekten iyi bir nedeniniz olmalı, belki yalnızca üçüncü taraf bir eklentinin öğelerini şekillendiriyorsanız ve o belirli öğe için varsayılan stili geçersiz kılmanız gerekiyorsa.)

Temel dosya biriminin nasıl görünmesi gerektiğine dair bir örnek:

 html { margin: 0; font-family: sans-serif; } a { color: #000; } button { color: #ababab; border: 1px solid #f2f2f2; }

Bu nedenle, web sitenizde kullanmayı planladığınız varsayılan boyutları, kenar boşluklarını, renkleri, kenarlıkları ve diğer varsayılan değerleri içermelidir. Tipografiniz ve form öğeleriniz, her sayfada görünen ve aynı tasarım ve temanın parçası oldukları hissi ve görünümü veren birleşik stillere sahip olmalıdır.

SMACSS olsun ya da olmasın, mümkün olduğunca !important kullanımından kaçınmanızı ve derin yuvalama kullanmamanızı şiddetle tavsiye ederim, ancak bunun hakkında daha sonra bu yazıda bahsedeceğim. Ayrıca uygulamanız CSS'yi sıfırlamaksa, onu eklemeniz gereken yer burasıdır. (Sass kullanmayı tercih ediyorum, bu yüzden onu kopyalamak veya her sayfanın <head> öğesinden ayrı olarak başvurmak yerine dosyanın en üstüne ekliyorum.)

İlgili: Sass ile Tema Oluşturma: Bir SCSS Eğitimi

Düzen

Mizanpaj stilleri sayfayı ana bölümlere ayıracaktır; örneğin gezinme veya akordeon gibi bölümlere değil, gerçekten üst düzey bölümlere:

Örnek SMACSS düzen stilleri: üstbilgi, kenar çubuğu, içerik/ana ve altbilgi

SMACSS düzen stilleri üstbilgi, kenar çubuğu, içerik/ana ve altbilgi gibi ana bölümler içindir.

Bu düzenler kutular, kartlar, sırasız listeler, galeriler ve benzerleri gibi birden fazla CSS modülünü barındıracak, ancak bir sonraki bölümde modüller hakkında daha fazla konuşacağım. Neleri düzenlere ayırabileceğimizi görmek için örnek bir web sayfası düşünelim:

SMACSS kullanılarak üstbilgi, ana ve altbilgi düzen stillerine göre düzenlenebilen örnek bir web sayfası

Burada üstbilgi, ana ve altbilgi var. Bu düzenler, üstte başlıkta bağlantılar ve logo, ana sayfada kutular ve makaleler ve altbilgi için bağlantılar ve telif hakkı gibi modüllere sahiptir. Sayfada tekrarlanmadıkları ve benzersiz oldukları için genellikle düzenlere bir kimlik seçici veririz.

Ayrıca, modül stillerinden ayırt etmek için düzen stilleri için kuralların önüne l harfi koymalısınız. Genellikle burada, kenarlık, hizalamalar, kenar boşlukları vb. gibi mizanpaja özgü şeyleri biçimlendirirsiniz. Ayrıca sayfanın o bölümünün arka planı, yerleşime özgü gibi görünmese bile anlamlı olabilir.

İşte nasıl görünmesi gerektiğine dair bir örnek:

 #header { background: #fcfcfc; } #header .l-right { float: right; } #header .l-align-center { text-align: center; }

Bu yardımcıları ayrıca, uygun sınıfı alt sınıfına ekleyerek veya metnini hizalayarak öğeleri kolayca konumlandırmak için kullanabileceğiniz hizalamalar için de ekleyebilirsiniz.

Başka bir örnek için, bir yerleşim kutusunda, 20px kenar boşluğuna sahip .l-margin gibi bazı varsayılan kenar boşluklarını kullanabilirsiniz. Ardından, herhangi bir kap, eleman, kart veya kutu için dolgu istediğiniz yere l-margin sınıfını eklemeniz yeterlidir. Ama yeniden kullanılabilir bir şey istiyorsun:

 .l-full-width { width: 100%; }

Bunun gibi dahili olarak birleştirilmiş bir şey değil:

 .l-width-25 { width: 25px; }

SMACSS'deki adlandırma kuralları hakkında konuşmak için biraz zaman ayırmak istiyorum. CSS'de ad alanı kavramını hiç duymadıysanız, temelde adı başka bir öğeden ayırt etmeye yardımcı olmak için başka bir öğenin başına eklemektir. Ama neden buna ihtiyacımız var?

Aşağıdaki sorunla hiç karşılaştınız mı bilmiyorum. CSS yazıyorsunuz ve bir şey üzerinde bir etiketiniz var - istediğiniz stilleri koyar ve sınıfınıza .label . Ancak daha sonra başka bir öğeye gelirsiniz ve bunun .label olmasını da istersiniz, ancak farklı şekilde biçimlendirirsiniz. Yani iki farklı şey aynı ada sahip - bir adlandırma çatışması.

Ad alanı, bunu çözmenize yardımcı olur. Sonuçta, bir düzeyde aynı şey olarak adlandırılırlar, ancak farklı bir ad alanına (farklı bir önek) sahiptirler ve bu nedenle iki farklı stili temsil edebilirler:

 .box--label { color: blue; } .card--label { color: red; }

Modül

Daha önce bahsettiğim gibi, SMACSS modülleri sayfada yeniden kullanılabilen daha küçük kod parçalarıdır ve tek bir düzenin parçasıdırlar. Bunlar, tek bir sayfada birçoğu olacağı için ayrı bir klasörde saklamak istediğimiz CSS parçalarıdır. Ve bir proje büyüdükçe, en iyi klasör yapısı uygulamalarını, yani modüllere/sayfalara göre bölebiliriz:

SMACSS ve Sass kullanan örnek bir dosya/klasör hiyerarşisi

Yani önceki örnekte, kendi başına bir modül olabilen bir makalemiz vardı. CSS burada nasıl yapılandırılmalıdır? Alt öğelerin title ve text sahip olabilen bir sınıf .article olmalıdır. Bu yüzden onu aynı modülde tutabilmek için alt öğelerin önüne eklememiz gerekiyor:

 .article { background: #f32; } .article--title { font-size: 16px; } .article--text { font-size: 12px; }

Modül önekinden sonra iki tire kullandığımızı fark edebilirsiniz. Bunun nedeni, bazen modül adlarının iki kelimeye veya big-article gibi kendi öneklerine sahip olmasıdır. Alt öğenin hangi bölümünün alt öğe olduğunu söylemek için iki kısa çizgiye ihtiyacımız var - örneğin, big-article-title big-article--title ve big-article--text karşılaştırın.

Ayrıca, belirli bir modül sayfanın büyük bir bölümünü kaplıyorsa modülleri modüllerin içine yerleştirebilirsiniz:

 <div class="box"> <div class="box--label">This is box label</div> <ul class="box--list list"> <li class="list--li">Box list element</li> </ul> </div>

Burada, bu basit örnekte, box bir modül olduğunu ve list onun içindeki başka bir modül olduğunu görebilirsiniz. Yani list--li , box değil list modülünün bir çocuğudur. Buradaki anahtar kavramlardan biri, her CSS kuralı için en fazla iki seçici kullanmak, ancak çoğu senaryoda öneklere sahip yalnızca bir seçiciye sahip olmaktır.

Bu şekilde, yinelenen kuralları önleyebilir ve aynı ada sahip alt öğeler üzerinde fazladan seçicilere sahip olabiliriz, böylece hızı artırabiliriz. Ama aynı zamanda, kötü yapılandırılmış CSS projelerinin bir işareti olan istenmeyen !important tarzı kuralları kullanmaktan kaçınmamıza da yardımcı olur.

İyi (tek seçiciye dikkat edin):

 .red--box { background: #fafcfe; } .red-box--list { color: #000; }

Kötü (seçiciler içindeki tekrarı ve örtüşen referans yöntemini not edin):

 .red .box { background: #fafcfe; } .red .box .list { color: #000; } .box ul { color: #fafafa; }

Belirtmek, bildirmek

SMACSS'de hangi durumun tanımlandığı, modüllerimizin farklı dinamik durumlarda nasıl göründüğünü tanımlamanın bir yoludur. Dolayısıyla bu kısım gerçekten etkileşim içindir: Bir öğenin gizlendiği, genişletildiği veya değiştirildiği düşünülüyorsa farklı davranışlar istiyoruz. Örneğin, bir jQuery akordeonunun, bir öğenin içeriğini ne zaman görüp göremeyeceğinizi tanımlamak için yardıma ihtiyacı olacaktır. Belirli bir zamanda bir elemanın stilini tanımlamamıza yardımcı olur.

Durumlar, düzen ile aynı öğeye uygulanır, bu nedenle varsa öncekileri geçersiz kılacak ek bir kural ekliyoruz. Devlet kuralına, kurallar zincirindeki son kural olduğu için öncelik verilir.

Düzen stillerinde olduğu gibi, burada önekleri kullanma eğilimindeyiz. Bu, onları tanımamıza ve onlara öncelik vermemize yardımcı olur. Burada is-hidden veya is-selected gibi is önekini kullanıyoruz.

 <header> <ul class="nav"> <li class="nav--item is-selected">Contact</li> <li class="nav--item">About</li> </ul> </header>
 .nav--item.is-selected { color: #fff; }

Burada, durum genellikle oluşturma zamanında değil, JavaScript değişikliği olarak kullanıldığından !important kullanılabilir. Örneğin, sayfa yüklendiğinde gizlenen öğeniz var. Düğme tıklandığında, göstermek istersiniz. Ancak varsayılan sınıf şöyledir:

 .box .element { display: none; }

Yani sadece şunu eklerseniz:

 .is-shown { display: block; }

.is-shown sınıfını JavaScript aracılığıyla öğeye ekledikten sonra bile gizli kalacaktır. Bunun nedeni, ilk kuralın iki seviye derinliğinde olması ve onu geçersiz kılmasıdır.

Bunun yerine durum sınıfını şu şekilde tanımlayabilirsiniz:

 .is-shown { display: block !important; }

Durum değiştiricileri, yalnızca bir sayfanın ilk yüklemesinde geçerli olan düzen olanlardan bu şekilde ayırt ederiz. Bu, minimal seçicilerin avantajlarını korurken şimdi çalışacaktır.

Tema

Bu, ana renklerin, şekillerin, kenarlıkların, gölgelerin ve benzerlerinin kurallarını içermek için kullanıldığından, en bariz olanı olmalıdır. Çoğunlukla bunlar, tüm bir web sitesinde tekrar eden öğelerdir. Onları her oluşturduğumuzda yeniden tanımlamak istemiyoruz. Bunun yerine, yalnızca daha sonra varsayılan bir öğeye ekleyeceğimiz benzersiz bir sınıf tanımlamak istiyoruz.

 .button-large { width: 60px; height: 60px; }
 <button class="button-large">Like</button>

Bu SMACSS tema kurallarını temel kurallarla karıştırmayın, çünkü temel kurallar yalnızca varsayılan görünümü hedefler ve bunlar varsayılan tarayıcı ayarlarına sıfırlama gibi bir şey olma eğilimindeyken, bir tema birimi daha çok son görünümü verdiği bir stil türüdür. bu özel renk şeması için benzersiz.

Tema kuralları, bir sitenin birden fazla stili veya farklı durumlarda kullanılan birkaç teması varsa ve bu nedenle, örneğin bir tema değiştirme düğmesi ile bir sayfadaki bazı etkinlikler sırasında kolayca değiştirilebilir veya değiştirilebilirse de yararlı olabilir. En azından, tüm tema stillerini tek bir yerde tutarlar, böylece onları kolayca değiştirebilir ve güzel bir şekilde organize edebilirsiniz.

CSS Organizasyon Metodolojileri

Bu CSS mimarisi fikrinin bazı temel kavramlarını ele aldım. Bu konsept hakkında daha fazla bilgi edinmek istiyorsanız, SMACSS'nin resmi web sitesini ziyaret edebilir ve daha derine inebilirsiniz.

Evet, muhtemelen OOCSS ve BEM gibi daha gelişmiş metodolojileri kullanabilirsiniz. İkincisi, neredeyse tüm ön uç iş akışını ve teknolojilerini kapsar. BEM seçiciler bazı insanlar için harika çalışabilir, ancak bazıları onları çok uzun ve bunaltıcı ve ayrıca kullanımı çok karmaşık bulabilir. Alması ve iş akışınıza dahil etmesi daha kolay olan daha basit bir şeye ve ayrıca sizin ve ekibiniz için temel kuralları tanımlayan bir şeye ihtiyacınız varsa, SMACSS mükemmel bir seçimdir.

Yeni ekip üyelerinin yalnızca önceki geliştiricilerin ne yaptığını anlaması değil, aynı zamanda kodlama stilinde herhangi bir farklılık olmaksızın anında üzerinde çalışmaya başlaması da kolay olacaktır. SMACSS sadece bir CSS mimarisidir ve kutuda ne yazıyorsa onu yapar - ne eksik ne fazla.