Stefan: CSS - Visuelle Orientierung in Tabelle

Ich versuche eine visuelle Orientierung in einer Tabelle zu erstellen, sodass man - ähnlich wie in Excel - bei einem Mouseover über ein Feld oben bzw. rechts visuell angezeigt bekommt in welcher Spalte und welcher Zeile man sich befindet.

Um es nicht zu verkomplizieren, wäre mein erster Zugang nun eine SVG-Grafik zu erstellen und den einzelnen Feldern dann in Klassen und Unterklassen so zu ordnen, dass sie entsprechend reagieren.

Wär das auch euer Zugang oder gäbe es noch einen einfacheren Weg?

  1. Servus!

    Ich versuche eine visuelle Orientierung in einer Tabelle zu erstellen, sodass man - ähnlich wie in Excel - bei einem Mouseover über ein Feld oben bzw. rechts visuell angezeigt bekommt in welcher Spalte und welcher Zeile man sich befindet.

    ok!

    Die Reihen kannst Du über tr:hover formatieren, evtl. den Hintergrund farbig, oder einen Schatten.

    HTML/Tabellen/Gestaltung_mit_CSS

    Kapitel 2.8

    Die Spalten sind nur mit JS möglich

    Tabellenspalte bei :hover markieren

    Um es nicht zu verkomplizieren, wäre mein erster Zugang nun eine SVG-Grafik zu erstellen und den einzelnen Feldern dann in Klassen und Unterklassen so zu ordnen, dass sie entsprechend reagieren.

    Das mit den Klassen funzt so nicht. Deshalb die Pseudoklasse :hover.

    Wär das auch euer Zugang oder gäbe es noch einen einfacheren Weg?

    Herzliche Grüße

    Matthias Scharwies

    --
    Ich habe heute rausgefunden, dass in das Pizzafach meines Rucksacks auch ein Laptop passt!
  2. Ich hab das versucht. Leider klappt das mit dem Hover (#a1:hover ~ #t1 {fill: red;} mit zwei IDs gleichzeitig nicht.

    Das Ziel wäre hier, dass bei hover auf #a1 sich auch #t1 und #z1 auf den definierten fill Wert ändern.

    <?xml version="1.0" encoding="UTF-8"?>
    <svg id="auswahl" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 601 395">
      <defs>
        <style>
    
    	  
    #a1 {fill: orange;}
    #t1 {fill: green;} 
    #a1:hover {fill: red;}	  
    #a1:hover ~ #t1 {fill: red;}
    
    
    
        </style>
      </defs>
      <g id="t3">
        <rect class="cls-3" x="195" width="128" height="98"/>
      </g>
      <g id="t2">
        <rect class="cls-3" x="325" y="0" width="128" height="98"/>
      </g>
      <g id="t1">
        <rect class="cls-3" x="455" y="0" width="128" height="98"/>
      </g>
      <g id="z3">
        <rect class="cls-2" x="2" y="97" width="128" height="98"/>
      </g>
      <g id="z2">
        <rect class="cls-2" x="1" y="197" width="128" height="98"/>
      </g>
      <g id="z1">
        <rect class="cls-2" y="297" width="128" height="98"/>
      </g>
      <g id="a3">
        <rect class="cls-1" x="174" y="110" width="128" height="98"/>
      </g>
      <g id="a2">
        <rect class="cls-1" x="344" y="120" width="128" height="98"/>
      </g>
      <g id="a1">
        <rect class="cls-1" x="473" y="120" width="128" height="98"/>
      </g>
    </svg>
    
    1. Hallo Stefan,

      oh. Sag das doch, dass deine Tabelle kein <table> Element ist.

      Der Hover auf dem a1 Element funktioniert bei mir.

      Der Hover per Nachbarselektor funktioniert deshalb nicht, weil das #t1 Element im DOM for dem #a1 Element steht. Aber weil dies SVG ist, kannst Du die Überschriften-Elemente auch ans Ende des SVG stellen. Dann geht's auch mit dem Hover.

      Die Datenzellen einer Spalte solltest Du dann mit einer Klasse versehen und nicht mit einer ID, dann ist das im CSS einfacher zu formulieren.

      Ich halte diese SVG basierende Lösung aber für sehr mühsam. Muss das in einem SVG passieren?

      Rolf

      --
      sumpsi - posui - obstruxi
  3. Hallo Stefan,

    oben bzw. rechts visuell angezeigt bekommt in welcher Spalte und welcher Zeile man sich befindet.

    Lechts und rinks ist schwierig, wervexele ich auch ständig.

    Zumindest in meinem Excel sind die Zeilennummern links 😉

    Zeilenweise ist das, was Du möchtest, mit der Pseudoklasse :hover machbar.

    <table>
    <thead>
    </thead>
    <tbody>
    <tr><th></th><td></td><td></td><td></td><td></td></tr>
    <tr><th></th><td></td><td></td><td></td><td></td></tr>
    <tr><th></th><td></td><td></td><td></td><td></td></tr>
    </tbody>
    </table>
    
    tbody tr:hover th {
       background-color: #ffc;
    }
    

    Damit würde die th Zelle in den body-Rows eine gelbe Hintergrundfarbe bekommen, wenn die Maus irgendwo in der Zeile schwebt.

    Für Spalten geht das nicht. Es gibt zwar das col-Element, mit dem Du Spaltenbreiten definieren kannst, und dem Du auch eine Hintergrundfarbe zuweisen könntest. Aber weil die td-Elemente keine Kind-Elemente von col sind und die Relation zwischen col und td nur im Table-Anzeigemodell ist, wird der hover über einem td-Element nicht auf das col-Element übertragen.

    Es gibt böse Tricks draußen im Web. Beispielsweise

    td:hover::before {
       content: " ";
       position:absolute;
       height: 10000px
       width: 100%;
    }
    

    D.h. wenn man über einem td hovert, wird diesem td ein Pseudoelement verpasst, das riesig hoch ist und die ganze Spalte überdeckt. Mittels overflow:hidden auf der table wird dann verhindert, dass dieses Pseudoelement aus der Tabelle hinausschaut.

    Aus meiner Sicht: NICHT tun. Ein solches Element belastet die Layout-Engine des Browsers massiv. Besser wären wohl col-Elemente und eine JavaScript-Lösung, die auf mouseenter und mouseleave reagiert und dem col-Element, das zum td-Element gehört, eine Highlight-Klasse zuweist. Die Nummer des col-Elements bekommst Du über die cellIndex-Eigenschaft des td Elements (vorausgesetzt, dass keine colspans verwendet werden).

    Das ist natürlich nur für Menschen nutzbar, die eine Maus verwenden. Manche Touch-Geräte simulieren mouseenter und mouseleave bei Touch-Aktionen. Das Feature wird also nicht für jeden verfügbar sein.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. @@Rolf B

      tbody tr:hover th {
         background-color: #ffc;
      }
      

      Damit würde die th Zelle in den body-Rows eine gelbe Hintergrundfarbe bekommen, wenn die Maus irgendwo in der Zeile schwebt.

      Eben: irgendwo. Auch über der Kopfzelle. Soll die Kopfzelle auch gehighlightet werden, wenn sich der Zeiger über dieser befindet? Oder nur, wenn sich der Zeiger über einer Datenzellen in dieser Zeile befindet? Ich denke, letzteres. Also den Selektor angepasst:

      tbody tr:has(td:hover) th {
         background-color: #ffc;
      }
      

      Für Spalten geht das nicht.

      🤣 Hold my beer!

      Klar geht das:

      thead:has(~ tbody td:nth-child(2):hover) th:nth-child(2),
      thead:has(~ tbody td:nth-child(3):hover) th:nth-child(3),
      thead:has(~ tbody td:nth-child(4):hover) th:nth-child(4) {
         background-color: #ffc;
      }
      

      Für wieviele Spalten man das vorsehen muss, hängt von der jeweiligen Tabelle ab. Und ein CSS-Präprozessor ist dabei hilfreich.

      Einfach wie das kleine Einmaleins.

      Funktioniert in Safari und Chromia. Firefox hinkt bei :has() noch etwas hinterher. Da es sich hierbei um ein sinnvolles, aber nicht zwingend notweniges Feature handelt, kann man auf progressive enhancement setzen. Irgendwann in nicht allzuferner Zukunft wird es auch im Firefox funktionieren, ohne dass man dazu nochmal was am Code ändern müsste.

      🖖 Живіть довго і процвітайте

      --
      „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
      — @Grantscheam auf Twitter
      1. @@Gunnar Bittersmann

        Und ein CSS-Präprozessor ist dabei hilfreich.

        Zuerst hatte ich im Codepen zu stehen:

        tbody > tr:has(td:hover) > th {
        	background-color: var(--th-highlight-background-color);
        	color: var(--th-highlight-text-color);
        }
        
        @for $col from 2 through 11 {
        	thead:has(~ tbody td:nth-child(#{$col}):hover) th:nth-child(#{$col}) {
        		background-color: var(--th-highlight-background-color);
        		color: var(--th-highlight-text-color);
        	}
        }
        

        Dadurch werden viele Regeln mit immer wieder denselben Deklarationen generiert, was das Stylesheet unnötig aufbläht.

        Besser: in der Schleife die Selektorliste zusammenbauen, dann eine Regel generieren:

        $selectors: "tbody > tr:has(td:hover) > th";
        
        @for $column from 2 through 11 {
        	$selectors: "#{$selectors}, thead:has(~ tbody td:nth-child(#{$column}):hover) th:nth-child(#{$column})";
        }
        
        #{$selectors} {
        	background-color: var(--th-highlight-background-color);
        	color: var(--th-highlight-text-color);
        }
        

        🖖 Живіть довго і процвітайте

        PS: Beachte auch die Umbenennung von $col in $column. 😏

        --
        „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
        — @Grantscheam auf Twitter