Olen sitten viimeisimmän artikkelin törmännyt erinäisiin tilanteisiin, missä CSS:n (cascading style sheets) sallimat muutokset eivät riitä. Usein näissä tilanteissa riittää käyttää lisätunnisteita, jotta halutut elementit saadaan erotettua muusta sisällöstä. Toisin sanoen käyttäjien tulee tällöin käyttää elementtiluokkia.
Käyn tässä artikkelissa läpi joitakin näistä rajoitteista. Lisäksi esittelen muutamia elementtiluokkien käytettävyyteen liittyviä huomioita. Yksi yksinkertainen huomio esimerkiksi auttaa parantamaan mitä vain DoX CMS:n käyttöön tehtyä tyylitiedostoja.
Milloin CSS Ei Riitä?
CSS perustuu kahteen tekijään: kohdistajiin ja sääntöihin.
Jos siis ei ole mahdollista muotoilla kohdistajaa asianmukaisella tavalla haluttujen sääntöjen käyttöpaikan rajaamiseksi, täytyy kohdistamisen tukena käyttää lisätunnisteita. DoX CMS:ssä tämä tarkoittaa useimmiten elementtiluokkien käyttämistä.
Jos puolestaan haluttujen muutoksien tekemiseen ei ole olemassa soveltuvaa sääntöä, ei tyylitiedostoilla voida toteuttaa kyseistä muutosta. CSS ei esimerkiksi salli poistaa kuin kokonaisia elementtejä. Jos valmiiksi määritetyistä sisällöistä halutaan tietyissä tilanteissa pyyhkiä esimerkiksi ylimääräisiä pisteitä, täytyy nämä sisällöt muotoilla tavalla, missä tällaisilla yksityiskohdilla on omat, tunnisteilla merkityt elementtinsä.
Listaan alla erinäisiä tähän mennessä vastaan tulleita tilanteita, missä ainakin toinen näistä ehdoista täyttyy. Lisäksi käyn läpi muita tyylitiedostojen käytettävyyteen liittyviä huomioita.
Kuvien Asettelu Taulukoissa
CSS ei (toistaiseksi) salli kohdistajia, joita käytetään ylemmän tason elementtiin sen sisältämien alemman tason elementtien perusteella. Tarkkaan ottaen tähän käytettävä ’:has()’-kohdistaja on osa CSS:n jatkokehitystä ja kirjoitushetkellä ainoa sitä tukeva selain on Safari.
Tämä rajoite on ongelma silloin, kun jokin asettelu haluttaisiin kohdistaa esimerkiksi taulukon soluihin, jotka sisältävät (vain) kuvia.
DoX CMS:n soveltamassa LW-DITA-formaatissa kaikkien taulukoiden solujen sisällä on oletusarvoisesti p-elementti ja kuvat täytyy upottaa sellaisen sisään. Tästä syystä on mahdotonta esimerkiksi kohdistaa valintaa suoraan taulukon solun sisäiseen kuvaan, koska sekä tekstiä että kuvia sisältävät solut sisältävät p-elementin niitä varten. CSS ei myöskään salli kohdentaa erikseen p-elementtejä, joiden ainoa välitön sisältö on kuva.
Kuviin taulukoiden sisällä on mahdollista kohdentaa muotoilua kuten enimmäiskoon määreet. Niiden asettelu kuten vaakasuuntainen sijoittaminen joko oikealle tai vasemmalle on kuitenkin sidonnaista ne sisältävien p-elementtien asetteluun. Koska kohdistajaa ei voi asettaa p-elementtiin sen mukaisesti, sisältääkö se kuvan tai ainoastaan kuvan vai ei, ei pelkästään kuvien asettumiseen voi vaikuttaa ilman lisätunnisteita.
Tarkkaan ottaen sain tässä tapauksessa toteutettua asiakkaan pyynnön, että ’taulukoissa vasemmanpuoleisen sarakkeen kuvat tasataan vasemmalle ja oikeanpuoleisen sarakkeen kuvat oikealle’ ilman elementtiluokkien lisäämistä. Käyttämäni toteutustapa on kuitenkin sen verran tökerö, että se on itsessään hyvä esimerkki siitä, kuinka on parempi hyväksyä CSS:n rajat ja käyttää elementtiluokkia. Tämä ratkaisu myös toimii vain sillä ehdolla, että kuvia ei lisätä taulukoiden sisällä kuin itsenäisinä sisältöinä.
tr > td:first-child > p > img {
float: left;
}
tr > td:first-child > p {
clear: left;
}
tr > td:last-child > p > img {
float: right;
}
tr > td:last-child > p {
clear: right;
}
tr > td:first-child > p::before, tr > td:last-child > p::before {
content: ".";
color: rgba(255,255,255,0.0);
display: inline-block;
width: 0px;
}
Kyseinen koodi siirtää taulukon solujen p-elementtien kuvat ulos kyseisistä p-elementeistä niiden vasemmalle puolelle ensimmäisessä sarakkeessa ja oikealle puolelle viimeisessä sarakkeessa. Kyseisiin p-elementteihin on sitten lisätty sääntö, joka asettelee niiden sisällön tasoon tällä tavoin siirretyn kuvan yläreunan kanssa. Muussa tapauksessa kuvien alareuna olisi tasossa niiden rivin alaosan kanssa. Tämä sääntö kuitenkin toimii vain, kun kyseissä p-elementeissä on jotakin muuta sisältöä. Tästä syystä kaikkiin ensimmäisen ja viimeisen sarakkeen p-elementteihin on lisätty näkymätön piste, jonka leveys on nolla. Se on kuvan pystysuunnassa tasaamiseen vaadittua sisältöä, joka ei vaikuta tekstillisiin soluihin, vaikka se tulee myös niihin.
Vaihtoehtoisesti olisi ollut mahdollista lisätä järjestelmään elementtiluokat niitä taulukoita varten, joissa joko ensimmäinen sarake tai viimeinen sarake on tarkoitettu ainoastaan kuvien käyttöön. Kun kyseinen elementtiluokka on käytössä koko taulukolla, voi säännöt kohdistaa sillä merkittyjen taulukoiden ensimmäisiin tai viimeisiin sarakkeisiin. Tällöin on myös mahdollista käyttää kuvia muun sisällön ohessa.
Listojen Jatkuva Numerointi
Toisin kuin HTML, jossa tätä varten on erillinen start-ominaisuus, DITA ei lähtökohtaisesti salli aloittaa numeroitua listaa eri numerolla. Jos siis tarvitaan listoja, jotka jatkuvat halki muiden elementtien rajojen kuten taulukon solusta toiseen, täytyy tämä tehdä tyylitiedoston avulla.
Tähän tarkoitukseen ei kuitenkaan löydy suoraa komentoa myöskään CSS:n osalta. Sen sijaan täytyy käyttää komentoja, joilla aloitetaan erillinen laskuri ja korvataan normaalit listan numerot kyseisen laskurin arvoilla. Jos tätä laskuria ei palauteta alkuun jokaisen numeroidun listan alussa, siihen perustuva numerointi jatkuu yhtenäisenä seuraavaan aloituspisteeseen saakka.
Kohdistajien osalta tämä myös tarkoittaa, että aloituspiste täytyy määrittää kyseiset listat sisältävien elementtien kautta. Alla esitetyssä esimerkissä näin on tehty taulukoiden osalta. Tämä vaatii elementtiluokkien käyttämistä, ellei kyseisenlaista toimintaa haluta käyttää oletusarvoisena toimintatapana listojen numeroinnin osalta. Tällainen toiminta on mahdollista määrittää ja tarvittaessa tarjoamme asiakkaillemme lisätietoja aiheesta tukemme kautta. Alla on kuitenkin esitetty vain merkittyihin taulukoihin soveltuva keino. Kiitos siitä kuuluu ensisijaisesti aiemmalle järjestelmäkehittäjällemme Oskari Torikalle, vaikka olen muokannut hänen versionsa käyttämiä kohdistajia hieman tämän toiminnallisuuden rajaamiseksi ensimmäisen tason numeroituihin listoihin. Lisäksi lisäsin erillisen numeroinnin alusta aloittamisen luokan puhtaasti käyttökokemuksen helpottamiseksi. Saman elementtiluokan käyttäminen sekä ylemmän tason elementtiin että sen sisällä olevaan alemman tason elementtiin numeroinnin alusta aloittamiseksi voisi helposti osoittautua epäintuitiiviseksi käytön osalta.
[doxelementclass~="JatkuvaNumerointi"] {
counter-reset: splitcounter;
}
[doxelementclass~="JatkuvaNumerointi"] td > ol > li {
list-style-type: none !important;
}
[doxelementclass~="JatkuvaNumerointi"] p {
display: inline;
}
[doxelementclass~="JatkuvaNumerointi"] td > ol > li:before {
counter-increment: splitcounter;
content: counter(splitcounter) ".";
}
[doxelementclass~="JatkuvaNumerointi"] td > ol > li {
text-indent: -1.3em;
}
[doxelementclass~="JatkuvaNumerointiAlusta"] {
counter-reset: splitcounter;
}
Vaikka toteutus on siis tarkkaan ottaen tehtävissä, se käytännössä vaatii elementtiluokkien käyttämistä. Lisäksi on välttämätöntä, että kyseinen elementtiluokka annetaan korkeamman tason elementille, johon kaikki keskenään jatkuvalla numeroinnilla varustetut listat tulee sisällyttää. Tätä toiminnallisuutta ei voi kytkeä suoraan itse listaelementteihin, koska siihen soveltuvia sääntöjä ei ole.
Otsikoiden Numerotunnisteen Välitys Sisällysluettelossa
Varsinaiset sisällön otsikot on mahdollista erottaa vapaasti niiden numerotunnisteista, koska käyttämämme dokumenttipohja sisältää tähän vaadittavat sisällön tunnisteet. Valitettavasti tämä ei pidä paikkaansa sisällysluettelon osalta. Siellä numerotunniste ja otsikko on erotettu toisistaan pelkällä välilyönnillä ja ne ovat molemmat osa samaa elementtiä.
Olemme suunnitelleet dokumenttipohjan päivitystä, joka lisäisi erilliset tunnisteelliset elementit mahdollisimman moneen muutoin järjestelmän automaattisesti hallinnoimaan sijaintiin. Tätä varten löytyy hahmotelma muutoksista nykyiseen dokumenttipohjaan. Koska erilainen dokumenttipohja tosin vaatii erillisen tyylitiedoston, jokaisen julkaisun osalta on sen käyttöönoton jälkeen mahdollista päättää, käyttääkö kyseinen julkaisu uutta vai vanhaa dokumenttipohjaa.
Tämä korostaa itse sisällön muotoiluun liittyviä velvoitteita suhteessa tyylitiedostoihin. Automaattisesti lisättyjen muotoilujen osalta meillä on velvollisuus varmistaa mahdollisimman laaja muokattavuus tyylitiedoston kautta. Myös käyttäjien on kuitenkin syytä huomioida tyylitiedostojen rajoitteet sisällön asettelun osalta. Esimerkiksi kuvia ei saa asetettua yhtä vapaasti kuin MS Word sallisi, koska sisältö kasataan vaihtelevan kokoisista osista eri kielillä eikä samanlaista sivukohtaisen asettumisen tapaa yleensä voi taata. Täten dokumenttien suunnittelussa täytyy yhtälailla huomioida tarve yhteensopivuudelle tyylitiedostojen kanssa esimerkiksi varmistamalla, että kuvien asettelun toteutus on yhteensopiva vaihtelevien sivukohtaisten sijoitteluiden kanssa.
Kasaajakohtaiset Rajoitteet
Täytyy myös huomioida, että tyylitiedostojen soveltaminen ei ole suhde pelkästään raakasisällön ja tyylitiedoston välillä. Tyylitiedoston soveltaminen sisällön asetteluun vaatii tulkitsijaa. Suhde lähtömateriaalien ja lopputuleman välillä ei ole yksiselitteinen, vaan siihen liittyy erinäisiä toteuttamistapaa koskevia valintoja. Tästä syystä esimerkiksi PDF-tiedostojen kasaamiseen on tarjolla useampia ohjelmia, jotka tukevat erilaisia ratkaisuja ja tuottavat erilaisia lopputulemia.
DoX CMS esimerkiksi sallii käyttäjien valita, käytetäänkö PDF:ien kasaamiseen Essential Objects vai DocRaptor-palvelua.
Nämä kaksi kasaajaa esimerkiksi käyttävät täysin erilaisia ratkaisuja sivutunnisteiden sijoittelemiseen. Tältä osin Essential Objects — varsinkin yhdessä DoX CMS:ään sen kanssa yhteensopivien lisätoimintojen kanssa — käyttää käyttäjien kannalta helpommin hallinnoitavia ja aseteltavia kokonaisuuksia. Toisaalta DocRaptor perustuu PrinceXML-kasaajaan ja täten sallii joustavampaa sivutunnisteiden sijoittelemista, mukaan lukien vaakamarginaalien käyttämisen. Lisäksi se sallii käyttää PrinceXML:n tukemia erityiskomentoja kuten ’leader()’ tai ’running()’, jotka helpottavat esimerkiksi sisällysluetteloiden asettelemista.
Jotkin pyynnöt saattavat olla toteutettavissa vain tietyillä kasaajilla. Siirtymä yhdestä kasaajasta toiseen puolestaan voi vaatia laaja-alaista aiempien tyylitiedostojen (mukaan lukien sivutunnisteiden tiedostojen) uudelleen kirjoittamista.
Elementtiluokat
Yllä on esitetty esimerkki siitä, kuinka elementtiluokilla on mahdollista ylittää muutoin ylitsepääsemättömiä CSS:n rajoitteita. Niiden ensisijainen tehtävä on sallia lisäerotteluita, jotta vain tiettyihin sijainteihin tarkoitetut säännöt saadaan rajattua vain kyseisiin sijainteihin.
Millaisia seikkoja elementtiluokkien käytön osalta on syytä huomioida?
Monta Elementtiluokkaa Samalla Elementillä
Samalle elementille on mahdollista antaa useampi elementtiluokka. Ne ovat kaikki arvoja samalle attribuutille ’doxelementclass’ ja jokainen listataan osana tämän attribuutin arvoa. Tällä tavoin on esimerkiksi mahdollista käyttää yhtäaikaisesti yllä esitetyn kaltaista elementtiluokkaa jatkuvalle listalle ja elementtiluokkaa esimerkiksi taulukon reunuksien piilottamiselle.
Jotta samalle elementille voidaan käyttää useampaa elementtiluokkaa, tämä tulee kuitenkin huomioida myös osana tyylitiedostojen muotoilua. Koska kyseessä on attribuutti, yhtäläisyysmerkki tarkoittaa koko arvon vastaavuuden tarkistamista. Tällä tavoin useamman elementtiluokan omaavan sisällön säännöt täytyisi määrittää erikseen jokaiselle yhdistelmälle.
Tämä lisätyö on kuitenkin helposti vältettävissä.
Kunnia tästä havainnosta kuuluu järjestelmäkehittäjällemme Atte Sairaselle.
Elementtiluokkien muotoilu tyylitiedostossa tarvitsee vain laittaa muotoon ’[doxelementclass~=”ElementtiLuokanNimi”]’. Merkki ’~’ ennen yhtäläisyysmerkkiä tarkoittaa, että kyseisen kohdistajan soveltaminen vaatii vain nimetyn osuuden mukana kyseisen attribuutin kokonaisarvossa olemista.
Suosittelemme yllä esitettyä muotoilua oletusmuotoiluna elementtiluokille. Näin varmistetaan niiden toimivuus, kun useampi on käytössä samalla elementillä, ja tällä merkintätavalla ei ole mitään haitallisia sivuvaikutuksia. Useimmissa vanhemmissa käyttöympäristöissä elementtiluokkien määreet on tällä hetkellä annettu muodossa ’[doxelementclass=”ElementtiLuokanNimi”]’ ilman ’~’-merkkiä.
Tarvittaessa nämä määreet voi antaa myös muilla tavoin. Jos elementtiluokat esimerkiksi nimetään järjestelmällisesti tavoilla, missä useammalla elementtiluokalla saattaa olla vastaava alku- tai lopputunniste, löytyy kyseisenlaisiin elementtiluokkajoukkoihin omat viittaamiskeinonsa. Lisätietoja aiheesta löytyy täältä.
Sisäkkäisyys ja Elementtiluokat
Elementtiluokkia ei tarvitse käyttää suoraan niihin elementteihin, joiden muotoiluun halutaan vaikuttaa tällä tavoin. Niitä voidaan käyttää korkeamman tason elementteihin ja niihin liittyvät kohdistajat voidaan määrittää suhteessa niihin sisältyviin alemman tason elementteihin.
Tällä tavoin on helppoa välttää asetuksien säätämistä useille peräkkäisille elementeille yksi kerrallaan. Esimerkiksi taulukoissa voi olla tarpeen antaa määreet useille riveille tai kaikille tiettyjen sarakkeiden soluille. Vaikka tällaiset seikat näyttäytyvät koko taulukon asettelun tai tyylittelyn määrityksinä, täytyy määreet antaa itse taulukon sijaan sen osatekijöille. Samaa menettelyä voi käyttää myös esimerkiksi osioelementteihin (section), jos useamman vastaavan elementin halutaan käyttäytyvän samalla tavoin mutta normista poiketen.
Tämä vaatii ainoastaan elementtiluokan sisältävän elementin käyttämistä ylemmän tason elementtinä siihen liittyvissä kohdistajissa. Siihen liittyviä määreitä ei anneta suoraan itse elementtiluokan omaaville elementeille vaan näiden elementtien sisäisille asianmukaisesti määritetyille alemman tason elementeille.
Ylitseajavuus
CSS asettaa voimaan viimeisimmäksi määritetyn saman tarkkuustason kohdistajan säännöt. Tästä syystä tyylitiedostot tulisi järjestää määrittämällä ensin ylemmän tason elementtien säännöt ja sitten poikkeavat alemman tason elementtien säännöt. Tämä hierarkia on mahdollista ohittaa määreellä ’!important’, mutta sen liikakäyttö tekee tyylitiedostosta arvaamattoman siltä osin, mikä osio jää voimaan. Elementtiluokkiin tätä määrettä on kuitenkin syytä käyttää, koska ne on tarkoitettu ylitseajaviksi määreiksi.
Kun elementtiluokille siis annetaan määreet, on hyvä ajatus sijoittaa ne mahdollisimman lähelle tyylitiedoston loppuosaa. Niihin liittyville säännöille on myös syytä käyttää lisämäärettä ’!important’ kuten ’font-size: 8pt !important;’, jotta niille määritetyt säännöt varmuudella jäävät voimaan.
Yhteenveto
Rakenteisen dokumentaation asettelu ja tyylittely on väistämättä riippuvaista tyylitiedostoista, koska tällaiset sisällöt koostetaan niiden sivukohtaisen käsin määrittelemisen sijaan. Tyylitiedostoilla on kuitenkin rajansa siltä osin, mitä niiden avulla voidaan saavuttaa. Esimerkiksi kuvia ei voi asetella sivukohtaisesti ja sivunvaihtojen ympärillä tapahtuva asettelu per sivu täytyy määrittää yleismuotoisina sääntöinä eikä tilannekohtaisesti.
Rajoitteet voivat perustua (1) kohdistajien muotoilun rajoitteisiin, (2) soveltuvien sääntöjen puuttumiseen, (3) sisällön tai sen rakenteen vääränlaiseen muotoiluun tai (4) käytetyn kasaajan rajoituksiin.
Kohdistajien osalta tilanne on pitkälti korjattavissa käyttämällä lisäluokituksia. DoX CMS:ssä tämä tarkoittaa elementtiluokkien käyttämistä.
Kun halutaan käyttää useampaa elementtiluokkaa samalla elementillä, täytyy niiden määritteiden olla muotoa ’[doxelementclass~=”ElementtiLuokanNimi”]’. Merkki ’~’ on syytä lisätä tästä syystä myös olemassaolevien tyylitiedostojen elementtiluokkien määrityksiin.
Elementtiluokkia ei tarvitse aina kohdistaa suoraan niihin elementteihin, joille niihin liittyvät säännöt otetaan käyttöön. Elementtiluokkiin viittaavat kohdistajat voivat asettaa säännöt alemman tason elementeille näin merkittyjen elementtien sisällä.
Koska elementtiluokkien tarkoitus on asettaa käyttöön poikkeussäännöt, kannattaa varmistaa niiden ylitseajavuus. Varmin keino tehdä niin on lisämääreen ’!important’ käyttäminen. Tätä määrettä tulisi mieluiten käyttää ainoastaan elementtiluokkiin, jotta niiden asianmukainen toimiminen voidaan varmistaa. Lisäksi elementtiluokat on syytä asettaa tyylitiedoston loppuosaan, jotta ne sisältävät viimeisen voimaan jäävän säännön kyseisenlaisille elementeille, vaikka ’!important’-määrettä olisi käytetty myös muualla.