Cum să dezvoltați un editor de text pentru web
Publicat: 2022-03-10Lucrez pentru Readymag, care face un instrument de design bazat pe browser, care îi ajută pe oameni să creeze site-uri web, portofolii și tot felul de publicații online, fără codare. Multe widget-uri sunt disponibile în instrumentul nostru, iar widget-ul text este unul dintre cele mai utilizate pe scară largă.
Widgetul text este un câmp de introducere a textului în care utilizatorul poate stila text folosind o serie de controale din editor. Fiecare control aplică o proprietate CSS textului. Din partea utilizatorului, arată ca un câmp obișnuit pentru introducerea textului, dar în spatele aparentei sale simplități se ascund un număr mare de procese complexe.
În acest articol, voi explica provocările cu care s-a confruntat compania mea și soluțiile pe care le-am folosit pentru a crea un widget text în aplicația noastră. De asemenea, voi descoperi cum l-am implementat și ce am învățat pe parcurs - și cum funcționează scrierea pe web în general.
Editarea textului pe web
Există mai multe modalități de implementare a câmpurilor de introducere a textului pe web. Am putea folosi un câmp de text simplu, sau un element textarea
cu mai multe linii, sau atributul contenteditable
pentru a face o intrare editabilă, sau document.designMode = on
. In ce fel sunt ei diferiti?
textarea
de input
și zona de text sunt ideale pentru adăugarea de text la o pagină, dar nu oferă o experiență bogată de formatare a textului. Pentru aceasta, putem folosi atributul contenteditable
pentru a face aproape orice element editabil și pentru a permite utilizarea stilurilor de text.
Dacă trebuie să editați întreaga pagină simultan, puteți utiliza document.designMode
. Acest mod permite editarea oricărui element dintr-un document dat, chiar și un iframe
.
Am optat pentru atributul contenteditable
, care include toate capabilitățile necesare de editare a textului. Cu acest atribut, orice text de pe pagină devine editabil, ceea ce este foarte important dacă dorim să le permitem oamenilor să stileze textul cu CSS . De exemplu, utilizatorii pot stila direct secțiunile selectate sau întregul text.
Stiluri de text și proprietăți de font
Permitem utilizatorilor să stileze textul în orice mod doresc, oferind acces la toate opțiunile pe care CSS le oferă imediat. Pe lângă proprietățile binecunoscute, cum ar fi fontul, stilul, culoarea și decorul, oferim utilizatorilor posibilitatea de a utiliza funcțiile de font OpenType, cum ar fi ligaturi, seturi stilistice, fracții și așa mai departe. Aceste caracteristici funcționează prin proprietatea CSS font-feature-settings
, care permite utilizatorilor să personalizeze stilurile de text.
Notă : vă recomand cu căldură să citiți articolul excelent al lui Sparanoid care prezintă toate caracteristicile OpenType.
Tipografia modernă a făcut un mare pas înainte, permițând utilizarea fonturilor variabile pe web prin proprietatea font-variation-settings
.
Fiecare font variabil are proprietăți variabile ale căror valori le puteți modifica. De exemplu, într-un font standard, puteți modifica greutatea fontului folosind valori strict specificate ( 400
, 500
, 600
și așa mai departe), în timp ce într-un font variabil, puteți utiliza orice valoare din intervalul disponibil, oferind posibilități mai extinse pentru stilul textului.
.style-1 { font-weight: 600; } .style-2 { font-variation-settings: "wght" 777; }
Mai jos puteți vedea un exemplu despre cum arată lucrul cu un font variabil într-un widget text.
Pe lângă valorile înregistrate ( wght
, wdth
, slnt
, etc.), producătorii de fonturi își pot crea și propriile caracteristici unice de font (ca în exemplul de mai sus). Pentru a oferi utilizatorilor noștri posibilitatea de a folosi toate caracteristicile posibile ale fonturilor, avem nevoie mai întâi de aceste informații.
Toate caracteristicile pe care doriți să le utilizați ar trebui să fie definite în fișierul cu font. Să ne uităm la specificațiile sale. Fiecare font poate fi reprezentat sub formă de tabele, oferind toate informațiile diferite folosite la redarea caracterelor sale.
Folosim două tabele pentru a colecta aceste informații despre fonturi:
- Tabel de înlocuire a glifelor
Tabelul de substituire a glifurilor (GSUB) conține o listă de date de redare a glifurilor. ObiectulGSUB.featureList
este o enumerare a caracteristicilor fontului și proprietățile acestora. Puteți vizualiza un exemplu de date în tabelul de pe GitHub. În acest tabel, câmpul detag
este cel mai interesant. Acesta este numele caracteristicii fontului și indică faptul că această caracteristică este disponibilă cu acest font. Putem folosi în siguranțătag
în proprietateafont-feature-settings
. - Tabelul cu variații de font
Tabelul cu variații de font (fvar) este o reprezentare a proprietăților variabilelor asociate unui font. Un exemplu de tabel este disponibil și pe GitHub. Fiecare obiect este o proprietate de font, cu o descriere a valorilor posibile (min
,max
, implicit) și un nume localizat (dacă există). Folosim aceste valori cu proprietateafont-variation-settings
.
Cu ajutorul acestor două tabele, putem acoperi toate cerințele noastre: folosind proprietăți variabile ale fontului și diverse caracteristici ale fontului. Datele rezultate sunt afișate în comenzile text-widget din editor, unde utilizatorii pot stila textul fără a utiliza niciun cod.
Utilizarea tastaturii
Introducerea textului este unul dintre cele mai importante aspecte ale experienței utilizatorului cu widget-uri de text. Pe lângă activarea comenzilor rapide pentru lucrul cu text, a trebuit să facem față unor provocări neobișnuite. Navigarea textului cu tastele săgeți a fost cu siguranță una dintre ele.
În timp ce utilizatorul editează, widgetul de text afișează și caractere ascunse, cum ar fi spații neîntrerupte și întreruperi de linie. Sunt implementate ca pictograme SVG inserate în text, ceea ce ridică o problemă: dacă folosim contenteditable
, atunci aceste pictograme împiedică utilizatorii să-și mute cursorul cu tastele săgeți.
Soluția este destul de simplă: utilizați un span
și pseudo-elementul :before
. În acest fel, browserul percepe pictograma ca fiind text, iar tastele săgeți funcționează excelent.
span:before { content: ""; height: 1em; position: relative; background-repeat: no-repeat; background-image: url("data:image/svg+xml,..."); background-position: center bottom; background-size: 1em; }
Comenzi rapide
Există două comenzi rapide de la tastatură pentru lipirea textului într-un widget text.
Cmd / Ctrl + V lipește textul din clipboard și păstrează toate stilurile pe care le avea în documentul original. Dacă textul a fost copiat dintr-o aplicație precum Pages, Notes, Word sau Google Docs, atunci clipboard-ul dvs. va conține informații HTML, nu doar text simplu. Acest HTML poate fi parsat și lipit păstrând stilurile originale.
Puteți obține datele HTML după cum urmează:
// https://www.w3.org/TR/clipboard-apis/#reading-from-clipboard document.addEventListener('paste', (e) => { const text = e.clipboardData.getData('text/plain'); const html = e.clipboardData.getData('text/html'); handlePaste(); });
În plus, avem comanda rapidă Cmd + Shift + V. Când inserați text folosind această combinație de tastatură, browserul va lăsa datele simple în încărcarea utilă, astfel încât stilul este controlat de destinația de lipire. Aceste comenzi rapide există în browser în mod implicit, dar trebuie să vă amintiți să le implementați în proiectul dvs.
Selectarea textului și focalizarea
Selectarea textului îi ajută pe utilizatori să vadă ce fragment de text este editat în prezent. Să încercăm un exemplu simplu: un câmp de introducere cu un buton pentru a controla caracterul îndrăzneț al textului.
În acest exemplu, putem selecta o bucată de text și apăsați butonul Bold
, iar selecția din text va rămâne ulterior. Dar dacă exemplul nostru este mai complicat? Să presupunem că adăugăm un câmp de intrare la selectorul de dimensiune a textului. În acest caz, focalizarea se va deplasa către noua intrare.
Există două opțiuni pentru a rezolva această problemă :
- După fiecare eveniment de intrare, forțăm focalizarea să se mute înapoi la blocul de text. În acest caz, selecția va începe să clipească după un anumit număr de evenimente de intrare - nu vrem asta.
- Putem adăuga blocul de text la un
iframe
. După cum probabil știți, uniframe
are propriul obiectwindow
globală. Deci, atâta timp cât selecția este în cadruliframe
, aceasta va persista chiar dacă focalizarea în exterior este mutată.
Am ajuns să avem un widget text iframe
-wrapped. Deci, atâta timp cât selecția este în cadrul iframe
, aceasta va persista chiar dacă focalizarea în exterior este mutată. Aruncă o privire la captura de ecran de mai jos. Avem două selecții pe pagină: fragmentul selectat în widget-ul text și valoarea selectată a dimensiunii textului în control.
Performanță în timpul introducerii textului
Este importantă capacitatea de răspuns a interfeței dvs. de editare a textului. Monitorizați îndeaproape valoarea cadrelor pe secundă (FPS), mai ales când vine vorba de sarcini precum editarea textului la o viteză mare sau schimbarea dimensiunii fontului.
Readymag are două ferestre de vizualizare: desktop și mobil . Stilurile de text pot apărea diferite în fiecare. În timp ce textul este introdus, editorul va efectua diverse calcule pentru a sincroniza datele între ferestrele de vizualizare. Se obține o capacitate de răspuns ridicată prin utilizarea API-ului browser: requestAnimationFrame
și requestIdleCallback
:
-
requestAnimationFrame
este apelat de fiecare dată când ecranul este reîmprospătat; -
requestIdleCallback
este apelat numai când browserul este inactiv.
Aceasta este o modalitate excelentă de a efectua operațiuni obositoare fără a bloca firul principal.
Accesibilitate
Activarea accesibilității este una dintre cele mai importante practici în dezvoltarea web în prezent. Dacă site-ul dvs. este proiectat având în vedere accesibilitatea, acesta va oferi mai multor persoane acces la produsul dvs. . Acest lucru înseamnă găzduirea nu numai a persoanelor cu dizabilități, ci și a utilizatorilor pe diferite platforme: dispozitive desktop și tactile, cititoare de ecran, dispozitive auditive și așa mai departe. Pentru a înțelege cât de importantă poate fi accesibilitatea proiectelor, vă recomand să consultați statisticile recente de accesibilitate.
Pentru a începe să încorporați practicile de accesibilitate web, verificați mai întâi Ghidurile de accesibilitate a conținutului web (WCAG), cea mai cuprinzătoare resursă pe acest subiect. Și atâta timp cât Readymag este un instrument de publicare, pe lângă WCAG, trebuie să respectăm și Ghidurile de accesibilitate pentru instrumentele de creație (ATAG).
Echipa noastră se află în prezent în etapa de integrare a accesibilității în editor. În articolele ulterioare, vom împărtăși mai multe despre călătoria noastră către integrarea completă a accesibilității la Readymag. De asemenea, puteți verifica orice lucrare realizată cu Readymag utilizând lista noastră de verificare a accesibilității.
Cele mai bune practici
În cele din urmă, iată câteva sfaturi pentru a vă ajuta să dezvoltați un editor de text pe web:
- Gândiți-vă bine la aspect.
Identificați dinainte ce capabilități aveți nevoie și cum veți lucra cu elementele din editorul de text. - Configurați testarea vizuală.
Când lucrați cu text, nu vă puteți baza în întregime pe rezultatul testului instantaneu. Este posibil să obțineți rezultatul corect în test, așteptând CSS-ul dat pentru bloc, dar uneori rezultatul ar putea să nu fie cel așteptat. - Testați-vă munca în diferite browsere.
În timp ce majoritatea browserelor acceptă noile funcții online destul de bine, există adesea probleme cu afișarea acelorași stiluri în browsere diferite. - Utilizați steaguri de caracteristici pentru dezvoltarea mai sigură a funcțiilor noi.
- Măsurați FPS în browser când introduceți text.
Nu faceți sarcini care necesită mult CPU într-un singur fir. - Nu vă fie frică să experimentați .
- Nu în ultimul rând, încercați Text Widget în Readymag.
Cateva Linkuri Utile
- „Demo completă CSS pentru funcțiile OpenType”, Sparanoid
- „Introducere în fonturile variabile de pe web”, web.dev
- „Tipografie minunată”, Joel Galeran
- „Fonturi variabile”, Nick Sherman
- Fontkit
- OpenType.js