zebra-tabel met CSS3's :not

Status
Niet open voor verdere reacties.

That Guy

Meubilair
Lid geworden
28 nov 2006
Berichten
5.010
geachte dames en heren,


Ik was wat aan het stoeien met het verzebra'en van een tabel. Nu dacht ik slim gebruik te maken van het :nth-child:
Code:
tr:nth-child(even)
{
   background-color: #eee;
}
dat werkt uiteraard prima. Nu, ik heb in Javascript een tabel-filter functie geschreven, die bepaalde rows een class invisible geeft.
Code:
.invisible
{
   display: none;
}
Nu, om deze gefilterde tabel weer netjes een zebra-streepje te geven, ging ik CSS' :not() gebruiken:
Code:
tr:not(.invisible):nth-child(even)
{
   background-color: #f3f3f3;
}
echter, dit werkt niet. Ook andersom, dus tr:nth-child(even):not(.invisible) doet 't niet.

Nu de vraag: komt dit omdat mn selector fout is, of omdat het CSS niet wordt 'herberekend' als bepaalde elementen veranderen?



:thumb:

[edit] zie hier voor de :not selector.[/edit]
 
Laatst bewerkt:
Nu de vraag: komt dit omdat m'n selector fout is, of omdat het CSS niet wordt 'herberekend' als bepaalde elementen veranderen?
Heb net even lokaal getest en die combinatie van selectors werkt bij mij prima. Ik denk dat het probleem inderdaad is dat de class wordt toegevoegd op het moment dat de browser de CSS al verwerkt heeft, die heeft geen reden om er nog eens naar te kijken. Mijn kennis van Javascript is niet zo groot maar volgens mij moet het mogelijk zijn om het script te activeren op het moment dat de DOM geladen is maar de CSS nog niet is verwerkt. Een andere oplossing zou zijn om de zebra strepen zelf ook door Javascript te laten tekenen.

Worden die rijen trouwens wel verborgen? Het zou raar zijn als een deel van de CSS wel op die class werd uitgevoerd en een deel niet.
 
Yup, maar een Javascript oplossing had ik al. Maar omdat het zebra'en van de tabel redelijk vaak gebeurt, dacht ik, laat ik eens kijken of het met CSS alleen kan.

Hier is mijn filter-script:[JS]// cc by 3.0, enzovoorts. Werkt (uiteraard -_-) niet in IE.

HTMLTableSectionElement.prototype.filter = function(criteria, caseSensitive)
{
var i, j, cols, rows = this.getElementsByTagName('tr');

for(i=0; i<rows.length; i++)
{
rows.setAttribute('class', 'invisible');
cols = rows.getElementsByTagName('td');

for(j=0; j<cols.length; j++)
{
if(cols[j].firstChild && cols[j].firstChild.nodeType == 3 &&
((caseSensitive === true && cols[j].firstChild.nodeValue.indexOf(criteria) != -1) ||
(caseSensitive != true && cols[j].firstChild.nodeValue.toLowerCase().indexOf(criteria.toLowerCase()) != -1)))
{
rows.removeAttribute('class');
}
}
}
};[/JS]
Worden die rijen trouwens wel verborgen? Het zou raar zijn als een deel van de CSS wel op die class werd uitgevoerd en een deel niet.
Jazeker. Hier is een voorbeeld zonder filter: css3not_halp2.png en hier een met een filter: css3not_halp1.png



:thumb:
 
Laatst bewerkt:
eventjes opnieuw onder de aandacht brengen.

Overgens is een oplossing misschien ook om de CSS opnieuw te 'forceren' elke keer als filter wordt aangroepen. Kan dat op een bepaalde manier?
 
Ahoy That Guy,
Het is hier wel stil aan de overkant, maar denk-denk, knars-knars, experimentje linksom, experimentje rechtsom ... en ik ben er nog niet uit of het nu echt niet kan met css:not, of dat ik erbarmelijk verdwaald blijf raken in de talloze combi-mogelijkheden van selectors en pseudo-selectors in css3... ;)

