CSS'ye bir sorgu dili olarak bakmak
(evdc.me)- Seçiciler ve kurallar ile hedef kümesini seçip özellik uygulayan CSS yapısı, kümeler ve kurallarla çalışan Datalog ile biçimsel olarak benzeşir
div.awesomegibi seçici birleşimleri bir kesişim oluşturur; Datalog'da ise aynı değişkeni tekrar etme yoluyla benzer bir join gerçekleşir- Günümüz CSS'i, hesaplanmış stil sonucunu tekrar seçim koşulu olarak kullanamadığı için özyineli geçişli sorguları ya da türetilmiş durumların yinelemeli yayılımını doğrudan ifade etmekte zorlanır
- Datalog, özyineli kurallar ve sabit nokta değerlendirmesi ile yeni olgular artık üretilmeyene kadar ilişkileri genişletir; monotonluk sayesinde sonlu bir kapsamda hesaplamayı tamamlayabilir
- Gerçek CSS, Container Queries gibi özelliklerle ata bilgisini okuyabilir; ancak geri besleme döngülerini ve çevrimleri engelleme yönünü seçmiştir, buna rağmen CSS sözdizimini özyineli sorgulara uyarlamak için alan hâlâ vardır
CSS ve Datalog'un benzer yapısı
- CSS, hedef kümesini seçme ve seçilen hedefe kural uygulama yapısına sahiptir
- HTML öğeleri gibi "Things" önce var olur ve selector ortak özelliklere sahip kümeyi gösterir
div,#child,.awesome,[data-custom-attribute="foo"]gibi selector'larla kümeler tanımlanabilirdiv.awesomegibi selector'lar birleştirilerek kesişim oluşturulabilir
- CSS kuralları, selector ve declaration'ı bir araya getirerek seçilen öğelerde
colorveyafont-sizegibi özellikleri ayarlar- Ancak bu özellikler çoğunlukla dilin dışındaki durumu değiştirir ve bu sonucu tekrar selector koşulu hâline getiremez
div[color=red]gibi stil sonucunu yeniden sorgulayan bir biçimi tarayıcı kabul etmez
- Datalog da benzer şekilde olgu kümesi ve kurala dayalı türetim ile çalışır
parent(alice, bob)gibi atomlar ve relation'lar temel birimi oluştururX,Ydeğişkenleri kullanılarak koşula uyan öğe kümeleri seçilebilir- Aynı değişken tekrar edilerek koşullar bağlandığında, CSS'teki selector birleşimine benzer bir join oluşur
head(X, Y) :- body1(X, Z), body2(Z, Y)yapısı, yönü ters olsa da CSS kuralına biçimsel olarak benzer- CSS'teki selector, Datalog'un body kısmına daha yakındır; declaration ise head'e daha yakındır
div.awesome { color: red; },color(X, red) :- div(X), class(X, awesome).ile eşleşir
CSS'in yapamadığı özyineli sorgular
data-theme="dark"içindeki tüm odaklanmış öğelere ters stil uygulamak, ama aradadata-theme="light"çıkarsa durmak koşulu bir geçişli sorgu gerektirir- Gerçek CSS'te bu durum
[data-theme="dark"] :focusve[data-theme="dark"] [data-theme="light"] :focusgibi kurallarla ancak kısmen ele alınabilir - İç içe seviye arttıkça yeni kurallar eklemek gerekir; özyineli ilişkiyi doğrudan ifade etmek zordur
- Gerçek CSS'te bu durum
- Gerekli olan koşul, bir öğenin effectively-dark olup olmadığını özyineli biçimde belirlemektir
- Kendisi
data-theme="dark"ise effectively-dark olur - effectively-dark bir atanın altındaki çocuk da, arada
data-theme="light"yoksa effectively-dark olur - Bu duruma dayanarak
.effectively-dark :focusiçin stil uygulanmalıdır
- Kendisi
- Varsayımsal CSSLog sözdiziminde kurallar,
class: +effectively-darkgibi türetilmiş durum ekleyebilir.effectively-dark > :not([data-theme="light"])çocuğa durumu yayar- Kurallar, hedef duruma ulaşılana kadar özyineli olarak tekrar uygulanmalıdır
- Bu tür özyineli yayılımı günümüz CSS'iyle ifade etmek zordur
- Yazının sonunda buna kısmen benzeyen bazı taklit yöntemler de verilir, ancak bunlar aynı ilkenin genel çözümü değildir
Datalog'da özyineleme ve sabit nokta
- Datalog, mevcut olgulardan yeni olgular türetme biçiminde çalışır ve özyinelemeyi doğal olarak ele alır
ancestor(X, Y) :- parent(X, Y).ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).
ancestorkuralı, ebeveyn ilişkisine dayanarak ata ilişkisini adım adım genişletirparent(alice, bob)üzerinden önceancestor(alice, bob)oluşur- Ardından
alice -> bob -> carol,alice -> bob -> davegibi yollar da ek olarak türetilir
- Bu hesaplama, açık bir
fordöngüsü olmadan bile sabit nokta değerlendirmesi ile sona kadar ilerler- Başta yalnızca tanımlanmış temel olgular kullanılır
- Tüm kuralların body kısmı mevcut olgu kümesine uygulanır ve head kısmı eklenir
- Yeni olgu artık üretilmeyince durur
- Bu yaklaşımın sonlanma nedeni monotonluktur
- Olgular sadece eklenir, kaldırılmaz; bu yüzden bilinen olgu kümesi sürekli büyür
- Sonlu bir olgu kümesinden başlanırsa, türetilebilir olgu sayısı da sonlu kalır
- Tersine, olgular kaldırılabilseydi önceki sonuçlar tersine dönebilir ve sonsuz döngü oluşabilirdi
Container Queries ve gerçek CSS'in sınırları
- Gerçek CSS'teki Container Queries, kural uygulamak için ata ya da container stilini ölçüt alabilir
@container style(--theme: dark) { .card { background: royalblue; color: white; } }gibi yapıları destekler
- Ancak geçişli dark mode örneği, basit ata sorgulamasından daha güçlü bir koşul gerektirir
- Her öğenin kendisinin effectively-dark olup olmadığını bilmesi gerekir
- Bu durumun tüm alt soya geçişli olarak yayılması gerekir
- Yayılım,
data-theme="light"sınırında durmalıdır
- Container Queries ikinci koşulu karşılayamaz
- Atanın custom property değerini okuyabilir, ama başka kuralların önceden hesapladığı türetilmiş durumu yeniden sorgulayamaz
- DOM'da baştan var olan bilgiyi görebilir, ancak özyineli hesaplama sonucunu selector koşulu yapamaz
- 2015 tarihli ilgili yazı da element queries'in aynı soruna çarptığını belirtir
- Sorguyla ayarlanan özelliğin tekrar sorgulanabilmesi, döngü ve sonsuz tekrar riskini büyütür
- CSS Working Group, bu sorundan bilgi akış yönünü sınırlayarak kaçınmıştır
- Alt soyun ata bilgisini sorgulamasına izin verir
- Ters yöndeki geri beslemeyi ya da öğenin kendi stiline dönen çevrimi engeller
- Böylece sabit nokta semantiği olmadan da hesaplamayı sonlu tutar
CSS sözdizimini özyineli sorgu diline çevirebilme olasılığı
- Datalog semantiğini CSS'e yerleştirmektense, CSS sözdizimini Datalog üzerine kurmak daha gerçekçi yeni bir yol olarak sunuluyor
- Datalog'un
:-, nokta ve deklarasyonsuz atomlar gibi sözdizimi, modern dil kullanıcıları için yüksek bir giriş eşiği oluşturur - CSS ise zaten ağaç yapılarıyla çalışmak için zengin bir selector sözdizimine sahiptir
- Datalog'un
- Gerçek verilerin önemli bir kısmının ağaç biçimli olduğuna dikkat çekiliyor
- JSON
- AST
- dosya sistemi
- organizasyon şeması
- XML
- Bu alanlarda ebeveyn/çocuk ilişkilerini örtük olarak ele alan CSS benzeri sözdizimi ile sabit noktalı özyineleme birleştirildiğinde yararlı olabilir
- Genel Datalog'da ağaç yapısını ilişkisel gösterime çevirmek gerektiğinden kullanım zahmetlidir
- CSS selector sezgisini doğrudan özyineli sorgulara taşımak, daha fazla programcının buna kolayca yaklaşmasını sağlayabilir
- Bu tür bir araç henüz belirgin biçimde görünmüyor
- "CSSLog" adı geçici bir ad ve daha iyi isimli bir dil ortaya çıkabilir
- Özyineli ağaç sorgularını daha tanıdık bir gösterimle ele alma alanı hâlâ açık
Ek noktalar ve referans bağlantıları
- Datalog, 1970'lerden beri ilişkisel veritabanları ve dönemin yapay zeka araştırmaları bağlamında ortaya çıktı; sonrasında da farklı biçimlerde tekrar tekrar geri döndü
- Sabit nokta hesaplamasının basit biçimi naive evaluation olarak tanıtılır; ancak her seferinde zaten bilinen olguları yeniden hesapladığı için verimsiz olabilir
- Her adımda yalnızca yeni üretilen olguları kullanan semi-naive evaluation, tipik bir iyileştirme yönü olarak ayrıca anılır
- Monotonluk, dağıtık sistemlerde de faydalı özellikler sağlar
- custom property kalıtımıyla geçişli dark mode'u kısmen taklit etmenin bir yolu da vardır
[data-theme="dark"] { --effective-theme: dark; }[data-theme="light"] { --effective-theme: light; }@container style(--effective-theme: dark) { :focus { outline-color: white; } }- Bu yöntem bu özel durumda çoğunlukla çalışsa da, genel anlamda gerçek geçişli kapanış sağlamaz
1 yorum
Hacker News görüşleri
CSS seçicileri, XPath'a göre çok daha kolay yazılıyor
Kısa süre önce de PHP'nin yeni DOM API'sinin HTML ve CSS seçicilerini yerel olarak çok kolay ele alabildiğini anlatan bir sunum yapılmıştı. Eskiden CSS'yi XPath'e dönüştürmek gerekiyordu
[1] https://speakerdeck.com/keyvan/parsing-html-with-php-8-dot-4...
Tarayıcı stil verme odağıyla geliştiği için, XPath'teki gibi metin içeriğine göre seçim gibi özelliklerin olmaması üzücü
Bildiğim kadarıyla geçmişte öneriler oldu ama tarayıcıların render bağlamında performans sorunları yaratabileceği için spesifikasyona giremedi
Belge düzenleme ajanı yaparken belgeyi HTML olarak gösterip LLM'in yalnızca CSS selector belirleyerek gerekli parçaları bağlama çekmesini sağladım; neredeyse sihir gibi iyi çalıştı
İnsanlar alışık oldukları yöntemi aynen kullanabiliyor
CSS sözdizimi ile CSSWG'nin tanımladığı kurallar, fonksiyonlar ve birimler gibi tüm sistemi ayırarak adlandırmak için bir isim olsa iyi olurdu
Burada epey potansiyel var ama başka kullanım örneklerini konuşmak ya da araştırmak isteyince, sonunda CSS ayrıştırıcısı kullanan GitHub kodlarını kurcalayıp insanların ne tür garip şeyler yaptığını görmekten başka çare yok gibi duruyor
Hafif bir düğüm tabanlı işaretleme dili, şablona neyin gireceğini ifade eden CSS seçicileri ve bu parçaların nasıl birleştirileceğini kontrol eden CSS benzeri bir sözdizimini karıştıran tuhaf bir şablon motoru benzeri şeylerle de oynuyorum
https://www.w3.org/TR/selectors-3/
DOM spesifikasyonu da buna referans veriyor
https://dom.spec.whatwg.org/#selectors
Bu yüzden genel ad olarak CSS selector zaten doğru; hatta sadece selector da denebilir
DOM selector adı daha derli toplu görünebilir ama statik CSS'te kullanılan seçicileri ya da JS motoru dışındaki başka DOM motorlarında (XML parser, PHP DOM API vb.) kullanılan seçicileri de düşününce, aslında daha da kafa karıştırıcı olabilir
Ayrıca
:hoverya da::target-textgibi doğrudan tarayıcı render etme/gezinme davranışına bağlı özel seçiciler de varYine de tarayıcıya ya da CSS'e daha az bağlı olan asgari sorgu sözdizimi altkümesi için ayrı bir isim faydalı olabilir
Eskiden bir konferansta gördüğüm https://github.com/braposo/graphql-css aklıma geldi
Şaka amaçlı bir projeydi ama kalıpları başka bağlamlara taşıyıp yeniden kullanmanın beklenmedik şeyleri mümkün kıldığını iyi göstermesi hoşuma gitmişti
Ben de tam böyle, farklı bağlamlardaki kalıpları alıp kullanmayı deniyorum
Çoğu çok ileri gitmese de hacker ruhu açısından oldukça ilgi çekici
pyastgrep, https://pyastgrep.readthedocs.io/en/latest/ adresinde görüldüğü gibi Python sözdizimini sorgularken CSS seçicileri kullanabiliyor
Varsayılanı XPath; örneğin
pyastgrep --css 'Call > func > Name#main'gibi kullanılabiliyorAnlatmak istediğim yönle neredeyse tam olarak örtüşüyor
Bunun hangi senaryoyu çözdüğünü pek anlamadım
Şu anda da çocuğa göre ebeveyni koşullu olarak değiştirebiliyorsunuz. Mesela
preiçin varsayılan padding 16px ise ve doğrudan çocuğucodeise,&:has(> code)ile bunu 0 yapabilirsinizSonuç da "modern CSS'nin sınırlarını düzeltmeliyiz"den çok, CSS benzeri bir sözdizimini Datalog benzeri bir sistemin üstüne koymanın ağaç biçimli verilerle çalışmayı daha fazla mühendis için tanıdık hale getirip getiremeyeceğine yakın
Yani DOM'a yeni alt öğeler ya da nitelikler eklemekten söz ediliyor
Günümüz LLM'leri CSS ile çok da iyi değil; bu yüzden bunu deneyince LLM'in daha basit şekilde akıl yürütüp yürütemeyeceğini görmek istiyorum
Gerçek bir faydası hemen aklıma gelmiyor ama yine de havalı
Hmm... Bu aslında sadece JQ değil mi?
CSS'yi belli ölçüde seviyorum ama karmaşıklığın sürünerek artması giderek canımı sıkıyor
Programlama dillerinin programlama dışı dillere göre daha güçlü hale gelmesi mantığını anlıyorum ama HTML, CSS ve JavaScript'i sürekli daha karmaşık hale getirmek yerine, keşke bunların tümünün yerini alacak başka bir şey çıksa diye düşünüyorum
HTML5'in yeni öğelerinin çoğunun neden gerekli olduğunu da pek anlamadığım için neredeyse hiç kullanmıyorum. Sonunda birçok kapsayıcının benzersiz kimlik verilmiş birer
divolduğu sonucuna vardım; hatta dahili bağlantılar içinhrefgezinmesinde kullanılacak bu kimlikler için bir tür takma ad olsa iyi olurdu diye düşündüm[data-theme="dark"] [data-theme="light"] :focus { outline-color: black; }gibi şeyleri kafamda çözümlemek çok uzun sürdüğü için artık zarif ve basit gelmiyorBuna karşılık
h2 { color: red; }hâlâ basitancestor(X, Y) :- parent(X, Y).gibi bir ifade ise daha şimdiden düşünmek istemediğim türden.:-de ne oluyor, gülen yüz gibi duruyor@container style(--theme: dark) { .card { background: royalblue; color: white; } }ifadesinde okumayı bıraktımEskiden iyi işleyen standartlar zamanla bozuluyormuş gibi gelmesi garip
Örneğin
[data-theme="dark"] [data-theme="light"] :focus { outline-color: black; }ifadesini İngilizce benzeri sözde koda açarsak,data-theme="dark"olan bir X var ve onun çocuğu olan Y'nindata-theme="light"olup odakta olması durumunda Y'ninoutline-colordeğerini black yap demeye yakınDolayısıyla bunu Datalog tarzında
outline-color(Y, black) if data-theme(X, "dark") and parent(X, Y) and data-theme(Y, "light") and focused(Y)şeklinde yazabilirsinizYani
:-yerineif, virgül yerineandkoymuş oluyoruzDaha da ileri gidip
Y.outline_color := black if X.data-theme == dark and Y.parent == X and Y.data-theme == dark and Y.focuseddiye yazarak,attr(X, val)biçiminiX.attr == valgibi UFCS benzeri bir sözdizimsel şeker halinde göstermek de mümkünDaha ALGOL ailesinden görünmesini isterseniz
forall Y { Y.outline_color := black if Y.data_theme == "dark" and Y.focused and Y.parent.data_theme == "light" }gibi de yazılabilirBurada Y'yi açıkça tanıtıp bir join'i örtük hale getirerek daha genel amaçlı programlama gibi gösteriyorsunuz ama pratikte olan şey, bağımlılıklar her değiştiğinde Datalog motorunun bu tür döngüleri verimli şekilde yeniden çalıştırmasıdır