offsetLeft, offsetTop eines fließenden Textabsatzes
Linuchs
- javascript
Moin,
ich möchte Bildelemente per SVG line mit Text verbinden.
Der Text fließt um die Grafik (float:left) und wenn ich offsetLeft abfrage, ergibt das 0, die line geht nach links auf 0 statt nach rechts zum Text.
Was muss man einem floatenden Text zu offsetLeft und offsetTop noch zuschlagen? style.paddingLeft ist leer.
Hallo,
ich möchte Bildelemente per SVG line mit Text verbinden.
Der Text fließt um die Grafik (float:left) und wenn ich offsetLeft abfrage, ergibt das 0, die line geht nach links auf 0 statt nach rechts zum Text.
ja, offsetLeft und offsetTop sind relativ zum Elternelement.
Was muss man einem floatenden Text zu offsetLeft und offsetTop noch zuschlagen?
Die offsets der Vorfahrenelemente. Guckstu hier.
Einen schönen Tag noch
Martin
Hallo Martin,
offsetLeft und offsetTop sind relativ zum Elternelement.
Das weiß ich und lasse die Elternelemente durchlaufen:
let obj_1 = document.getElementById(id1);
let x1 = 0;
let y1 = 0;
while ( obj_1.style.position != "relative" && obj_1.tagName != "body" ) {
x1 += obj_1.offsetLeft; // x-Pixel addieren
y1 += obj_1.offsetTop; // y-Pixel addieren
console.log( "x1=[" +x1 +"] y1=[" +y1 +"]" );
obj_1 = obj_1.parentElement;
}
Die offsets der Vorfahrenelemente
Verstehe ich nicht, HTML-mäßig davor auf gleicher Ebene ist die Grafik. Die wäre wohl ein sibling, aber das Stichwort fehlt in deinem Link.
<div id=canvas_1 class=mb05 style="position:relative; height:10em;">
<div class=li style="position:relative; width:10em; height:10em;">
<img src="img/animiertes_segelboot.gif" style="width:100%;height:100%" alt="Segelschiff" />
<div class=anker id=fock style="left:20%; top:65%"></div>
<div class=anker id=gross style="left:42%; top:50%"></div>
<div class=anker id=besan style="left:65%; top:50%"></div>
</div>
<p><b>Segel eines Dreimasters:</b></p>
<p id=fock_x>Fock</p>
<p id=gross_x>Grosssegel</p>
<p id=besan_x>Besansegel</p>
<div class=clear></div>
<script>
// die transparente SVG-Grafik, die id=canvas_1 mit position:absolute vollflächig bedeckt
</script>
</div>
Hi,
offsetLeft und offsetTop sind relativ zum Elternelement.
Das weiß ich und lasse die Elternelemente durchlaufen:
was aber, wenn ich mir die Markup-Struktur ansehe, vielleicht doch nicht nötig ist.
Die offsets der Vorfahrenelemente
Verstehe ich nicht, HTML-mäßig davor auf gleicher Ebene ist die Grafik. Die wäre wohl ein sibling, aber das Stichwort fehlt in deinem Link.
Stimmt. Aber der Ansatz ist richtig. Sie haben dasselbe Elternelement, also beziehen sich ihre offsetTop und offsetLeft auf denselben Referenzpunkt.
<div id=canvas_1 class=mb05 style="position:relative; height:10em;"> <div class=li style="position:relative; width:10em; height:10em;"> <img src="img/animiertes_segelboot.gif" style="width:100%;height:100%" alt="Segelschiff" /> <div class=anker id=fock style="left:20%; top:65%"></div> <div class=anker id=gross style="left:42%; top:50%"></div> <div class=anker id=besan style="left:65%; top:50%"></div> </div> <p><b>Segel eines Dreimasters:</b></p> <p id=fock_x>Fock</p> <p id=gross_x>Grosssegel</p> <p id=besan_x>Besansegel</p> <div class=clear></div> <script> // die transparente SVG-Grafik, die id=canvas_1 mit position:absolute vollflächig bedeckt </script> </div>
Und die p-Elemente sind gefloatet?
So sollte es NICHT aussehen, die roten Linien müssen nach rechts zu den Texten laufen.
Javascript findet aber nicht dessen Abstand zum linken Rand des SVG
Ja, das Problem ist ein anderes. Im DOM-Inspektor würdest du sehen, dass der linke Rand der p-Elemente tatsächlich ganz links liegt. Denn float verschiebt nicht das ganze Blockelement, sondern nur dessen Inline-Inhalt.
Wie man "sauber" an diesen Versatz kommt, kann ich dir im Moment auch nicht sagen - mir fällt nur ein ganz dreckiger Workaround ein: Setze den Text innerhalb der Absätze in ein span-Element und bestimme dessen offsetLeft.
PS: groß schreibt man auch nach der Rechtschreibdeform noch mit ß. Nur nach einem kurzen Vokal ist ß zu ss geworden (z.B. Fluss, krass).
Einen schönen Tag noch
Martin
Ho,
Denn float verschiebt nicht das ganze Blockelement, sondern nur dessen Inline-Inhalt.
Ja, kann man sehen, wenn das Element border oder background hat.
Setze den Text innerhalb der Absätze in ein span-Element
Habe ich beim Großsegel probiert. Der x-Wert stimmt jetzt. Merkwürdigerweise ist das span-Element 80px tiefer (y) als sein p-Elter. Das wiederum 76px tiefer als der Rand des SVG-Bereichs. Macht zusammen 156px von oben und ist zu tief.
<p style="background:#ccc"><span id=gross_x>Großsegel </span></p>
Hallo Linuchs,
Denn float verschiebt nicht das ganze Blockelement, sondern nur dessen Inline-Inhalt.
Ja, kann man sehen, wenn das Element border oder background hat.
stimmt, auch eine gute Möglichkeit.
Setze den Text innerhalb der Absätze in ein span-Element
Habe ich beim Großsegel probiert. Der x-Wert stimmt jetzt. Merkwürdigerweise ist das span-Element 80px tiefer (y) als sein p-Elter. Das wiederum 76px tiefer als der Rand des SVG-Bereichs. Macht zusammen 156px von oben und ist zu tief.
Huch? Du bist sicher, dass dir nicht irgendwo jemand ein x für ein y vormacht - oder dass du schlicht irgendwo aufgrund eines Tippfehlers die x-Koordinate verwendest, wo es y hätte sein sollen?
Denn sonst wäre ich mit meinem Latein am Ende.
<p style="background:#ccc"><span id=gross_x>Großsegel </span></p>
Da kann man ja nicht gar so viel falsch machen.
Wie sieht es aus, wenn du das mit der span-Bastelei für die anderen beiden Segel auch machst? Eventuell kann man aus dem Verhältnis der falschen y-Offsets irgendeinen Schluss ziehen.
Einen schönen Tag noch
Martin
Hallo Martin,
Wie sieht es aus, wenn du das mit der span-Bastelei für die anderen beiden Segel auch machst?
Habe ich gemacht. Beim Durchlaufen der Elemente und deren parents darf ich den offsetTop NUR DANN berücksichtigen, wenn der tagName != "SPAN" ist.
Klappt beim Firefox 101.0.1, ist aber so unlogisch, dass das bei anderen Browsern vermutlich nicht funktioniert.
function linie( id1, id2, farbe) {
let obj_1 = document.getElementById(id1);
let x1 = 0;
let y1 = 0;
while ( obj_1.style.position != "relative" && obj_1.tagName != "BODY" ) {
x1 += obj_1.offsetLeft; // x-Pixel addieren
if( obj_1.tagName != "SPAN" ) {
y1 += obj_1.offsetTop; // y-Pixel addieren
}
console.log( "x1=[" +x1 +"] y1=[" +y1 +"]" );
obj_1 = obj_1.parentElement;
}
let obj_2 = document.getElementById(id2);
let x2 = 0;
let y2 = 0;
while ( obj_2.style.position != "relative" && obj_2.tagName != "BODY" ) {
x2 += obj_2.offsetLeft; // x-Pixel addieren
if( obj_2.tagName != "SPAN" ) {
y2 += obj_2.offsetTop; // y-Pixel addieren
}
console.log( "x2=[" +x2 +"] y2=[" +y2 +"] tagName=[" +obj_2.tagName +"]" );
obj_2 = obj_2.parentElement;
}
x2 -= 5; // kleiner Abstand zw. line und Text
let h2 = document.getElementById(id2).offsetHeight; // height der Zielmarke
y2 += h2/2;
let line_command = "<line x1='" +x1 +"px', y1='" +y1 +"px', x2='" +x2 +"px', y2='" +y2 +"px' style='stroke:#f00; stroke-width:2px; z-index:99' />";
//console.log( line_command );
document.write( line_command );
}
var line_command = "<svg style='position:absolute; left:0; width:100%; top:0; height:100%;'>";
//console.log( line_command );
document.write( line_command );
linie("gross", "gross_x", "#f00");
linie("besan", "besan_x", "#f00");
linie("fock", "fock_x", "#f00");
var line_command = "</svg>";
document.write( line_command );
n'Abend,
Wie sieht es aus, wenn du das mit der span-Bastelei für die anderen beiden Segel auch machst?
Habe ich gemacht. Beim Durchlaufen der Elemente und deren parents darf ich den offsetTop NUR DANN berücksichtigen, wenn der tagName != "SPAN" ist.
das ist echt seltsam.
Klappt beim Firefox 101.0.1, ist aber so unlogisch, dass das bei anderen Browsern vermutlich nicht funktioniert.
Oder es ist ein ganz seltsamer Spezialfall, der durch um-die-Ecke-Denken irgendwie doch durch die Spec abgedeckt ist. @Gunnar Bittersmann, das wandelnde Spezifikations-Lexikon, wüsste da bestimmt was.
Eventuell hängt es damit zusammen, dass inline-Elemente per se keine definierte Höhe haben? Nee, Quatsch, die ergibt sich ja aus dem Inhalt. Vergiss die Idee.
Das sieht in der Tat vernünftig aus. Kannst du das als minimalisiertes Beispiel irgendwo online stellen? Vielleicht können das ein paar andere Mitleser mit anderen Browsern testen.
Tipp: Setz doch den Startpunkt der Linie noch um die halbe Zeilenhöhe nach unten (oder 1/3), das sieht wahrscheinlich noch besser aus.
Einen schönen Tag noch
Martin
Kannst du das als minimalisiertes Beispiel irgendwo online stellen?
Ja.
Hallo,
Kannst du das als minimalisiertes Beispiel irgendwo online stellen?
Ja.
gut, ich biete schon mal an:
Scheint also kein Zufall zu sein, sondern das hat System.
Bleibt immer noch die Frage: Warum?
Einen schönen Tag noch
Martin
Danke dir für die Tipps und das Testen.
Hallo Linuchs!
Ich habe noch einige Test-Ergebnisse hinzuzufügen:
Au revoir,
Samuel Fiedler
Servus!
Gunnar schrieb an Linuchs:
Ich würd mal sagen, du bist auf dem Holzweg.
Tu alles – Bild, Linien und Texte – ins SVG. Dann brauchst du keinerlei JavaScript-Gedöns. ☞ Beispiel
Ich würde so ein Bild mit Text-Erklärungen als Infografik ansehen.
Da haben wir 2 Tutorials:
Ich würde vorschlagen, die irgendwann zusammenzufassen,
Die lange Einführung in SVG will ich irgendwann als Video auf YouTube stellen. Am Ende eines solchen Tutorials oder Kurses ok, aber nicht am Anfang, wie es jetzt ist.
Herzliche Grüße
Matthias Scharwies
So sollte es NICHT aussehen, die roten Linien müssen nach rechts zu den floatenden Texten laufen.
Javascript findet aber nicht deren Abstand zum linken Rand des SVG
@@Linuchs
ich möchte Bildelemente per SVG line mit Text verbinden.
Der Text fließt um die Grafik (float:left)
Ich würd mal sagen, du bist auf dem Holzweg.
Tu alles – Bild, Linien und Texte – ins SVG. Dann brauchst du keinerlei JavaScript-Gedöns. ☞ Beispiel
🖖 Живіть довго і процвітайте
Hallo Gunnar,
ich möchte Bildelemente per SVG line mit Text verbinden.
Der Text fließt um die Grafik (float:left)
Ich würd mal sagen, du bist auf dem Holzweg.
das kann schon sein.
Tu alles – Bild, Linien und Texte – ins SVG. Dann brauch du keinerlei JavaScript-Gedöns. ☞ Beispiel
Okay, praktischer und wahrscheinlich auch sinnvoller Ansatz. Der beantwortet aber nicht die Frage, warum sich die Browser hier so eigenartig verhalten.
Einen schönen Tag noch
Martin
@@Der Martin
Der beantwortet aber nicht die Frage, warum sich die Browser hier so eigenartig verhalten.
Worum geht’s? Kannst du mir eine Zusammenfassung geben?
Den Code von Linuchs so mit unlesbaren Stringkonkatenationen (wir sprachen drüber) und document.write()
– sorry, den will ich mir nicht ansehen.
🖖 Живіть довго і процвітайте
Hallo,
Der beantwortet aber nicht die Frage, warum sich die Browser hier so eigenartig verhalten.
Worum geht’s? Kannst du mir eine Zusammenfassung geben?
ungefähr ab diesem Beitrag erklärt Linuchs recht gut nachvollziehbar, was er gemacht hat.
Den Code von Linuchs so mit unlesbaren Stringkonkatenationen (wir sprachen drüber) und
document.write()
– sorry, den will ich mir nicht ansehen.
Ich sehe weder das eine noch das andere. Nur dass er - wie leider so oft - seine Informationen erst nach und nach rausrückt.
Konkret: Warum ist bei einer Struktur
<div style="position:relative">
<p style="float:left"><span>Text</span></p>
</div>
die offsetTop-Eigenschaft des span-Elements nicht 0, wie man erwarten würde, sondern hat einen Wert ungleich 0, dessen Herkunft für mich nicht nachvollziehbar ist?
Und nein, ich empfehle keine Inline-Styles; ich wollte hier nur die aus meiner Sicht relevante Information so kompakt wie möglich darstellen.
Einen schönen Tag noch
Martin
Hallo Martin,
Nur dass er - wie leider so oft - seine Informationen erst nach und nach rausrückt.
Dieses Thema ist ja keine JA/NEIN Frage. Gespräche und Meetings laufen oft im Top- Down- Verfahren. Erst die Idee, das Konzept vorstellen. Zu Recht kommt der Hinweis, dass die Lösung mit floatendem Text wohl nicht stabil machbar ist.
Warum sollte ich vor der ersten Reaktion einen Roman schreiben? Die Nachfragen sind wertvoll.
@@Der Martin
Den Code von Linuchs so mit unlesbaren Stringkonkatenationen (wir sprachen drüber) und
document.write()
– sorry, den will ich mir nicht ansehen.Ich sehe weder das eine noch das andere.
Konkret: Warum ist bei einer Struktur
<div style="position:relative"> <p style="float:left"><span>Text</span></p> </div>
die offsetTop-Eigenschaft des span-Elements nicht 0, wie man erwarten würde, sondern hat einen Wert ungleich 0, dessen Herkunft für mich nicht nachvollziehbar ist?
Um das nachvollziehbar zu machen, hab ich mal die Boxen der Elemente sichtbar gemacht (outline
, nicht border
, um nichts zu verfälschen).
Durch das p { float: left }
hat das div
keinen Inhalt, der eine Höhe aufspannen würde.
Zwischen dem div
und dem p
ist der Abstand p { margin-block: 1em }
(Browser-Default). Wenn man den nullt, ist spanElement.offsetTop
um 16 geringer.
Die restlichen 2 kommen daher, dass die Zeilenboxen des span
(Höhe der Schrift) mittig innerhalb der Höhe des Zeilenabstands sitzen (per Browser-Default größer als die Schriftgröße). Setzt man line-height: 1
, sind auch die weg.
🖖 Живіть довго і процвітайте
Moin,
Den Code von Linuchs so mit unlesbaren Stringkonkatenationen (wir sprachen drüber) und
document.write()
– sorry, den will ich mir nicht ansehen.Ich sehe weder das eine noch das andere.
okay, hast recht. So weit runter hatte ich das Script nicht mehr gelesen, sondern mich stattdessen nur noch auf die Offset-Geschichten und mögliche CSS-Stolpersteine konzentriert.
Konkret: Warum ist bei einer Struktur
<div style="position:relative"> <p style="float:left"><span>Text</span></p> </div>
die offsetTop-Eigenschaft des span-Elements nicht 0, wie man erwarten würde, sondern hat einen Wert ungleich 0, dessen Herkunft für mich nicht nachvollziehbar ist?
Um das nachvollziehbar zu machen, hab ich mal die Boxen der Elemente sichtbar gemacht (
outline
, nichtborder
, um nichts zu verfälschen).
Ich sehe nichts. Cloudflare (was codepen.io wohl als Proxy vorgeschaltet hat) lässt mich direkt nacheinander drei Captchas lösen ("I am human") und will mich dann irgendwohin weiterleiten ("Redirecting"). Nach etwa 5min Warten habe ich aufgegeben.
Durch das
p { float: left }
hat dasdiv
keinen Inhalt, der eine Höhe aufspannen würde.
Ja, klar.
Zwischen dem
div
und demp
ist der Abstandp { margin-block: 1em }
(Browser-Default).
margin-block?? Du meinst margin-top?
Wenn man den nullt, ist
spanElement.offsetTop
um 16 geringer.
Verstehe.
Die restlichen 2 kommen daher, dass die Zeilenboxen des
span
(Höhe der Schrift) mittig innerhalb der Höhe des Zeilenabstands sitzen (per Browser-Default größer als die Schriftgröße). Setzt manline-height: 1
, sind auch die weg.
Aber Linuchs hatte eine "Missweisung" von 80, nicht 16 oder 20.
Einen schönen Tag noch
Martin
@@Der Martin
Ich sehe nichts. Cloudflare (was codepen.io wohl als Proxy vorgeschaltet hat) lässt mich direkt nacheinander drei Captchas lösen ("I am human") und will mich dann irgendwohin weiterleiten ("Redirecting"). Nach etwa 5min Warten habe ich aufgegeben.
Hm, ist mir bei CodePen noch nie untergekommen. So sollte es aussehen:
margin-block?? Du meinst margin-top?
Nein, ich meine margin-block
– den Abstand oben und unten (bei horizontaler Schreibrichtung).
Aber da der untere Abstand hier keine Rolle spielt, kannst du auch margin-top
nullen.
Aber Linuchs hatte eine "Missweisung" von 80, nicht 16 oder 20.
Hatte er auch div { position: relative }
gesetzt? Oder noch andere Inhalte über dem span
?
🖖 Живіть довго і процвітайте
Hallo,
@@Der Martin
Ich sehe nichts. Cloudflare (was codepen.io wohl als Proxy vorgeschaltet hat) lässt mich direkt nacheinander drei Captchas lösen ("I am human") und will mich dann irgendwohin weiterleiten ("Redirecting"). Nach etwa 5min Warten habe ich aufgegeben.
Hm, ist mir bei CodePen noch nie untergekommen.
mir bisher auch nicht. Jetzt geht's wieder. War wohl nur 'ne Verdauungsstörung.
So sollte es aussehen:
Gut. Abgesehen von der anderen Anordnung der Boxen auf dem Desktop-Bildschirm.
margin-block?? Du meinst margin-top?
Nein, ich meine
margin-block
– den Abstand oben und unten (bei horizontaler Schreibrichtung).
Ah, das kannte ich noch nicht.
Aber Linuchs hatte eine "Missweisung" von 80, nicht 16 oder 20.
Hatte er auch
div { position: relative }
gesetzt? Oder noch andere Inhalte über demspan
?
Wozu verlinke ich denn direkt seine Beiträge? 😉
Einen schönen Tag noch
Martin
@@Der Martin
Gut. Abgesehen von der anderen Anordnung der Boxen auf dem Desktop-Bildschirm.
Und von dem dark theme vermutlich.
Die Anordnung der Boxen lässt sich über den -Button oben regeln.
Nein, ich meine
margin-block
– den Abstand oben und unten (bei horizontaler Schreibrichtung).Ah, das kannte ich noch nicht.
Zu logischen vs. physischen Eigenschaften und Werten hab ich auch einen Vortrag in der Mache. Die Titelfolie hab ich schon:
Wozu verlinke ich denn direkt seine Beiträge? 😉
Aber doch nicht, dass ich mir alle nötigen Informationen selbst zusammensuche? 😜
🖖 Живіть довго і процвітайте
Hallo Gunnar,
mein Beispiel ist wohl wirklich ein Holzweg mit dem floatenden Text um eine Grafik. Wusste nicht, dass man die Position der Texte mit Javascript nicht greifen kann.
Folgendes Beispiel habe ich vor Jahren mit flex und zwei nebeneinander liegenden divs gemacht. Jeder District kann textlich erweitert werden, die anderen rutschen dann korrekt nach unten:
Ich werde mein Beispiel auf zwei nebeneinander liegende divs ändern.
Hi there,
ich möchte Bildelemente per SVG line mit Text verbinden.
Der Text fließt um die Grafik (float:left)
Ich würd mal sagen, du bist auf dem Holzweg.
Tu alles – Bild, Linien und Texte – ins SVG. Dann brauchst du keinerlei JavaScript-Gedöns. ☞ Beispiel
Ja, in Deinem Beispiel ist das überzeugend. Die Frage stellt sich halt, was passiert, wenn die Linie nicht zu einem kurzen Text wie "letter g" geht sondern zu irgendeinem anderen HTML-Element mit irgendeinem beliebigen Inhalt. Da wird dann eine "Nur-SVG-Lösung" vermutlich nicht die beste Lösung sein (keine Ahnung, ob Suchmaschinen den Inhalt von SVG-Elementen parsen, bspw.) und insoferne kann der gesuchte Weg von Linuchs doch ein ganz normaler, auch ohne Holz sein...
@@klawischnigg
Die Frage stellt sich halt, was passiert, wenn die Linie nicht zu einem kurzen Text wie "letter g" geht sondern zu irgendeinem anderen HTML-Element mit irgendeinem beliebigen Inhalt. Da wird dann eine "Nur-SVG-Lösung" vermutlich nicht die beste Lösung sein (keine Ahnung, ob Suchmaschinen den Inhalt von SVG-Elementen parsen, bspw.) und insoferne kann der gesuchte Weg von Linuchs doch ein ganz normaler, auch ohne Holz sein...
Ja. Mit der Anforderung „Text kann auch länger sein und sich immer wieder mal ändern“ kam Linuchs natürlich in „bester“ Linuchs-Manier erst später …
🖖 Живіть довго і процвітайте