Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

CSS positioning help 1

Status
Not open for further replies.

OsakaWebbie

Programmer
Feb 11, 2003
628
JP
I'm making my first attempt at using CSS to position things (rather than just set fonts and stuff), so pardon my ignorance. Although I've been trying to learn it on my own with online docs I find, it's getting confusing. What I'm trying to do is take chord symbols and lyrics from a database of songs and lay them out such that each chord lines up above its associated word. My first attempt used code like this:
Code:
<style>.lyrics { font-size: 12pt; margin-bottom: 0; margin-top: 14pt; font-family: Arial, Helvetica;}
.chord { position:relative; left:0px; top:-14pt; font-size: 12pt; color:red; font-weight:bold; font-family: Arial, Helvetica; }
</style></head>
<body><p class=lyrics><span class=chord>D</span>Great in power, <span class=chord>Bm</span>great in glory</p>
<p class=lyrics><span class=chord>G</span>Great in mercy, <span class=chord>Em</span>King of <span class=chord>A</span>heaven</p>
<p class=lyrics><span class=chord>D</span>Great in battle, <span class=chord>Bm</span>great in wonder</p>
<p class=lyrics><span class=chord>G</span>Great in Zion, <span class=chord>Em</span>King over <span class=chord>Asus A</span>all the <span class=chord>D</span>earth</p>
But the horizontal space for each chord is still there between the words - I want the words to have their normal spacing, and the chord's left edge to be lined up with whatever the next character is (after the span, the way I have it now). How can I do that? I assume it has to do with span vs. div, or position types, or something, but... [ponder]
 
Try this:

Code:
<html>
<head>
	<style type="text/css">
		.lyrics { position: relative; font-size: 12pt; margin-bottom: 0; margin-top: 14pt; font-family: Arial, Helvetica;}
		.chord { position:absolute; top:-14pt; font-size: 12pt; color:red; font-weight:bold; font-family: Arial, Helvetica; }
	</style>
</head>

<body>
	<p class=lyrics><span class=chord>D</span>Great in power, <span class=chord>Bm</span>great in glory</p>
	<p class=lyrics><span class=chord>G</span>Great in mercy, <span class=chord>Em</span>King of <span class=chord>A</span>heaven</p>
	<p class=lyrics><span class=chord>D</span>Great in battle, <span class=chord>Bm</span>great in wonder</p>
	<p class=lyrics><span class=chord>G</span>Great in Zion, <span class=chord>Em</span>King over <span class=chord>Asus A</span>all the <span class=chord>D</span>earth</p>
</body>
</html>

Hope this helps,
Dan



