
🎯 Selectors i Elementor-widgeter: komplett guide for utviklere
Hvorfor Elementor-utviklere trenger selektorer og hvordan de fungerer
Når en bruker justerer widget-innstillinger i editoren, forventer de en umiddelbar respons på skjermen. Uten selektorer måtte en utvikler skrevet en JS-handler for hvert felt som endres. Med selektorer løses alt med CSS.
Parameteren selectors (og dens mindre kjente motstykke selectors_dictionary) legges direkte inn i arrayet til add_control()-kallet. Elementor setter dynamisk inn verdier fra felter i CSS-regler og sender dem ut til postfilen, noe sånt som /wp-content/uploads/elementor/css/post-1234.css. Så snart brukeren forlater editoren, forsvinner inline-stiler, og etterlater ren, generert CSS.
💡 Rask oversikt:
- Forstå selektorsyntaks og plassholdertabellen
- Se konkrete eksempler for farge og størrelser
- Lær å hente verdier fra tilstøtende kontroller
- Mestre selectors_dictionary for erstatning av CSS-deklarasjoner
- Legg puslespillet med CSS-variabler og skjulte kontroller
Hvor selektorer defineres
Når du oppretter en widget, aksepterer hvert add_control()-kall et innstillingsarray. Det er akkurat der selectors ligger. For gruppekontroller er syntaksen den samme, arrayet sendes inn i grupperegistreringen.
Grunnformat:
1 'selectors' => [ 2 '{{WRAPPER}} .my-widget-class' => 'color: {{VALUE}}', 3 ]
Nøkkelen er en CSS-selektor (starter med {{WRAPPER}} for å unngå å påvirke tilstøtende widgets på siden). Verdien er én eller flere CSS-deklarasjoner med dynamiske plassholdere. Elementor tar den aktuelle kontrollverdien og setter den inn i stedet for plassholderen.
Resultatet rendres til postens eksterne CSS-fil, stiler eksisterer bare mens editoren er åpen og umiddelbart etter lagring. Ikke noe inline-rot.
Tabell over variabler med krøllparenteser
Ingen magi, bare søk og erstatt. Men variasjonen av plassholdere åpner dører for ganske smarte konstruksjoner.
For selektorer (array-nøkkel)
Plassholder | Hva den erstatter |
|---|---|
| Unik widget-instans-selektor, for eksempel |
| Kun widget-ID-en (delen etter bindestreken, |
| Begrenser regelen til den angitte enheten. Med |
| Aktivt element i en repeater-kontroll |
For deklarasjoner (array-verdi)
Plassholder | Hva den erstatter |
|---|---|
| Rå kontrollverdi. Kan overstyres av |
| Tall og måleenhet fra numeriske kontroller. Opptrer vanligvis i par: |
| Retninger fra dimensjonskontroll |
| Tilgang til navngitt egenskap i sammensatte kontroller: for eksempel returnerer Media Control et array med feltene |
| Verdi fra en annen kontroll etter ID. Suffiksene |
| Fallback: hvis kontrollen er tom, settes |
Enkle eksempler, fra farge til bakgrunnsbilde
Farge fra palett. Ikke noe ekstra:
1 'selectors' => [ 2 '{{WRAPPER}} .elementor-svg-divider-basic-text' => 'color: {{VALUE}}', 3 ],
Numerisk kontroll med og uten enhet. Den andre egenskapen (stroke-width) er bevisst uten {{UNIT}}, strektykkelse er i piksler, uten px:
1 'selectors' => [ 2 '{{WRAPPER}} svg.sde-classic' => 3 'height: {{SIZE}}{{UNIT}}; stroke-width: {{SIZE}};', 4 ],
Avstand fra dimensjonskontroll, hver retning separat:
1 'selectors' => [ 2 '{{WRAPPER}} .elementor-svg-divider-basic-button' => 3 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', 4 ],
Bakgrunnsbilde av et lysbilde i repeater-kontroll:
1 'selectors' => [ 2 '{{WRAPPER}} {{CURRENT_ITEM}} .swiper-slide-bg' => 3 'background-image: url({{URL}})', 4 ],
Betinget posisjon for RTL. Samme kontroll gir ulike egenskaper avhengig av tekstretning:
1 'selectors' => [ 2 'body:not(.rtl) {{WRAPPER}} .dialog-close-button' => 'right: {{SIZE}}{{UNIT}}', 3 'body.rtl {{WRAPPER}} .dialog-close-button' => 'left: {{SIZE}}{{UNIT}}', 4 ],
Hvordan hente en verdi fra en annen kontroll
Hvis to felter påvirker samme CSS, ikke dupliser arrayet, bare referer til den tilstøtende kontrollen:
1 'selectors' => [ 2 '{{WRAPPER}} svg.sde-classic' => 3 'stroke-dasharray: {{dash_length.SIZE}} {{whitespace_length.SIZE}};', 4 ],
Her er dash_length og whitespace_length ID-er til andre kontroller i samme widget. Ingen ekstra kall, bare punktnotasjon.
Responsiv versjon, verdier hentes basert på enheten. Ekte eksempel fra Elementor Pro:
1 'selectors' => [ 2 '(desktop).elementor-msie {{WRAPPER}} .elementor-portfolio-item' => 3 'width: calc( 100% / {{columns.SIZE}} ); border: {{SIZE}}px solid transparent', 4 '(tablet).elementor-msie {{WRAPPER}} .elementor-portfolio-item' => 5 'width: calc( 100% / {{columns_tablet.SIZE}} ); border: {{SIZE}}px solid transparent', 6 '(mobile).elementor-msie {{WRAPPER}} .elementor-portfolio-item' => 7 'width: calc( 100% / {{columns_mobile.SIZE}} ); border: {{SIZE}}px solid transparent', 8 ],
Hvert brytningspunkt får sin egen columns-verdi. De resterende egenskapene (border, SIZE) er felles, de er ikke knyttet til enheten.
Selectors_dictionary, switch-case for CSS
Den mest undervurderte egenskapen. selectors_dictionary erstatter {{VALUE}} med en hardkodet streng, og gjør i praksis kontrollverdien om til en ordboknøkkel.
Ta standardkontrollen for Justering med alternativene venstre/midt/høyre. Uten en ordbok ville du skrevet noe unaturlig:
1 'selectors' => [ 2 $sde_selector => 'margin: 0 auto; margin-{{VALUE}}: 0;', 3 ],
For center produserer dette margin: 0 auto; margin-center: 0;. Egenskapen margin-center finnes ikke, nettleseren ignorerer den i stillhet. Men det ser rotete ut.
Ordboken gjør det samme på en ryddig måte:
1 'selectors_dictionary' => [ 2 'left' => 'margin-right: auto', 3 'center' => 'margin: 0 auto', 4 'right' => 'margin-left: auto', 5 ], 6 'selectors' => [ 7 '{{WRAPPER}} .sde' => '{{VALUE}}', 8 ],
Kontrollverdi center → {{VALUE}} blir til margin: 0 auto. Det er alt.
Viktig begrensning: etter at du har aktivert selectors_dictionary mister du den opprinnelige {{VALUE}}. Hvis den samme matrisen har et annet selector-declaration-par som trenger den opprinnelige verdien, vil det motta den allerede substituerte strengen. Her er et problematisk eksempel:
1 'selectors' => [ 2 '{{WRAPPER}} .sde' => '{{VALUE}}', 3 '{{WRAPPER}}.elementor-sde-scale-the-cropped .sde-cropping-allow .sde' => 4 'transform-origin: {{VALUE}} 0;', 5 ],
Her vil transform-origin motta margin: 0 auto 0; i stedet for center 0;. Løsning: trekk ut avhengige deklarasjoner til en separat kontroll.
Ordboken håndterer også oversettelse av enkeltstående CSS-verdier godt:
1 'selectors_dictionary' => [ 2 'top' => 'flex-start', 3 'middle' => 'center', 4 'bottom' => 'flex-end', 5 ], 6 'selectors' => [ 7 '{{WRAPPER}} .elementor-price-table__currency' => 'align-self: {{VALUE}}', 8 ],
Og til og med med hele sett av deklarasjoner, én nøkkel → flere CSS-egenskaper:
1 'selectors_dictionary' => [ 2 'left' => 'right: auto; left: 0', 3 'right' => 'left: auto; right: 0', 4 ], 5 'selectors' => [ 6 '{{WRAPPER}}.elementor-wc-products ul.products li.product span.onsale' => '{{VALUE}}', 7 ],
CSS-variabler, calc() og skjulte kontroller, puslespillet legges
Den virkelige kraften i selektorer avsløres i kombinasjon. Én kontroll setter en CSS-variabel, en annen refererer til den, en tredje aktiverer/deaktiverer en hel blokk med regler gjennom en betingelse.
Glidebryteren for Skala% skriver en variabel:
1 'selectors' => [ 2 '{{WRAPPER}} .sde' => '--sde-scale-percentage: {{SIZE}};', 3 ],
Veksleren "Skala beskåret" bruker denne variabelen to steder, både for transform og for å sende den videre til Gap-kontrollen:
1 'selectors' => [ 2 '{{WRAPPER}} .sde' => 3 'transform: scale(var(--sde-scale-percentage)) scale(0.01); 4 --sde-scale-pct-for-gap: var(--sde-scale-percentage);', 5 ],
Skjult kontroll med betingelse, samme transform men med en annen selektor (for ubeskåret tilstand):
1 'condition' => [ 2 'scale_the_cropped!' => 'cropped', 3 ], 4 'selectors' => [ 5 '{{WRAPPER}} .sde svg' => 6 'transform: scale(var(--sde-scale-percentage)) scale(0.01);', 7 ],
Og Gap-kontrollen bruker den videresendte variabelen med fallback:
1 'selectors' => [ 2 '{{WRAPPER}} .sde' => 3 'padding: calc({{SIZE}}{{UNIT}} / (var(--sde-scale-pct-for-gap, 100) / 100)) 0;', 4 ],
Det som skjer her: Gap kompenserer for skalering. Hvis et element krympes til det halve, multipliseres gapet med 2 for å visuelt forbli det samme. Uten krymping (variabel ikke satt) slår fallback-verdien 100 inn → divisjon med 1 → gapet endres ikke. Ren CSS-matematikk, uten en eneste linje JS.
Transform-stabling, løsning for Edge
Konstruksjonen scale(X) scale(0.01) fortjener spesiell omtale. Hvorfor ikke scale(calc(var(--sde-scale-percentage) / 100))? Fordi Edge ikke støtter calc() inne i transform. I det hele tatt.
Løsning: stabling. Nettlesere bruker transform-funksjoner sekvensielt, én etter én. Derfor:
1 transform: scale(var(--sde-scale-percentage)) scale(0.01);
Matematisk ekvivalent med scale(var(--sde-scale-percentage) * 0.01), med andre ord divisjon med 100. Brukeren får en velkjent 0-100-glidebryter, mens verdien under panseret gjøres om til en koeffisient på 0-1.
Det samme prinsippet gjelder for andre transformasjoner: roter, translate, skew, og fungerer i alle moderne nettlesere, inkludert Edge.
⁉️🤔 Ofte stilte spørsmål
Hva havner egentlig i den genererte CSS-filen?
Elementor samler alle selektorer fra registrerte widget-kontroller, setter inn gjeldende verdier fra brukerinnstillingene og skriver resultatet til
/wp-content/uploads/elementor/css/post-XXXX.css. Dette er ikke innebygde stiler og ikke dynamisk CSS i sanntid: det er en statisk fil som bufres av nettleseren og lever til neste innstillingsendring i editoren. Selve plassholderne{{VALUE}}{{SIZE}}og andre er ikke en del av WordPress eller Blade-malmotoren: Elementor gjør en vanligstr_replaceunder CSS-generering, itererer gjennom alle selektor-deklarasjonspar og erstatter tokens med faktiske kontrollverdier.
Hvordan feilsøker jeg selektorer hvis CSS ikke slår inn?
Åpne innleggets genererte CSS-fil (banen er synlig i sidekilden) og sjekk at regelen er der. Hvis regelen mangler, se etter en skrivefeil i kontroll-ID-en eller en syntaksfeil i
selectors-arrayet. Hvis regelen er der, men ikke virker, sjekk selektorspesifisitet:{{WRAPPER}}gir høy prioritet, men nestede temaer kan overstyre gjennom!important. AktiverWP_DEBUGog følg med på PHP-loggen: Elementor hopper lydløst over feilaktige arrays uten å vise feil på skjermen. Bruk{{WRAPPER}}ALLTID, unntatt ved bevisst målretting mot body eller html.
Hvordan skiller selektorer seg fra tilpasset CSS i widget-innstillinger?
Tilpasset CSS (Avansert-fanen) skrives manuelt av brukeren, dette er statiske regler som ikke reagerer på innstillingsendringer. Selektorer kobler kontroller dynamisk med CSS: dra i slideren,
widthendres, bytt Justering,marginbygges om. Brukeren ser ikke denne mekanismen, de får bare en live forhåndsvisning. For utvikleren er hovedgevinsten fraværet av_content_template()-metoden: uten selektorer måtte du skrevet JS-forhåndsvisning for hver enkelt kontroll.
Trenger jeg selectors_dictionary hvis jeg allerede bruker selectors?
Ja, for et kvalitativt sprang i kode-ryddighet. Uten en ordbok behandler du kontrollverdien implisitt, via merkelige CSS-egenskaper som den ikke-eksisterende
margin-center, som nettleseren ignorerer. Med en ordbok spesifiserer du eksplisitt: «hvis verdien er left, sett inn margin-right: auto, hvis center, margin: 0 auto». Kode blir selvdokumenterende, og viktigst av alt,{{VALUE}}drar ikke lenger med seg den opprinnelige kontrollverdien inn i andre deklarasjoner i samme array.
Kan jeg kombinere selectors med _content_template() i én widget?
Teknisk sett ja, men i praksis er dette et signal om å revurdere arkitekturen. Hvis selectors er nok for de fleste kontroller, men et par felter krever JS-rendring, trekk ut JS-logikken i en egen metode og kall den presist. Fullstendig avvisning av selectors til fordel for
_content_template()betyr at du skriver en JS-duplikat av all PHP-kontrollogikk, og vedlikehold av en slik widget blir raskt et problem.
Er det verdt å mestre selektorer i 2026
Elementor fortsetter å utvikle atomisk infrastruktur, Variables Manager, Grid- og Flexbox-containere, globale stiler. Men grunnmekanikken i widgets har ikke endret seg siden versjon fire: selectors og selectors_dictionary forblir den primære måten å koble en kontroll med live forhåndsvisning.
Ved å mestre denne teknikken eliminerer du en god halvpart av all JS-logikk i en typisk widget. I stedet for handlere for hvert felt, ett selectors-array per kontroll. I stedet for kompleks posisjonering i forhåndsvisning, en kombinasjon av CSS-variabler med calc() og et par skjulte kontroller. SVG Divider for Elementor-pluginen er et levende eksempel: mer enn halvparten av kontrollene styres utelukkende gjennom selektorer, uten et eneste _content_template()-kall.
Hovedregelen er ikke overkompliser. Hvis du tar deg selv i å skrive en fjerde nestet calc() med tre variabler, stopp. Kanskje er det enklere å legge til en skjult mellomkontroll eller dele logikken i to separate felter. Og Elementors kildekode er den beste læreboken: add_control_rules()-metoden i core/files/css/base.php viser hvordan selektorer behandles internt.