Waar ik al wel achter ben, is dat het 'forceren' van herhaalde css-toepassing na het gescript niet kan werken, om de eigenlijk doodeenvoudige reden dat je wel {display:none;} op een element kunt loslaten, maar dat dan het element nog steeds (met z'n row-eigenschappen!) in de html staat, en daar gewoon meetelt voor de kleur van de volgende rij.
Maar ik ga later nog wel even door met de multiple choice van css3-selectors.

Wordt vervolgd!
CSShunter
 
Laatst bewerkt:
Hoi csshunter,


Alvast bedankt voor de tijd die je hierin steekt.

De reden dat ik CSS gebruik ipv Javascript is dat ik de filter() zo makkelijk mogelijk wil houden. Met removeChild moet je, als je 'minder filterd' namelijk het element weer terug zetten op de goede plek. Dat is weer een hoop Javascript: onthouden op welke plek het stond, dan nog eens alle elementen die je weghaald opslaan (in een array oid) om later terug te zetten op de opgeslagen plek.



:thumb:
 
De reden dat ik CSS gebruik ...
Daar was ik al bang voor.
Als je eenmalig die overbodige rijen moet verduisteren, is er met js niets aan de hand.
Maar als het een Show-Hide-Show-Hide feestje moet worden *), moet er een bulk extra script aan te pas komen. :rolleyes:

Met vriendelijke groet,
CSShunter
_____________
*) offtopic:

Show-Hide
Move em on (hit em up)
Hit em up (move em up)
Move em on (hit em up)
Show-Hide
Cut em out (ride em in)
Ride em in (cut em out)
Cut em out (ride em in)
Show-Hide!
:)
 
Show / hide the Zebra

Hoi That Guy,
Nou, ik heb er inmiddels nog een (
oneindig.png
- x) aantal pogingen op zitten om het met de css3 (pseudo) selectors te doen, maar dat is me niet gelukt. Ik geef het op: het is niet uit te sluiten dat het wel kan, maar kennelijk heb ik daarvoor te weinig css3-praktijk en/of is mijn brein daar niet geschikt voor. Met al de nth kinderen en > en + regels raak ik al gauw het spoor bijster: ik zie niet voor me wat ik doe. *) :confused:

Niettemin is er wel een simpele css-methode, tenminste als de tabelcellen nooit méér dan één regel hoogte hebben.

Maar, :D, ik kom terug op mijn eerdere uitspraak:
... als het een Show-Hide-Show-Hide feestje moet worden, moet er een bulk extra script aan te pas komen. :rolleyes:
Eerst zat ik onnoemelijk te pielen met het opvragen van de bg-color van een bepaalde rij, om dan alle volgende om-en-om in zebra-design te husselen. Dat opvragen is op zich al niet zo eenvoudig (www.quirksmode.org/dom/getstyles.html), en het husselen is ook prettig gecompliceerd.
Edoch: met een simpele vergeet-me-niet variabele voor elke wel-geshowde rij kan je de volgende de andere kleur geven. En in plaats van het steeds husselen van alleen de rijen erna, zodra er een nieuwe hide wordt gegeven: na elke hide gewoon alle rijen vanaf het begin opnieuw inkleuren. Na terugplaatsen van een rij gebeurt hetzelfde, dus geen centje pijn met allerlei onthoud-array's: niet nodig!
[JS]function zebra(){
var remember = 0;
for (var i=0; i<rows.length; i++){
if (rows.style.display != "none"){
if (remember == 0){rows.style.backgroundColor="#BBE0FF"; remember=1;}
else {rows.style.backgroundColor="#FFE3F7"; remember = 0;}
}
}
}[/JS]
Dat is geen bulk, maar best te overzien. :)
  • Test-test: www.developerscorner.nl/csshunter/tests/show-hide-the-zebra.htm
  • Ter linkerzijde: de één-rij-ige css oplossing.
  • Ter rechterzijde: de javascript zebra() functie in actie. Door 'm met een onload meteen aan te roepen is zelfs geen css3 nodig (hier met een CC toegepast voor IE: IE6
    smiley-15x13.gif
    , IE7 en IE8 compatible).
