FEATUREDFrontend

Budúcnosť CSS: :drag a možno aj ::drag-image

Nová CSS pseudo-trieda :drag by mohla umožniť vývojárom aplikovať štýly na ťahané elementy bez JavaScriptu. Pozrite si, ako by mohla fungovať a prečo by sme mohli potrebovať aj ::drag-image.

GUY Team
6 min čítania
Budúcnosť CSS: :drag a možno aj ::drag-image

Viem, na čo myslíte. Ďalšia CSS pseudo-trieda… Ale myslím, že tento návrh je celkom zaujímavý.

Začiatkom tohto roka bol navrhnutý nový pseudo-trieda, :drag, ktorá by umožnila vývojárom aplikovať štýly, keď používateľ aktívne ťahá element. V súčasnosti CSS nemá mechanizmus na detekciu interakcií ťahania, čo sťažuje správu UI správania, ktoré závisí od tejto akcie bez spoliehania sa na JavaScript.

Žiadny JavaScript! Páči sa mi myšlienka mať pseudo-triedu venovanú tejto funkcii namiesto toho, aby sme išli cestou classList.toggle().

Ale ako by to fungovalo?

Aby ste to pochopili, najprv musíte poznať HTML Drag and Drop API. Niektoré z udalostí, ktoré spúšťa zahŕňajú: 

  • drag (spúšťa sa každých niekoľko milisekúnd, keď je element ťahaný), 
  • dragstart (udalosť sa spúšťa pri začiatku ťahania), a 
  • dragend (udalosť sa spúšťa, keď ťahanie elementu skončí).

Pozrime sa rýchlo na to, ako tieto udalosti drag-and-drop fungujú v JavaScripte, aby sme pochopili, ako by sa preložili do CSS. Predstavme si, že máme sedem tlačidlových elementov v <div> :

<menu class="menu-bar"> <li><button>Home</button></li> <li><button>Products</button></li> <li><button>Services</button></li> <li><button>About</button></li> <li><button>Contact</button></li> <li><button>Blog</button></li> <li><button>Careers</button></li>
</div>

Celý .menu-bar môžeme urobiť ťahateľným pridaním atribútu:

<menu class="menu-bar" draggable="true"> <!-- etc. -->
</div>

Pre náš CSS jednoducho dáme triede is-dragging nejaké štýlovanie, ktoré bude aplikované len vtedy, keď je element ťahaný alebo presunutý:

V CSS môžeme nastaviť triedu .is-dragging, ktorú nastavíme na element pomocou JavaScriptu, keď je v procese ťahania. Toto sú štýly, ktoré aplikujeme na element, keď sa to deje:

.is-dragging { box-shadow: 0 4px 12px rgba(0 0 0 / 0.15); background: #fff; transform: translate(1px); opacity: 0.2; scale: 1.2;
}

A tu je JavaScript na prepínanie medzi začiatkom ťahania myšou a jeho koncom. Počúva udalosť dragstart a pridáva triedu .is-dragging k .menu-bar. A keď pustíme .menu-bar, zábava s ťahaním končí a trieda .is-dragging je odstránená:

menuBar.addEventListener("dragstart", (event) => { event.target.classList.add("is-dragging");
}); menuBar.addEventListener("dragend", (event) => { event.target.classList.remove("is-dragging");
});

Náš výstup by vyzeral nejako takto. Potiahnutím prvku dropdown uvidíte:

Celkem dobré! Keď je panel ponuky ťahaný, zachováva si obraz seba samého v pôvodnej pozícii, ktorý je naštýlovaný triedou .is-dragging. A hoci sme to dokázali zvládnuť pomocou JavaScriptu, ako skvelé by bolo mať navrhovanú pseudo-triedu :drag, ktorá by abstrahovala všetky tie skriptové veci:

.menu-bar:drag { cursor: grabbing; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); background: #fff; transform: translate(1px); opacity: 0.2; scale: 1.2;
}

+1 za výkon! +1 za jednu závislosť menej! +1 za udržiavateľnosť!

Čo tak náhľadový obrázok?

Vedeli ste, že môžeme štýlovať samotný element, keď je ťahaný po obrazovke? Nazýva sa to náhľadový obrázok a môžeme ho nahradiť <div>, do ktorého môžeme pridať vlastné štýlovanie.

Horizontálna ponuka tlačidiel v jednom riadku ťahaná kurzorom myši. Vidíme ponuku v jej pôvodnej pozícii a jej aktuálnej ťahanej pozícii.
Prehliadač zobrazuje “náhľad” elementu počas jeho ťahania.

Ide len o trochu viac JavaScriptu pomocou funkcie dataTransfer.setDragImage() :

const dragPreview = document.createElement("div"); dragPreview.textContent = "📦 Dragging...";
dragPreview.style.cssText = ` background: #fff6d6; border: 2px dashed orange; border-radius: 0.5rem; color: #333; padding: 0.5rem 1rem;
`; document.body.appendChild(dragPreview); // Toto nahradí predvolený náhľad ťahania
event.dataTransfer.setDragImage(dragPreview, 0, 0); // Odstráňte po spustení udalosti
setTimeout(() => dragPreview.remove(), 0);

Tu sa odvážim a navrhnem ďalší CSS pseudo špeciálne pre ::drag-image. Predstavte si, že by ste mohli obísť všetok ten JavaScript a priamo napísať štýly v CSS:

::drag-image { content: "📦 Dragging..."; padding: 0.5rem 1rem; background: #fff6d6; color: #333; border: 2px dashed orange; border-radius: 0.5rem;
}

Predpokladám, že by to mohla byť pseudo-trieda, ale zdá sa, že pseudo-element dáva väčší zmysel, pretože hovoríme o konkrétnom objekte a nie o stave.

Otvoril som issue pre to — dajte mu palec hore, ak by sa vám zišiel pseudo-element ::drag-image ako tento. CSSWG už má naplánovanú diskusiu o návrhu :drag. Ak sa to dostane do špecifikácií, potom by som presadzoval aj pseudo-element.

Myšlienky?

Áno alebo nie pre pseudo prvky súvisiace s ťahaním? Siahli by ste po niečom takom, alebo máte pocit, že to príliš šliape na päty JavaScriptu?

cssjavascriptwebdizajnfrontenddrag-and-drop

Nenechajte si ujsť žiadny článok

Prihláste sa na odber newslettera a dostávajte najnovšie tipy a trendy priamo do emailu.