CSS: Formatierungsprobleme mit einer Tabelle

WulfmanGER

Commander
Registriert
Juli 2005
Beiträge
2.272
Hallo geschätzte Gemeinde ;)

ich kämpfe gerade mit einem Formatierungsproblem. Ich hab schon ChatGPT, Ollama/Codellama drauf angesetzt. Leider ohne Erfolg. Wobei mich Ollama bisher am besten geholfen hat.

Ich habe folgendes CSS (für eine Scrollbare Tabelle wo der Header oben fixiert ist):

Code:
table.scroll thead tr:after {
  content: '';
  overflow-y: scroll;
  off_visibility: hidden;
}

table.scroll thead th {
  flex: 1;
  display: table-cell;
}

table.scroll tbody {
  display: block;
  width: auto;
  overflow-y: auto;
  max-height: 400px;
}

table.scroll thead tr,
table.scroll tbody tr {
  OFF_display: flex;
 }

table.scroll tbody tr td {
  flex: none;
  white-space: normal;
}

.genre-rating {
  width: 70px;
  text-align: center;
}

.genre-rating-titel {
  width: fit-content;
  text-align: left;
}

dazu folgendes html (mit smarty)
[code]
            <table id="content-table" class="scroll" cellspacing="0" cellpadding="0" border="0">
                <thead>
                    <tr>
                        <th class="genre-rating-titel">Titel</th>
                        <th class="genre-rating">Rating</th>
                    </tr>
                </thead>
                <tbody>
                    {foreach $genreContent as $rowg}

                    <tr>
                        <td class="genre-rating-titel"><a href="index.php?view=movie&imdb={$rowg.imdb_id}">{$rowg.tmdb_title}</a></td>
                        <td class="genre-rating">{$rowg.imdb_rating}</td>
                    </tr>

                    {/foreach}
                </tbody>
            </table>

Mein Problem ist jetzt folgendes:
Ich möchte eine Tabelle angezeigt bekommen die 2 Spalten hat:
Titel: die Breite ist Variable! 250px ... 300px ... 90px. Kommt auf den Inhalt an.
Rating: 70px reicht. (die mal bitte merken... ich glaub hier ist mein Problem irgendwo versteckt)

Scheinbar hat CSS ein Problem mit Tabellen die keine feste breite haben - kennt es nicht, will es nicht, mag es nicht. Der Aktuelle Zustand ist (siehe Screenshot) das die Spaltenüberschrift RECHTS von ihrem eigentlichen Inhalt steht. Jetzt hab ich festgestellt dsa die Spaltenüberschrift exakt 70px breiter ist als die breiteste zelle, nach der sich orientiert werden soll. 70px. Wird hier etwas addiert? Warum?
1711570955226.png

Wie man sieht: Rating steht neben der eigentlichen Content-Spalte.

Ich find die stelle nicht. Bin aber schon froh das ich den <td>-Inhalt sauber untereinander habe - nur passt der nicht zum <th>.

Ich hatte schon die vermutung das es an den classen liegt ... Ich hab auch bei der <th>titel die class entfernt und style-widht-auto etc. versucht - keine chance. Ich weiß einfach nicht wo die verbreiterung der Spaltenüberschrift um die Breite der Rating-Überschrift herkommt.

Getestet: ist Rating auf 80; ist Titel 80 breiter bzw.
Code:
.genre-rating {
  WEG_width: 70px;
  width: fit-content;
  text-align: center;
}
war meine letzte Idee ... aber auch hier wird die Breite zu <th class="genre-rating-titel">Titel</th> addiert ... und wohl gemerkt: nur da.

Hat da jemand eine Idee woran das liegt? Wie ich das behoben bekomme?

BTW: wenn ich die Tabelle ohne CSS mache (und somit ohne Scrolling), klappt es einwandfrei :(
Bin kurz davor das Scrolling per DIV zu machen. Tabelle ohne Überschrift. Titel LINKS, Rating RECHTSbündig. Und im DIV eben Titel links und Rating Rechts. Ein Fake-Tabellenkopf .... Aber das will ich nicht :( Möchte das gerne mit einer Tabelle nutzen... (ich brauch die Tabellenüberschriften ggf. später noch)

Grüße
 
  • Gefällt mir
Reaktionen: Sinatra81
Das Problem ist, dass man bei "display" nicht einfach so "block" und "table-cell" zusammen nutzen kann. Hier ist das Resultat, dass die erste <th> so breit wird wie der gesamt <tbody>. Der Code ist auch insgesamt viel zu kompliziert, denn es gibt für fixierte Elemente extra "position: sticky".

HTML:
<!DOCTYPE html>
<html>
<head><style>
table {
  width: fit-content;
  white-space: nowrap;
  display: block;
  overflow-y: auto;
  max-height: 400px;
  border: 1px solid black;
}
th, td {
  padding: 4px;
}
th {
  text-align: left;
  position: sticky;
  top: 0;
  background: #ccc;
}
th+th {
  width: 70px;
  text-align: center;
}
</style></head>
<body>
  <table id="content-table" class="scroll" cellspacing="0" cellpadding="0" border="0">
    <thead>
      <tr>
        <th>Titel</th>
        <th>Rating</th>
      </tr>
    </thead>
    <tbody>
      {foreach $genreContent as $rowg}
      <tr>
        <td><a href="index.php?view=movie&imdb={$rowg.imdb_id}">{$rowg.tmdb_title}</a></td>
        <td>{$rowg.imdb_rating}</td>
      </tr>
      {/foreach}
    </tbody>
  </table>
</body>
</html>
 
Danke dir schon mal.

Es sind aber noch zwei Probleme drin:
1) Das Sticky klappt nicht. Die Überschrift der Spalten scrollt aus den Bildschirm raus wenn ich runterscrolle
=> gerade mal zu Sticky geguckt: Liegt das vielleicht am top:0? Die Tabelle ist teil eines DIV-DIV-DIV - darüber befindet sich noch das Seitenmenu etc. top:0 wäre der Bildschirmrand oder der Tabellen-DIV-Rand? Hab mal mit hohen, viel höheren Werten probiert - das ändert aber nichts. Ein top:500 sollte dann ja optisch reinschlagen ;)
2) Auf Handy klappt die Höhenbegrenzung max-height: 400px; nicht (auch ohne max-). Ich muss den Screen scrollen - nicht die Tabelle. Aufm Desktop hab ich eine Tabelle die 400px hoch ist und da drin scrolle ich.