Met vriendelijke groet,
CSShunter
_________
*) Voor mij hadden ze bij w3c liever een javascript-analoog css3-script ontwikkeld...
 
Hoi csshunter,


Achtergrond-plaatje gebruiken in plaats van stijl was me nog niet eens binnengevallen: maar wel een goed idee! Helemaal omdat alle rijen inderdaad maar 1 hoog zijn (overflow hidden).

Echter, ik weet niet hoe het zit met 'inzoomen' (bv: text groter maken in IE, of ctrl+muiswiel in andere browsers). Als it de achtergrond niet groter maakt is dat natuurlijk niet zo netjes.

Ook het 'onthoud' idee is super; het scheelt inderdaad in rekentijd als je alleen vanaf de verwijderde row bezig gaat. Probleem is alleen dat de filter() functie er vaak meerdere tegelijkertijd weghaald; je begint met typen van 1 letter, filter() haalt alle rijen met die letter weg. Als je nog een letter typed komen er meer terug; je filter()t namelijk op een minder specifieke case.

Ik ga zelf nog eventjes aanklooien met deze nieuwe info. Nogmaals bedankt voor je input (en tijd).



:thumb:
 
Echter, ik weet niet hoe het zit met 'inzoomen' (bv: text groter maken in IE, of ctrl+muiswiel in andere browsers). Als it de achtergrond niet groter maakt is dat natuurlijk niet zo netjes.
Is aan gedacht! :P Daarom ook een minimale {line-height: 100%;} gebruikt, met een vertical-align voor de tekst in de tabel-cel:
  • Als je met FF begint op standaard lettergrootte, kan je 5 keer Ctrl~+ geven voor de regel er af schiet. En dan heb je intussen koeieletters die op tv-afstand van je scherm nog goed te zien zijn (resolutie 1024*768px):
zebra-tv.gif
  • Het gebruikte img is voor een "fixed rij-hoogte" van 25px.
  • Als je de jaloezie-achtergrond een paar pixels meer geeft per rij, kan je nog groter gaan.
  • Met het gebruikte img kan je Internet Explorer gerust op het grootste lettertype zetten (resolutie 1280*1024):
zebra-tv-ie.gif

Ook vele malen groter dan de systeemletters: dat is dus leesbaar voor iedereen.
  • Bovenstaande is verder bij alléén vergroten van het letterformaat.
    Bij inzoomen op de hele pagina tegelijk heb je al helemaal geen last van onderbloesende zebra's. :)
==========================

het scheelt inderdaad in rekentijd als je alleen vanaf de verwijderde row bezig gaat.
Nop, juist niet! In mijn scriptje wordt alles opnieuw ingekleurd, niet alleen vanaf een wispunt. Er moet juist extra gerekend (en eerst extra gescript) worden als je telkens vanaf een vers gewiste rij moet herberekenen. Het bij elke wijziging om-en-om renderen van de hele tabel gaat m.i. veel sneller, en is in elk geval in een p*p en een sch**t gepiept.

Probleem is alleen dat de filter() functie er vaak meerdere tegelijkertijd weghaalt ...
Dat zal dan ook geen probleem zijn. Op de staart van elke filter() functie zet je gewoon de zebra() functie, die alles on-the-fly regelt: wat je ook weghaalt of toevoegt. Toch?
Dus als er 3 rijen tegelijk verdwijnen en daarna de zebra() van stal wordt gehaald, staat alles meteen goed. Als de filter() functie lettergewijs werkt, ook geen probleem: aan de onkeyup plak je behalve het filter() ook de zebra().

Met vriendelijke groet,
CSShunter
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan