Div in Div zentrieren
Jens Heinerl
- css
Hi,
ich hoffe ihr könnt mir weiterhelfenk, weil ich bekomms einfach nicht hin. Ich möchte gern ein div Element in einem anderen div Element zentrieren, welches nur auf einer Seite einen Border besitzt. Wie kann ich das realisieren, dass das auch der IE9 versteht.
div.tablecontainer {}
div.spalte
{
float:left;
border-left: 1px solid black;
background: #dcdcdc;
}
div.cols
{
border-bottom:1px solid black;
height: 28px;
white-space: nowrap;
padding:2px;
text-align:center;
vertical-align: middle;
line-height: 28px;
}
.cdiv
{
display:block;
border: 1px solid #000;
height: 24px;
text-align:center;
vertical-align: middle;
line-height: 24px;
}
<div class="tablecontainer">
<div class="spalte">
<div class="cols">
<div class="cdiv"></div>
</div>
<div class="cols">
<div class="cdiv"></div>
</div>
</div>
</div>
Bis jetzt erhalte ich vom .cdiv Border aus gesehen, rechts stets einen größeren Abstand (um 1px) als links zum jeweiligen .spalte Border.
Mein Ziel ist eine Tabelle zu erstellen mittels Divs und der Inhalt in diesen Divs (cols) soll stets zentriert sein.
Mit Tabellen habe ich das ganze schon ausprobiert, nur leider stört mich der Pixelfehler im Firefox und Safari. Beide Browser (auch in den neusten Versionen) sind nicht in der Lage eine Tabelle pixelgenau / sauber darzustellen. Entsprechende Fehlerberichte bzw. Reports existieren bereits seit längerer Zeit, aber finden scheinbar keine Beachtung bei den Entwicklern :-(.
Gruß
Jens
Hi!
Ich möchte gern ein div Element in einem anderen div Element zentrieren, welches nur auf einer Seite einen Border besitzt. Wie kann ich das realisieren, dass das auch der IE9 versteht.
Ehrlich gesagt habe ich bis jetzt weder das Vorhaben, noch das Problem richtig verstanden.
Aber spontan kam mir beim Lesen in den Sinn: Border auch auf der anderen Seite und border-color auf transparent setzen.
<div class="tablecontainer">
<div class="spalte">
<div class="cols">
<div class="cdiv"></div>
</div>
<div class="cols">
<div class="cdiv"></div>
</div></div>
</div>
Das ist in meinen Augen hochgradige [Divitis](http://en.wiktionary.org/wiki/divitis).
> Bis jetzt erhalte ich vom .cdiv Border aus gesehen, rechts stets einen größeren Abstand (um 1px) als links zum jeweiligen .spalte Border.
Hier schafft eventuell
`* {box-sizing: border-box;}`{:.language-css} Abhilfe (mit entsprechenden Vendor Prefixen).
> Mein Ziel ist eine Tabelle zu erstellen
Wenn es sich dabei um tabellarische Daten handelt, ist das bis hierhin OK.
> mittels Divs
Jetzt nicht mehr.
> und der Inhalt in diesen Divs (cols) soll stets zentriert sein.
>
> Mit Tabellen habe ich das ganze schon ausprobiert,
Zeigen!
> nur leider stört mich der Pixelfehler im Firefox und Safari. Beide Browser (auch in den neusten Versionen) sind nicht in der Lage eine Tabelle pixelgenau / sauber darzustellen.
Letzteres kann ich ja kaum glauben. Je nach "Konstrukt" hast du ggf. mit Rundungsfehlern zu tun. Wenn diese auftreten können (wenn relative Werte verwendet werden), muss man das Layout so anlegen, dass sie an einer Stelle auftreten, wo sie nicht auffallen.
> Entsprechende Fehlerberichte bzw. Reports existieren bereits seit längerer Zeit, aber finden scheinbar keine Beachtung bei den Entwicklern :-(.
Link(s)?
Gruß Gunther
Hi Gunther,
einen Link zu der Page habe ich leider nicht, aber den Quellcode mit den Tabellen. Ich hab den Border mal sehr breit gewählt, damit der Fehler stark zur Geltung kommt.
Kurz was der Code überhaupt bewirken soll. Im Html-Body hab ich eine Tabelle erstellt. In manchen Zellen ist ein Div ("cdiv") integriert. Wird auf dieses "cDiv" geklickt wird die Javascript-Funktion "CreateDiv" ausgeführt. In dieser Funktion soll dem "cdiv" ein weiteres div "cdiv_ul" angehängt werden, welches eine Liste beinhaltet. Ähnlich wie bei einer Dropdownbox.
Das Problem bei diesem Ansatz ist, dass ich im IE9 einen Pixelversatz dieses "cdiv_ul" erhalte. Setze ich den Border der Tabelle auf 1px ist der Versatz auch nur 1px. Setze ich den Border der Tabelle auf 10px sind es 5px Versatz. Das Div "cdiv_ul" ist gegenüber dem "cdiv" nach links und nach oben verschoben. Lasse ich den Border komplett weg, habe ich auch keinen Versatz und alles läuft wie erwartet.
Im Firefox und Safari hab ich bei diesem Bsp auch keinen Versatz; gleiches trifft auch für den IE8 zu. Im IE9 (9.0.8112.16421) tritt der Versatz auf.
Gruß
Jens
function CreateDiv(obj) {
var pos = getPosition(obj);
var posarray = pos.split(",");
var offset = obj.offsetHeight;
var width = obj.offsetWidth;
/* create & define div container */
var newdiv = document.createElement('div');
var divIdName = 'mDivCBox';
newdiv.setAttribute('id', divIdName);
newdiv.style.position = "absolute";
newdiv.style.top = (parseInt(posarray[1]) + parseInt(1)) + 'px';
newdiv.style.left = (parseInt(posarray[0]) + parseInt(1)) + 'px';
newdiv.style.top = (parseInt(posarray[1])) + 'px';
newdiv.style.left = (parseInt(posarray[0])) + 'px';
newdiv.style.width = (parseInt(width)) + 'px';
newdiv.innerHTML = '<div><ul id="cdiv_ul" class="cdiv_ul"><li>first item</li><li>second item</li><li>third item</li><li>four item</li></ul></div>';
/* wrapper div container will contain our new div */
var ni = document.getElementById('wrapper');
ni.appendChild(newdiv);
/* add specific padding-value */
var select_ul = document.getElementById(cdiv_ul');
select_ul.style.marginTop = parseInt(offset) + 'px';
}
.cdiv
{
display:block;
border: 1px solid #000;
height: 24px;
margin:0px auto;
padding:0px;
}
.cbox_div
{
display:block;
background-color:transparent;
}
.cbox_ul {
background:#aaa;
list-style:none;
border: 1px solid #000;
border-top-width:0px;
border-top:none;
cursor:default;
}
.cbox_ul li:hover
{
background:#dcdcdc;
}
.cbox_ul li {padding-left:4px; }
table {
border-collapse: collapse;
/*border:1px solid #000;*/
/*border-right-width:0px;
border-bottom-width:0px;
border-bottom:none;
border-right:none;*/
}
td, th
{
padding:2px;
border: 10px solid #000;
height:60px;
}
thead th {
text-align: center;
background: #787878;
color: #000;
}
<body>
<div class="wrapper">
<div class="tablecontainer">
<table>
<thead>
<tr>
<th>Hdr1</th>
<th>Hdr2</th>
<th>Hdr3</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="cdiv" onclick="CreateDiv(this);">
<div class="cbild">
</div>
<div class="ctext">
<span class="as_cui_t">Auswahl:</span>
</div>
</div>
</td>
<td>
<div class="cdiv" onclick="CreateDiv(this);">
<div class="combobild">
</div>
<div class="combotext">
<span class="as_cui_t">Auswahl2:</span>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
Hi Jens!
Im Firefox und Safari hab ich bei diesem Bsp auch keinen Versatz; gleiches trifft auch für den IE8 zu. Im IE9 (9.0.8112.16421) tritt der Versatz auf.
Um das jetzt mal "live" im IE9 zu betrachten ...
function CreateDiv(obj) {
var pos = getPosition(obj);
var posarray = pos.split(",");
var offset = obj.offsetHeight;
var width = obj.offsetWidth;/* create & define div container */
var newdiv = document.createElement('div');
var divIdName = 'mDivCBox';
newdiv.setAttribute('id', divIdName);newdiv.style.position = "absolute";
newdiv.style.top = (parseInt(posarray[1]) + parseInt(1)) + 'px';
newdiv.style.left = (parseInt(posarray[0]) + parseInt(1)) + 'px';
newdiv.style.top = (parseInt(posarray[1])) + 'px';
newdiv.style.left = (parseInt(posarray[0])) + 'px';
newdiv.style.width = (parseInt(width)) + 'px';newdiv.innerHTML = '<div><ul id="cdiv_ul" class="cdiv_ul"><li>first item</li><li>second item</li><li>third item</li><li>four item</li></ul></div>';
/* wrapper div container will contain our new div */
var ni = document.getElementById('wrapper');
ni.appendChild(newdiv);/* add specific padding-value */
var select_ul = document.getElementById('cdiv_ul');
select_ul.style.marginTop = parseInt(offset) + 'px';
}
... fehlt mir hier die Funktion getPosition.
Und dir ist auch bekannt, dass eine ID nur einmal pro Seite vorkommen darf!?
> ~~~html
> <body>
> <div class="wrapper">
>
> <div class="tablecontainer">
> <table>
> <thead>
> <tr>
> <th>Hdr1</th>
> <th>Hdr2</th>
> <th>Hdr3</th>
> </tr>
> </thead>
> <tbody>
> <tr>
> <td>
> <div class="cdiv" onclick="CreateDiv(this);">
> <div class="cbild">
> </div>
> <div class="ctext">
> <span class="as_cui_t">Auswahl:</span>
> </div>
> </div>
> </td>
> <td>
> <div class="cdiv" onclick="CreateDiv(this);">
> <div class="combobild">
> </div>
> <div class="combotext">
> <span class="as_cui_t">Auswahl2:</span>
> </div>
> </div>
> </td>
> </tr>
> </tbody>
> </table>
> </div>
> </div>
> </body>
>
Vielleicht könntest du mal deine "Absicht" erläutern, denn wenn ich mir deinen Code so angucke, habe ich immer noch die allergrößten Zweifel daran, dass er semantisch korrekt ist (bspw. wozu schon wieder diese "Divitis" innerhalb von Tabellenzellen?).
Gruß Gunther
Hi Gunther,
stimmt die Funktion habe ich vergessen:
function getPosition(obj) {
var topValue = 0, leftValue = 0;
while (obj) {
leftValue += obj.offsetLeft;
topValue += obj.offsetTop;
obj = obj.offsetParent;
}
finalvalue = leftValue + "," + topValue;
return finalvalue;
}
Und dir ist auch bekannt, dass eine ID nur einmal pro Seite vorkommen darf!?
Das ist mir bekannt. Das div wird sobald der User mit der Mouse irgendwo hinklickt oder das Fenster verlässt wieder gelöscht. Hab das bloß nicht in den Code reingepackt, da dort der Fehler nicht liegen kann. Und sonst würde es noch mehr Code bedeuten, den ihr euch anschauen müsstet.
> <td>
> <div class="cdiv" onclick="CreateDiv(this);">
> <div class="combobild">
> </div>
> <div class="combotext">
> <span class="as_cui_t">Auswahl2:</span>
> </div>
> </div>
> </td>
Klar, kann ich das erläutern: innerhalb der Tabelle soll ein Text mit einem Bild (rechts davon) angezeigt werden.
----------------------------
| Das ist ein text | [Bild]|
-----------------------------
Das Bild weist eine feste Breite von 21px auf und befindet sich im div container "combobild". Im div container "combotext" befindet sich der Text (span) der unterschiedlich lang sein kann und die Spaltenbreite bis zu einer "max-width" definiert. Das Div "combotext" beinhaltet ein Hintergrundbild für den span-text.
Beide divs "combotext" und "combobild" hab ich in das div "cdiv" gepackt, welches dem ganzen einen Border "1px solid #eee" verleiht.
Diese Informationen habe ich lediglich rausgenommen, da das eigentlich Darstellungsproblem auch ohne dieen css-Styles auftritt. Aber vielleicht hast du diesbezüglich noch eine gute Optimierung hinsichtlich Codesize parat.
Hier sind die CSS:
.combotext
{
background: url("../images/dd_bk.png") repeat-x;
height:100%;
margin-right:21px;
padding:0px 2px 0px 2px;
text-align:left;
}
.combobild
{
float:right;
border-left:1px solid #747373;
border-right:none;
background: url("../images/dd_img.png") no-repeat;
width:21px;
height:100%;
}
.cdiv
{
/* display:block; macht das hier Sinn??? */
border: 1px solid #000;
height: 24px;
text-align:center;
vertical-align: middle;
line-height: 24px;
}
Gruß
Jens
Hi Gunther,
hier hab ich mal den vollständigen, funktionierenden Code (selbst ausprobiert im IE9 mit dem Versatzfehler).
<!DOCTYPE html>
<html lang="en-us">
<head>
<title>Index</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!--<meta http-equiv="X-UA-Compatible" content="IE=8" />-->
<script type="text/javascript">
function getPosition(obj) {
var topValue = 0, leftValue = 0;
while (obj) {
leftValue += obj.offsetLeft;
topValue += obj.offsetTop;
obj = obj.offsetParent;
}
finalvalue = leftValue + "," + topValue;
return finalvalue;
}
function CreateDiv(obj) {
var pos = getPosition(obj);
var posarray = pos.split(",");
var offset = obj.offsetHeight;
var width = obj.offsetWidth;
/* create & define div container */
var newdiv = document.createElement('div');
var divIdName = 'mDivCBox';
newdiv.setAttribute('id', divIdName);
newdiv.style.position = "absolute";
newdiv.style.top = (parseInt(posarray[1]) + parseInt(1)) + 'px';
newdiv.style.left = (parseInt(posarray[0]) + parseInt(1)) + 'px';
newdiv.style.top = (parseInt(posarray[1])) + 'px';
newdiv.style.left = (parseInt(posarray[0])) + 'px';
newdiv.style.width = (parseInt(width)) + 'px';
newdiv.innerHTML = '<div id="cbox_div"><ul id="cdiv_ul" class="cdiv_ul"><li>first item</li><li>second item</li><li>third item</li><li>four item</li></ul></div>';
/* wrapper div container will contain our new div */
var ni = document.getElementById('wrapper');
ni.appendChild(newdiv);
/* add specific padding-value */
var select_ul = document.getElementById('cdiv_ul');
select_ul.style.marginTop = parseInt(offset) + 'px';
}
</script>
<style type="text/css">
.cbox_div
{
display:block;
background-color:transparent;
}
.cdiv_ul {
background:#aaa;
list-style:none;
border: 1px solid #000;
border-top-width:0px;
border-top:none;
cursor:default;
}
.cdiv_ul li:hover
{
background:#dcdcdc;
}
.cdiv_ul li {padding-left:1px; }
table {
border-collapse: collapse;
/*border:1px solid #000;*/
/*border-right-width:0px;
border-bottom-width:0px;
border-bottom:none;
border-right:none;*/
}
td, th
{
padding:2px;
border: 10px solid #000;
height:60px;
}
thead th {
text-align: center;
background: #787878;
color: #000;
}
.combotext
{
background: url("../images/dd_bk.png") repeat-x;
height:100%;
margin-right:21px;
padding:0px 2px 0px 2px;
text-align:left;
}
.combobild
{
float:right;
border-left:1px solid #747373;
border-right:none;
background: url("../images/dd_img.png") no-repeat;
width:21px;
height:100%;
}
.cdiv
{
/* display:block; macht das hier Sinn??? */
border: 1px solid #000;
height: 24px;
text-align:center;
vertical-align: middle;
line-height: 24px;
}
</style>
</head>
<body>
<div class="wrapper" id="wrapper">
<div class="tablecontainer">
<table>
<thead>
<tr>
<th>Hdr1</th>
<th>Hdr2</th>
<th>Hdr3</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="cdiv" onclick="CreateDiv(this);">
<div class="cbild">
</div>
<div class="ctext">
<span class="as_cui_t">Auswahl:</span>
</div>
</div>
</td>
<td>
<div class="cdiv" onclick="CreateDiv(this);">
<div class="combobild">
</div>
<div class="combotext">
<span class="as_cui_t">Auswahl2:</span>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
مرحبا
Das Problem bei diesem Ansatz ist, dass ich im IE9 einen Pixelversatz dieses "cdiv_ul" erhalte.
Das Problem ist eher, dass du Javascript verwendest, um Elemente zu stylen. Du kannst Javascript verwenden, um den Inhalt an die Stelle einzufügen, wo sie hin soll. Das aussehen sollte aber komplett und ausnahmslos CSS regeln.
So wie du es weiter unten hier im Thread gepostet hast, kann ich dein Problem nicht nachvollziehen, da bei klick viel mehr als nur ein kleiner Versatz existiert.
http://jsfiddle.net/Ytcjw/
Einfacher wäre, den gewünschten Inhalt lediglich in die Tabellenzelle einzufügen, zu der Sie gehört. Dann kannst du es auch viel einfacher stylen und positionieren.
mfg
مرحبا
Das Problem bei diesem Ansatz ist, dass ich im IE9 einen Pixelversatz dieses "cdiv_ul" erhalte.
Das Problem ist eher, dass du Javascript verwendest, um Elemente zu stylen. Du kannst Javascript verwenden, um den Inhalt an die Stelle einzufügen, wo sie hin soll. Das aussehen sollte aber komplett und ausnahmslos CSS regeln.
So wie du es weiter unten hier im Thread gepostet hast, kann ich dein Problem nicht nachvollziehen, da bei klick viel mehr als nur ein kleiner Versatz existiert.
http://jsfiddle.net/Ytcjw/
In diesem Fall tritt ein höherer Versatz auf, weil der Tabellenrahmen entsprechend breiter ist. Würde man hier nur einen Border mit 1px Breite verwenden, ist der Versatz kleiner. Nämlich genau ein Pixel nach links und eines nach oben.
Einfacher wäre, den gewünschten Inhalt lediglich in die Tabellenzelle einzufügen, zu der Sie gehört. Dann kannst du es auch viel einfacher stylen und positionieren.
Ich möchte halt, dass der Inhalt (Listitems) nicht in der Tabelle selbst dargestellt wird, sondern im Prinzip als Popup darüberliegt (wie bei einer Combobox) und die darunterliegenden Tabellenelemente weder durchscheinen noch ausgewählt werden können. Gibt es hierfür ein spezielles CSS-Attribut?
Gruß
Jens
مرحبا
Einfacher wäre, den gewünschten Inhalt lediglich in die Tabellenzelle einzufügen
Ich möchte halt, dass der Inhalt (Listitems) nicht in der Tabelle selbst dargestellt wird, sondern im Prinzip als Popup darüberliegt (wie bei einer Combobox)
Der Inhalt und dessen aussehen sind 2 Unterschiedliche dinge. Inhaltlich gesehen gehört die Liste in die Tabellenzelle, von wo ich auch die Auswahl treffe. Die Liste ist ja bestandteil der Auswahl, die ich treffe, somit gehört sie sowohl Optisch, als auch Technisch in die gleiche Tabellenzelle. Wenn das gegeben ist, kannst du sie aussehen lassen, wie du willst.
Aber auch Technisch hast du da ein Paar Fehler drin. Es sollte maximal eine Liste zu sehen sein, wenn man auf eine Auswahl klickt. Das heisst, bei jeder neuen Auswahl müssen alle anderen Listen wieder verschwinden.
mfg
مرحبا
Einfacher wäre, den gewünschten Inhalt lediglich in die Tabellenzelle einzufügen
Ich möchte halt, dass der Inhalt (Listitems) nicht in der Tabelle selbst dargestellt wird, sondern im Prinzip als Popup darüberliegt (wie bei einer Combobox)
Der Inhalt und dessen aussehen sind 2 Unterschiedliche dinge. Inhaltlich gesehen gehört die Liste in die Tabellenzelle, von wo ich auch die Auswahl treffe. Die Liste ist ja bestandteil der Auswahl, die ich treffe, somit gehört sie sowohl Optisch, als auch Technisch in die gleiche Tabellenzelle. Wenn das gegeben ist, kannst du sie aussehen lassen, wie du willst.
Aber auch Technisch hast du da ein Paar Fehler drin. Es sollte maximal eine Liste zu sehen sein, wenn man auf eine Auswahl klickt. Das heisst, bei jeder neuen Auswahl müssen alle anderen Listen wieder verschwinden.
mfg
ok, ich glaub ich versteh was du meinst.
D.h. pro Liste würde das ungefähr so im html Code aussehen. Alle sind zu Beginn auf display:none gesetzt und werden über das Javascript beim Click-Event angezeigt.
<td>
<div class="cdiv" onclick="CreateDiv(this, 'cbox_ul1');">
<div class="cbild">
</div>
<div class="ctext">
<span class="as_cui_t">Auswahl:</span>
<ul style="display: none;" id="cbox_ul1" class="cbox_ul">
<li>first item</li>
<li>second item</li>
<li>third item</li>
<li>four item</li>
</ul>
</div>
</div>
</td>
function CreateDiv(obj, list) {
var dropbox = document.getElementById(list);
dropbox.style.display = 'block';
}
Was mir allerdings noch nicht klar ist, wie ich es mittels CSS realisiere, dass die Liste nicht in der jeweiligen Tabellenzelle angezeigt wird, sondern als Popup über die darunterliegenden Tabellenzellen hinweg?
Zuvor hab ich das über Javascript realisiert (die Position errechnet und die Liste unter das "cdiv" gesetzt), aber dann hätte ich Inhalt und Aussehen wieder nicht getrennt. Kannst du mir hierzu noch einen Tipp geben?
مرحبا
Was mir allerdings noch nicht klar ist, wie ich es mittels CSS realisiere, dass die Liste nicht in der jeweiligen Tabellenzelle angezeigt wird, sondern als Popup über die darunterliegenden Tabellenzellen hinweg?
Ich habe mal ein kleines Bsp. mit JQuery geschrieben, wie es in etwa mit position:absolute; aussehen kann.
So in etwa würde ich es lösen. Allerdings stellt sich noch die Frage, wie du die Listen zusammenstellst? Werden die Dynamisch irgendwie generiert, oder Datenbanken abgefragt? Wenn es umfangreiche Listen sind, könnte man darüber nachdenken, die Listen nur bei Bedarf ins HTML einzufügen, nicht direkt.
mfg