Danke schon mal


PS: da auf der Seite mehrere Tabellen sind muss ich natürlich mit class arbeiten. Wie setze ich dein th+th da um? ist ja auch 2x th - ist das absicht oder vertipper? (beim rest hab ich ein .scroll dran gepappt - damit nur die "scroll-tabelle" genutzt wird)
 
Zuletzt bearbeitet: ("nicht" fehlte)
th+th bedeutet ein th, das auf selber Ebene einem th folgt. Konrekt heißt das: alle th, außer das erste. Den Trick schau ich mir gleich ab.
Ich kann dir statt einem table auch ein Grid empfehlen, da hast du viele Probleme nicht mehr. Du kannst auch deine vorhandene Tabelle testweise nur per CSS in ein Grid umbauen:

CSS:
table
{
    display: grid;
    grid-template-columns: repeat(2, 1fr);
}

tr
{
    display: contents;
}
 
floq0r schrieb:
Tabelle testweise nur per CSS in ein Grid umbauen:
die ganze Seite ist bereits in ein grid gebaut (div) - kann es daher sein das dieses table-grid ein problem versucht? Dein Code sorgt dafür das ich links die beiden Spaltenüberschriften habe. Direkt nebeneinander: TitelRating und gaaaaanz weit rechts die dazugehörigen Spalten - die Darstellung hatte ich gestern mehrfach :|

floq0r schrieb:
th+th bedeutet ein th, das auf selber Ebene einem th folgt. Konrekt heißt das: alle th, außer das erste. Den Trick schau ich mir gleich ab.
Versteh ich nicht :( hab das jetzt einfach mal gelöscht und geguckt was passiert. Nichts. Die 70px waren für die zweite Spalte gedacht - die wollte ich "erstmal" auf 70px setzen (und dann langsam verkleinern - mit auto, fit-content etc. hab ich die nicht kontrollieren können). Wobei hier die überschrift das breiteste ist was vorkommen kann -> wenn ich die 70px entferne oder drin lasse: die spalte ist so breit wie die Überschrift -> PERFEKT ;)
 
Ah, man muss thead und tbody auch noch "deaktivieren":

CSS:
table
{
    display: grid;
    grid-template-columns: repeat(2, 1fr);
}

thead,
tbody,
tr
{
    display: contents;
}

Damit gibt es im Flow nur mehr table, th und td.

Wegen th+th: Dafür brauchst du beim table ev. noch table-layout: fixed;. width formatting bei tables ist teilweise sehr mühsam. Die Probleme hast du bei einem Grid wie gesagt nicht.
 
1711623044276.png

Wobei hier der maximale Abstand (den das äussere DIV erlaubt) gewählt wurde - die Content-Spalte ist ganz rechts und TitelRating ist ganz links.
 
Die CSS für Titel und Zelle sollten dieselbe text-align haben denke ich
 
WulfmanGER schrieb:
1) Das Sticky klappt nicht. Die Überschrift der Spalten scrollt aus den Bildschirm raus wenn ich runterscrolle
Das tut sie auch im gelieferten Beispiel. Ich ging davon aus, dass die Überschrift nur in Bezug auf den Tabellencontainer stehen bleiben soll, wie es auch der Code im Startbeitrag tut. Und das funktioniert sauber:

1711624096789.png


WulfmanGER schrieb:
2) Auf Handy klappt die Höhenbegrenzung max-height: 400px; nicht
Das kann ich ebenfalls nicht bestätigen, der Beispielcode funktioniert.

WulfmanGER schrieb:
da auf der Seite mehrere Tabellen sind muss ich natürlich mit class arbeiten.
Das muss man aber nicht für jede einzelne Zelle der Tabelle. Es reicht ein Selektor für die Tabelle, und dann kann man alles andere darunter eingliedern. Und falls doch Klassen für Zellen genutzt werden, dann muss man da nicht ständig einen Roman wie "genre-rating-titel" hin schreiben.

WulfmanGER schrieb:
Wie setze ich dein th+th da um? ist ja auch 2x th - ist das absicht oder vertipper?
Das heißt "th nach th" und selektiert im Beispiel somit die th aller Spalten ab der zweiten. Die Reihenfolge ist hier auch relevant, die spezifischere Regel muss später kommen.
Ergänzung ()

floq0r schrieb:
Ich kann dir statt einem table auch ein Grid empfehlen
Das kann man auch machen. Das ist dann im Beispiel aber immer so breit wie der umgebende Container.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: floq0r
Zurück
Oben