Chuaat: Probleme mit Zentrierung von Tabellen

Hallo, auf meiner Website habe ich eine Tabelle die in PHP erzeugt wird. Aus irgendeinem Grund wird die Tabelle aber Links an den Rand gepresst (siehe BildTabelle Links)

Im style.css habe ich bisher folgendes:

.tables {
    width: 600px;
    margin-left: 300px;
    text-align: left;
}

table,
th,
td {
	border: 1px solid #a0a0a0;
}


}

th,
td {
	font-weight: normal;
	text-align: left;
}

th {
	color:coral;
	background-color: #f1f3f4;
	font-weight: 700;
}

akzeptierte Antworten

  1. Hallo Chuaat,

    https://wiki.selfhtml.org/wiki/CSS/Tutorials/Ausrichtung/Inhalte_zentrieren

    Bis demnächst
    Matthias

    --
    Du kannst das Projekt SELFHTML unterstützen,
    indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
  2. Hallo Chuaat,

    ohne Kenntnis des HTML kann man schlecht beurteilen, ob das CSS ok ist.

    Mir fällt nur auf, dass der Tabelle nicht nur der margin, sondern auch die richtige Breite fehlt. Hat die table die class tables?

    Zum zentrieren verwendet man aber grundsätzlich keinen margin, der zur Breite passt, sondern margin:auto.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf, erstmal danke für deine Antwort. Die Tabelle hat tatsächlich die class tables. Das HTML der Seite sieht so aus:

      <!DOCTYPE html>
      
      <head>
      	<title>Bio</title>
      	<link rel="stylesheet" media="(orientation: landscape)" href="desktop.css">
      	<link rel="stylesheet" media="(orientation: portrait)" href="mobile.css">
      	<meta name="viewport" content="width=device-width, initial-scale=1.0">
      </head>
      
      <body>
      	<div id="wrapper">
      		<h1>Biologie</h1>
      		<?php include 'header.php';	?>
      	</div>
      	<div id="tables">
      		<br>
      		<?php
      	include 'abfrage.php';
      		?>
      	</div>
      	<br>
      	<p>Hier unten bitte Hausis reinschreiben</p>
      	<?php
      		include 'hausaufgaben_eintragen.php'
      		
      		?>
      	<script>
      		window.onscroll = function() {
      			myFunction()
      		};
      
      		var header = document.getElementById("myHeader");
      		var sticky = header.offsetTop;
      
      		function myFunction() {
      			if (window.pageYOffset > sticky) {
      				header.classList.add("sticky");
      			} else {
      				header.classList.remove("sticky");
      			}
      		}
      	</script>
      </body>`
      

      Wobei in abfrage.php die Tabelle generiert wird. Abfrage.php:

      <?php
      $abfrage = "SELECT * FROM Hausaufgaben WHERE Fach LIKE 'Bio' ORDER BY Bis ";
      $ergebnis = mysqli_query($db, $abfrage);
      echo "<table>";
      echo "<th>Erledigen Bis               </th>";
      echo "<th>Hausaufgabe          </th>";
      $date2 = 0;
      $datum = date("Y.d.m",$timestamp);
      while($row = mysqli_fetch_object($ergebnis))
      {
      	echo "<tr>";
       	echo "<td>",$row->Bis."</td>";
      	if ($date2 == 0)
      		$date2 = $row->Bis;
       	echo "<td>",$row->Hausaufgabe."</td>";
      	echo "</tr>";
      }
      echo "</table>";
      echo ($date2);
      $dateTimestamp1 = $timestamp;
      $dateTimestamp2 = strtotime($date2);
      $dateTimestamp1 = $dateTimestamp1 - 86400;
      if ($dateTimestamp1 > $dateTimestamp2)
      	$datum2 = date("Y-d-m",$dateTimestamp2);
      	$loeschen = ("DELETE FROM Hausaufgaben WHERE Bis LIKE $datum2");
      	$loesch = mysqli_query($db, $loeschen);
      ?>
      

      margin:auto habe ich auch probiert, die Tabelle bleibt links. Ich vermute ich habe unwissentlich zwei sich entgegensprechende Attribute benutzt. Wer will, kann sich die Website auch hier mal anschauen.

      Chuaat

      Edit Rolf B: Codeformatierung korrigiert.

      1. Hallo Chuaat,

        Die Tabelle hat tatsächlich die class tables.

        Dieser Satz enthält zwei Fehler.

        1. Du verwendest id="tables", statt class="tables". Deswegen ist deine .tables Regel im css unwirksam. Die Angabe id="tables" matcht man mit #tables, und class="tables" mit .tables.

        2. Die Tabelle hat weder id noch class tables, sondern diese id liegt auf einem div drumherum. Ein div ist ein Blockelement und breitet sich, sofern man das nicht beeinflusst, bis zum rechten Rand aus. Deswegen ist ein margin:auto unwirksam: Es gibt keinen freien Platz, den man als margin verteilen könnte.

        Also:

        • Das <div id="tables"> komplett entfernen. Das scheint mir keine Kunst zu sein, sondern etwas, das bedenkenlos weg kann.
        • Das <br> vor der Table kann auch weg. Abstände erstellt man im CSS mit margin.
        • Gib dem <table> Element das Attribut class="tables". Darin brauchst Du eigentlich nur margin: 1em auto; (das 1em als Ersatz für das <br>), ggf. kannst Du noch eine width setzen, aber die bitte nicht in px, sondern in em oder ch. 1em ist der aktuelle font-size Wert (was der Höhe der Schrift entspricht), 1ch ist die Breite der Ziffer 0 im aktuellen Font. Ich würde sagen, mit 40em oder 60ch bist Du gut bedient.

        Weitere Hinweise:

        • Eigentlich ist class="tables" nicht gut, weil nicht konkret genug. Klassen sollten eine fachliche Beschreibung dessen sein, was von diesem HTML dargestellt wird. In diesem Fall wäre class="hausaufgabenliste" vermutlich die bessere Wahl.

        • Dieser Klassenname deutet darauf hin, dass auch <table> eigentlich nicht die richtige Wahl ist. Man könnte auch argumentieren, dass dies eine Liste von Aufgaben ist, und das <dl> Element nutzen. Damit hättest Du relativ einfach die Möglichkeit, per CSS zwischen einer Matrixdarstellung (2 Spalten) und einer Listendarstellung (Datum links, die Aufgaben zum Datum eingerückt darunter) umzuschalten.

        • Verwende nicht media="(orientation:...)" als Grundsatzfilter für die CSS Links. Dadurch entsteht eine Menge Redundanz in den CSS Dateien, die Du pflegen musst. Die korrekte Lösung ist "Mobile First", d.h. Du machst eine .css Datei, die für Smartphones eine gute Anzeige bringt, und baust dann in diese CSS Datei mit @media Queries Zusätze ein, die Styles hinzufügen oder überschreiben, so dass die Anzeige für breite Geräte (Tablet, ggf. Handy im Querformat, Desktop-PC) verbessert wird. In diesen @media-Queries frage dann aber nicht die Orientierung ab, sondern die width, und zwar in em oder ch. Vorteil ist: wenn jemand einen größeren Font einstellt, schaltet die Seite erst bei einer größeren Breite in den "Breit"-Modus.

        • Verwende nicht font-family: arial. Das ist nicht genug. Du möchtest Arial, das ist ok, aber den hat nicht jeder. Du brauchst eine Liste von serifenlosen Fonts, und eine generische Angabe am Schluss, falls alle Fonts auf dem Gerät unbekannt sind. Unser Wiki empfiehlt: font-family: Helvetica, Arial, Geneva, sans-serif;

        • Deine Seite kann nicht bedient werden, die Menüpunkte sind nicht erreichbar. Es sei denn, man hat eine Maus oder einen Touchscreen. Eine Tastaturbedienung ist nicht möglich, und ein Screenreader dürfte ebenfalls scheitern. Dropdown-Menüs nur über :hover sind nicht zugänglich, das braucht JavaScript. Unser Wiki enthält ein Tutorial dazu. Ich kann Dich nicht dazu zwingen, und es ist auch ordentlich Arbeit. Wenn deine Nutzergruppe mit :hover klarkommt, würde ich sagen: Investiere die Zeit lieber ins Vokabellernen 😉

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Danke für deine ausführliche Antwort!👍 Ich werde versuchen das alles demnächst mal umzusetzen.

      2. @@Chuaat

        <?php
        $abfrage = "SELECT * FROM Hausaufgaben WHERE Fach LIKE 'Bio' ORDER BY Bis ";
        $ergebnis = mysqli_query($db, $abfrage);
        echo "<table>";
        echo "<th>Erledigen Bis               </th>";
        echo "<th>Hausaufgabe          </th>";
        $date2 = 0;
        $datum = date("Y.d.m",$timestamp);
        while($row = mysqli_fetch_object($ergebnis))
        {
        	echo "<tr>";
         	echo "<td>",$row->Bis."</td>";
        	if ($date2 == 0)
        		$date2 = $row->Bis;
         	echo "<td>",$row->Hausaufgabe."</td>";
        	echo "</tr>";
        }
        echo "</table>";
        echo ($date2);
        $dateTimestamp1 = $timestamp;
        $dateTimestamp2 = strtotime($date2);
        $dateTimestamp1 = $dateTimestamp1 - 86400;
        if ($dateTimestamp1 > $dateTimestamp2)
        	$datum2 = date("Y-d-m",$dateTimestamp2);
        	$loeschen = ("DELETE FROM Hausaufgaben WHERE Bis LIKE $datum2");
        	$loesch = mysqli_query($db, $loeschen);
        ?>
        

        Du solltest Markup nicht mit PHP echo generieren, sondern PHP als Template-Sprache einsetzen. Sieht dann so aus:

        <?php
        $abfrage = "SELECT * FROM Hausaufgaben WHERE Fach LIKE 'Bio' ORDER BY Bis ";
        $ergebnis = mysqli_query($db, $abfrage);
        $date2 = 0;
        $datum = date("Y.d.m",$timestamp);
        ?>
        
        <table>
          <thead>
            <tr>
              <th>Erledigen Bis</th>
              <th>Hausaufgabe</th>
            </tr>
          </thead>
          <tbody>
        <?php while($row = mysqli_fetch_object($ergebnis)):
          if ($date2 == 0) {
            $date2 = $row->Bis; 
          } ?>
            <tr>
              <td><?php echo $row->Bis; ?></td>
              <td><?php echo $row->Hausaufgabe; ?></td>
            </tr>
        <?php endwhile; ?>
          </tbody>
        </table>
        <?php echo ($date2); ?>
        
        <?php
        $dateTimestamp1 = $timestamp;
        $dateTimestamp2 = strtotime($date2);
        $dateTimestamp1 = $dateTimestamp1 - 86400;
        if ($dateTimestamp1 > $dateTimestamp2) {
        	$datum2 = date("Y-d-m",$dateTimestamp2);
        }
        $loeschen = ("DELETE FROM Hausaufgaben WHERE Bis LIKE $datum2");
        $loesch = mysqli_query($db, $loeschen);
        ?>
        

        Fehlende HTML-Elemente (thead, tr) hab ich ergänzt; mögliche Logikfehler im PHP nicht korrigiert.

        🖖 Stay hard! Stay hungry! Stay alive! Stay home!

        --
        “Turn off CSS. If the page makes no sense, fix your markup.” —fantasai
        1. Hallo Gunnar, danke auch für deine Antwort, kann es sein das diese

          möglichen Logikfehler im PHP

          mit dem löschen am Ende zu tun haben?

      3. Hallo Chuaat,

        ich würde auch gern mal über die abfrage.php reden. Die sieht sehr merkwürdig aus.

        • Wo kommt $timestamp her und was steht drin?
        • Wieso formatierst Du Datumswerte als Y.d.m, das ist zum Sortieren und auch für deutsches Datumsverständnis unpassend. Entweder d.m.Y für die Anzeige, oder Y-m-d zum Sortieren.
        • In der Datenbank sollte ein Datum kein String sein, bei Dir scheint es aber so zu sein. MYSQL hat eigene Datentypen für zeitliche Werte, in deinem Fall wäre wohl DATE richtig (es sei denn, du brauchst für die, die ihre HA in der Pause vor der Stunde machen, auch Uhrzeiten im „zu erledigen bis“). DATE Spalten werden trotzdem als String nach PHP transportiert (vermutlich aus irgendwelchen historischen Gründen), im Format Y-m-d, d.h. die solltest Du dann nicht mit strtotime in einen time_t verwandeln, sondern mit new DateTime($row->Bis) in ein DateTime Objekt. Davon kannst Du mit der add Methode einen Tag abziehen, das funktioniert dann auch korrekt an Tagen mit Uhrzeitumstellung.
        $row = mysqli_fetch_object($db, mysqli_fetch_object($ergebnis);
        $bis = new DateTime($row->Bis);
        
        $bis->sub(new DateInterval("P1D")); // 1 Tag abziehen
        

        Die Strings im Konstruktor für DateInterval sind etwas kryptisch, sie beginnen immer mit P (Periode), dann kommen Zahlen und Buchstaben. Näheres steht hier.

        • Du liest die aktuellen Aufgaben ein, aber es ist nicht so gut, wenn Du 'Bio' hart codiert in der Abfrage hat. Besser ist es, wenn Du deine Abfrage in eine Funktion packst und diese Funktion ganz zu Anfang von bio.php mit require_once einbindest. Der Funktion kannst Du dann Parameter geben. Die Ergebnisse sammelst Du in einem Array und gibst es zurück - man muss DB-Zugriffe, Fachlogik und HTML Ausgabe möglichst gut trennen, das schafft Wiederverwendbarkeit und macht den Code überschaubarer. Sicherlich gibt es noch mehr Code-Teile, die man auf diese Weise in Funktionen kapseln kann, daraus machst Du ein functions.php und lädst es zu Beginn.
        <?php
        function LeseHausaufgaben($fach) {
           $abfrage = "SELECT * FROM Hausaufgaben WHERE Fach = '$fach' ORDER BY Bis ";
           $ergebnis = mysqli_query($db, $abfrage);
           if ($ergebnis === FALSE) {
              // Hier noch hinzufügen: Fehler und SQL Query ins Log schreiben.
              // NICHT ins HTML ausgeben
              die ("SQL Query gescheitert!");
           }
           $aufgaben = ARRAY();
           while ($row = mysqli_fetch_object($ergebnis)) {
              $aufgaben[] = $row;
           }
           return $aufgaben;
        }
        

        Das verwendest Du dann - verkürzt gezeigt - so:

        $aufgaben = LeseHausaufgaben("Bio");
        if (count($aufgaben) == 0) {
           echo "Heute nichts auf";
        }
        else {
           foreach ($aufgaben as $aufgabe) {
              ... ausgeben
           }
        }
        

        Deine Löschlogik ist mir nicht klar. Da ist ein $timestamp Wert mit unbekannter Herkunft, und du löschst dann mit einem LIKE. Das ist sehr merkwürdig. Zum einen ist LIKE für einen Mustervergleich gedacht und du hast überhaupt kein Muster, zum anderen - was willst Du tun? Alles löschen was bis gestern oder noch früher zu erledigen war? Dafür kannst Du SQL Bordmittel verwenden. Es gibt die Funktion CURDATE, die liefert das aktuelle Datum, und es gibt in SQL Datumsarithmetik:

        DELETE 
        FROM Hausaufgaben 
        WHERE Fach = 'Bio' 
          AND Bis < DATE_SUB(CURDATE(), INTERVAL 1 DAY)
        

        Würde alles löschen, was bis vorgestern fällig war (wegen des < Vergleichs). Für Löschen "bis gestern" brauchst Du gar nicht rechnen.

        Das funktioniert natürlich nur gut, wenn Bis eine Datumsspalte ist.

        Rolf

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

    in Ergänzung zu dem, was Matthias und Rolf schrieben:
    Ich denke, dass deine Fehlannahme darin besteht, was text-align macht. Es macht genau das, was es verspricht: Text zentrieren. Und das auch mit Erfolg, denn der Text in deiner Tabelle ist zentriert.

    Gruß
    Julius

    1. Hallo,

      Es macht genau das, was es verspricht: Text zentrieren. Und das auch mit Erfolg, denn der Text in deiner Tabelle ist zentriert.

      Obwohl text-align:left angegeben ist…
      Ich vermag keinen Erfolg erkennen.

      Gruß
      Kalk

      1. Hallo Tabellenkalk,

        Es macht genau das, was es verspricht: Text zentrieren. Und das auch mit Erfolg, denn der Text in deiner Tabelle ist zentriert.

        Obwohl text-align:left angegeben ist…
        Ich vermag keinen Erfolg erkennen.

        Du hast recht, im Ausschnitt ist es tatsächlich left. Allerdings sieht das Resultat wie das von text-align:center aus (danach habe ich mich gerichtet), und das ist es auch. Im Stylesheet wurde das auch für den body so formuliert.

        Gruß
        Julius

    2. Hallo, ich bin mir aber nicht sicher was genau ich verwenden soll, um die Tabelle weiter nach rechts, bzw. in die Mitte verschieben soll.

      1. Hallo Chuaat,

        ich bin mir aber nicht sicher was genau ich verwenden soll, um die Tabelle weiter nach rechts, bzw. in die Mitte verschieben soll.

        Matthias hat in seiner Antwort bereits den betreffenden Wiki-Artikel verlinkt.

        Gruß
        Julius

    3. Hi Julius,

      Es [text-align] macht genau das, was es verspricht: Text zentrieren.

      das ist die Wahrheit, aber nicht die ganze Wahrheit.

      Es zentriert nämlich ganz allgemein inline-Inhalte. Dazu zählen z.B. auch Bilder (img) oder Formularelemente, wenn man die Defaults nicht überschreibt.

      Live long and pros healthy,
       Martin

      --
      Ich stamme aus Ironien, einem Land am sarkastischen Ozean.
    4. Danke dir, @Tabellenkalk und @Der Martin für eure Beiträge zu dem Thema.