[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
Just to explain it a bit more...

I've added a type to your style declaration (you should always have one of these). I've also added the missing html, head, body tags (some open or closing tags were missing altogether).

Re. the CSS... I added a "position: relative" to the lyrics paragraph so that the chords would be positioned relative to them, and removed the left positioning from the chords, so they stayed at their default position.

The last change was to make the chords absolutely positioned, which removed them from the document flow, and thus removed the space they took up.

Dan

[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
Thanks! BTW, the missing head tags and such were because it was only a snippet - those aren't really missing in the real thing. But I did add the type specification - I hadn't heard of that for the style section before.

As for the positioning, yes, that worked beautifully! I don't really understand the role of the position:relative for the lyrics, but without it, the chords get "written" 14 points above the top of the page - it seems to be what makes the vertical alignment work. I have other p's with different classes interspersed on the page (which I didn't include in my snippet for simplicity) - the song title, copyright info, blank lines between stanzas that aren't as big, etc., but apparently I don't need to add the position:relative to them to get the chords to behave - perhaps because it is only the lyrics that have the spans within them? If you have extra energy and feel like explaining to me why position:relative vs. no position on class A affects class B, that would be helpful. But at least it's working - perhaps clarity will come later.

Icing on the cake would be figuring out a way to make sure that overlaps don't happen - if you look at the last line of the song, you'll see that "Asus A" is longer than the lyrics under it, so it overlaps the last "D". In a case like that, it would be sweet to have the second set of lyrics and chord move to the right somewhat (say, 6 points to the right of the right edge of "Asus A"?), but I haven't a clue how to do that, because I don't know how it would even know where the right edge of "Asus A" ended up being. If you know of a way to do that without turning too many cartwheels, that would be great. But if it is too messy, I'll just try to make sure that everyone who inputs chords checks their results, and hopefully the spacing won't be too different on different browsers. This is already way better than most web pages I see that provide chord charts - usually the character spacing of the chords and the lyrics below them are so totally different that you really have to already know the song to figure out what the writer meant.

Thanks again for such a prompt and effective answer.
 
In a case like that, it would be sweet to have the second set of lyrics and chord move to the right somewhat

To be honest, your best bet there is to put some non-breaking spaces in so that the lyrics move over by the right amount.

It might seem like a hack, but it'll sure be easier than creating a specific rule for each chord to be positioned exactly where it needs to be.

Dan

[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
That's kinda what I expected - too hard. The non-breaking spaces is what I meant when I said the responsibility would be on the person inputing the chords into the database - they (which will mostly be me) puts the chords in, and adds extra spaces in the lyrics where needed, and my code detects multiple spaces and converts them to non-breaking when creating the output.

Thanks again for your help.
 
I have other p's [...] - the song title, copyright info, blank lines between stanzas
There are better ways of doing that. Surely the song title is some kind of heading? So use a heading element - <h1>, <h2>, whatever. Blank lines between stanzas/verses can be handled with margins - you just need some kind of block element, something like this:
Code:
<h1>Great in Power</h1>
<div class="verse">
  <p><span>D</span>Great in power, <span>Bm</span>great in glory</p>
  <p><span>G</span>Great in mercy, <span>Em</span>King of <span>A</span>heaven</p>
</div>
<div class="verse">
  <p><span>D</span>Great in battle, <span>Bm</span>great in wonder</p>
  <p><span>G</span>Great in Zion, <span>Em</span>King over <span>Asus A</span>all the <span>D</span>earth</p>
</div>
(I'm not that struck on <p> elements for each line either, but we'll let that pass.) Now you style it like this:
Code:
.verse {margin-bottom: 2em; }

.verse p { position: relative; font-size: 12pt; margin-bottom: 0; margin-top: 14pt; font-family: Arial, Helvetica; white-space: nowrap;}

.verse p span { position:absolute; top:-14pt; color:red; font-weight:bold; }
Note how I've only used a single class, and used the other elements' position below the classed element to identify them - it saves a lot of typing. I've also not repeated properties like [tt]font-family[/tt] in the <span> rule that will be inherited from the <p> anyway.

-- Chris Hunt
Webmaster & Tragedian
Extra Connections Ltd
 
Actually, I didn't fully describe what I'm doing, because I didn't think it was relevent to the discussion. There is no typing involved in laying out the formatted page - it is all generated by PHP code that accesses a database. The "song" table in my database contains various pieces of data, like title, lyrics (plain text, with blank lines interspersed), key, tempo, copyright info, sources, etc. There are other tables that in combination specify what fields will be included in the output, and the CSS attributes for each. So my code just goes through the fields it is supposed to display, puts the CSS in the header, then goes through the songs it is asked to display and names the classes fo the fields as it goes, and all is well. Using different tags would make it significantly more complicated. An additional advantage to using classes for everything is that it makes my Word 2000 templates work - more on that below.

The new code I hope to add will allow the user to include chords in the lyrics field by enclosing them somehow (my current thought is [square brackets] preceding the character they want it lined up above). My code will look for the brackets as it goes through the code, and replace them with the spans discussed previously (and replace multiple spaces with non-breaking ones - it already does that at the beginning of lines, so that the user can indent things, but I'll change it to watch in the middle also).

What I wish I could do, but I haven't figured out yet, is how to construct the HTML/CSS in such a way that one could copy/paste it into Word (or something similar that could allow editing and especially the addition of page breaks at selected points) and have the formatting still be there. All the code except the chords stuff is already written and been in use for months, and I've discovered that Word does not handle CSS well. In Word 2000, if I paste it into a document that already has styles that match the classes in name, the pasted stuff will smoothly adopt the document's existing styles, so I can set up templates ahead of time to paste into. Newer versions of Word don't even do that, and no versions will use the actual CSS definitions, nor will OpenOffice. It may just be a pipe-dream...
 
Hi again! I have an additional question regarding this issue, so I thought I'd keep with the same thread.

First, to review, here are the key points of BRPS's most excellent CSS that I originally incorporated into my dynamic code (example - my actual point sizes are dynamically calculated):
Code:
.lyrics { position:relative; font-size:12pt; margin-bottom:0; margin-top:14pt;}
.chord { position:absolute; top:-12pt; font-size:12pt;}
However, afterwards I discovered a small problem. When I print it, if one of the "chorded" lyrics lines is the first line on the new page, the chords for that line are not visible. Apparently the printed page space does not include the margin-top area right after a page break - under normal circumstances I would like that behavior, but in this case the margin is needed even at the top of a page because the chords are written in that space. So I changed my code to this:
Code:
.lyrics { position:relative; font-size:12pt; margin-bottom:12pt; margin-top:2pt; top:12pt;}
.chord { position:absolute; top:-12pt; font-size:12pt; }
But with this code, up to 12 points of the top margin of the following line is ignored (I might not have noticed it on just the little 2 point spacer on the next line of lyrics, but when the last line of one song crunches up against the title of the next song, which of course has a sizeable top margin, it leaps right out at me). Is there a way to "have my cake and eat it too" - i.e. make it respect the top margin of the following element but allow space for the chords even at the beginning of a page?
 
And... I just discovered that with the new method of pushing everything down, I could have a line at the bottom of a page where only the chords show but not the lyrics (the exact reverse of the original problem - makes sense). And I assume that with the original way, it probably fails to respect any bottom margin of the previous line - the way I set mine up that isn't a noticable difference, but it is clear that this whole behavior is symmetrical - the same problems happen up or down.

Today I also tried line-spacing:24pt instead of margin-top:14pt, because I had also noticed that the occasional long line with chords didn't wrap gracefully with just margins. But even though that causes wrapped lines to still have vertical room for the chords, the chords don't appear there - they still appear above the first line instead (of course causing a mess). And the cutting off of chords at the top of the page still exists - this time, just the top half. To solve that, should I be using the "lyrics" class (which has the position:relative) on a different kind of element than <p>? I ask this because I'm wondering if the -12pt in the position:absolute <span> is relative to the start of its position:relative partner, which is the paragraph, not the spot where the <span> appears.

Anybody out there know how to use position:absolute, margins, and/or line spacing in such a way that page boundaries are respected and chords go where they should?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top