Customize Superscript as in Songbook - html

I want to do a songbook in HTML, something like
I wonder whether this can be easily achieved by some css trick on the <sup> tag (or similar)
<sup>F</sup>Yesterday <sup>Em7</sup> all my <sup>A7</sup> troubles seemed so <sup>Dm</sup>far away <sup>Dm/C</sup>
<sup>Bb</sup>now I <sup>C7</sup>need a place to <sup>F</sup>hide away <sup>C</sup>oh <sup>Dm</sup>I <sup>G7</sup>believe in <sup>Bb</sup>yes<sup>F</sup>terday
Now two questions:
Which adjustments should be added to the <sup> tag for this to work? At least it must be higher and must behave as if it occupied no space at all (for example, 'yesterday' should not be divided)
Is there a better trick than using the <sup> tag?
Thanks for all your comments

Rather than a sup, I'd suggest a span with a data-attribute in a pseudo-element.
The pseudo-element can then be positioned as you desire and provided a suitable line-height is used this all works out fairly dynamically.
Size everything in em and:
p {
line-height: 2em;
margin: 1em;
}
span {
position: relative;
}
span::after {
content: attr(data-note);
display: inline-block;
position: absolute;
top: -2em;
color: red;
font-size: .75em;
padding-right: 1em;
}
<p>
<span data-note="F"></span>Yesterday <span data-note="Em7"></span>all my <span data-note="Dm"></span>troubles seemed so <span data-note="A7"></span>far away
<br><span data-note="Bb"></span> <span data-note="Bb"></span>now I <span data-note="C7"></span>need to find a place to <span data-note="F"></span>hide away <span data-note="C"></span>oh <span data-note="Dm"></span>I beli<span data-note="G7"></span>eve in yes<span data-note="Bb"></span>terday
</p>
As the span's are empty screenreaders shouldn't have a problem with them (although I'm unsure as whether the content is read by screenreaders.

Related

Styling quotation marks

I have run into and issue when styling quotes. So what I'm trying to do is pull the quotation marks down a bit relative to the text so that it lines up well. I played around with relative and absolute positioning but could not figure it out. This program will become a random quote generator and the position of the end quote has to be such that it lines up the same way relative to the text if it there is a quote that takes up several lines.
body {
background-color: rgb(44, 62, 80);
}
.quoteMachine {
margin: 100px auto 0 auto;
padding: 40px 60px;
max-width: 600px;
min-height: 225px;
border-radius: 5px;
background-color: white;
}
.theQuote {
text-align: center;
font-size: 30px;
color: rgb(44, 62, 80);
}
.quotetationMarks {
font-size: 60px;
font-weight: 600;
}
.quoteAuthor {
text-align: right;
font-size: 20px;
color: rgb(44, 62, 80);
}
.twitterButton {}
<div class="quoteMachine">
<div class="theQuote">
<blockquote><span class="quotetationMarks">“</span > They call me Mister Tiibs <span class="quotetationMarks">”<span></blockquote>
</div>
<div class="quoteAuthor">
- hello
</div>
<button class="twitterButton"></button>
<button class="newQuoteButton"></button>
</div>
Since the spans are inline elements, you could add vertical-align: middle; to .quotetationMarks and that would move them down toward the middle of the rest of the string.
Alternatively, you could add position: relative; top: 10px; if you need more precise control.
Maybe adding vertical-align: sub; to .quotetationMarks is what you are looking for?
You can also use fontawesome, that's always a good option. -> http://fontawesome.io/icon/quote-right/
Edit: While vertical-align: middle; is a very valid and elegant approach, sometimes you've got a very specific position in mind for the quotation marks. If you need to match a mockup to pixel perfection, this approach grants you the flexibility.
You might get some mileage out of using pseudo-elements to render the quotes, and relative/absolute positioning to get them "just so".
This is especially important to help position them across line breaks. (I've edited my example to force a line break, in order to illustrate the robustness of this approach.)
From MDN:
Just like pseudo-classes, pseudo-elements are added to selectors but instead of describing a special state, they allow you to style certain parts of a document. For example, the ::first-line pseudo-element targets only the first line of an element specified by the selector.
And specifically for the ::before pseudo element:
::before creates a pseudo-element that is the first child of the element matched. It is often used to add cosmetic content to an element by using the content property. This element is inline by default.
These quotes you're styling are cosmetic content, so I think that this is a great use-case for the ::before pseudo element.
I've forked your codepen here: http://codepen.io/cam5/pen/kkxpbX, but here are the relevant parts
<!-- quote HTML -->
<blockquote>
<span class="quotationMark quotationMark--left"></span >
They call me…<br /> Mister Tiibs
<span class="quotationMark quotationMark--right"></span >
</blockquote>
and the CSS:
/* quote css */
.quotationMark {
position: relative;
}
.quotationMark--left::before,
.quotationMark--right::before {
font-size: 60px;
font-weight: 600;
position: absolute;
top: -15px;
}
.quotationMark--left::before {
content:"\201C";
left: -45px;
}
.quotationMark--right::before {
content:"\201D";
right: -45px;
}
This CSS Tricks resource is great when you're trying to locate the ISO for putting a certain glyph into a CSS content rule: https://css-tricks.com/snippets/html/glyphs/
Setting the parent element, the .quotationMark to display: relative; will mean that the top, right, left values passed to the children (the pseudo-elements) of it bearing the position: absolute; property are calculated relative to their parent.

Positioned spans being clipped in Chrome

I'm trying to position a label above inline sections containing a set of spans, but I'm finding that Chrome appears to be clipping the labels weirdly. Take a look at these two screenshots:
In Firefox:
In Chrome:
If you look at the screenshot from Chrome, you can see the labels are being clipped based on the start point of the next label. The desired result would be the same as the Firefox screenshot, where the labels go all the way up to the end of the line.
Here is the code used for these two examples:
.section {
position: relative;
border-right: solid 1px #000;
}
.section-title {
display: inline-block;
position: absolute;
top: -10px;
left: 5px;
right: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-family: sans-serif;
font-size: 0.8em;
}
.pieces {
font-family: monospace;
}
.pieces span {
display: inline-block;
padding: 10px 5px 0 5px;
}
<span class="section">
<span class="section-title">Really long title is really long</span>
<span class="pieces">
<span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span>
</span>
</span>
<span class="section">
<span class="section-title">Really long title is really long</span>
<span class="pieces">
<span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span>
</span>
</span>
<span class="section">
<span class="section-title">Really long title is really long</span>
<span class="pieces">
<span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span>
</span>
</span>
<span class="section">
<span class="section-title">Really long title is really long</span>
<span class="pieces">
<span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span><span>00</span>
</span>
</span>
Is this a known Chrome/WebKit bug? Is it possible to fix without drastically modifying the HTML?
It's not a bug in Chrome... it's a problem with the code, which Chrome interpreted in a way that it deemed logical.
Firstly, note that your .section-title is absolutely positioned and set with both left and right. This means:
It automatically becomes display:block.
It tries to be 5px from left, and 5px from right boundary of the parent.
Then, note that your parent .section is an inline element, since all span tags are inline by default. Therefore, it takes the width that it requires to accommodate its children. Your long line of 00 overflows to the next row, and hence the "right boundary" also overflows to the next row.
Being an obedient element, .section-title tries its best to stay 5px away from that right border, which is now very much nearer. Hence, the text-overflow: ellipsis correctly kicks in.
To fix your code:
Having display: inline-block for an absolutely positioned element is useless. It confuses. Take it out.
Don't set it to right:5px. Take it out. (this is the only fix that matters, actually).
Please do feedback to the author who wrote this HTML that the HTML vocabulary is more than just <span>. It's ridiculous to use only <span> for everything when more logical tags like <section>, <h1>-<h6> will fit the content better.

How to make the last span element inside a paragraph no-wrap?

I have a paragraph surrounded by decorative quotes. The layout is fluid, and for some width, only the decorative quote is wrapping, which I want to avoid.
Screenshot :
Code : http://jsfiddle.net/84EDh/1/ (Note: not tested outside of Chrome)
<p>
<span class="bigchar ldquo"></span>
Begin paragraph [...paragraph content...] end paragraph.
<span class="bigchar rdquo"></span>
</p>
css:
p { position: relative; }
.bigchar {
display: inline-block;
width: 20px;
}
.bigchar:after {
color: #aaa;
font-size: 50px;
position: absolute;
}
.ldquo:after {
content: '“';
top: -10px;
}
.rdquo:after {
content: '”';
bottom: -30px;
}
Possible solution:
Wrap the last word with the closing span in another span
[...paragraph content...] end
<span class="nowrap">
paragraph.
<span class="bigchar rdquo"></span>
</span>
Question:
Is there a more elegant way to achieve the no-wrapping of the last span of the paragraph ?
This is not very semantic, nor easy to achieve because, as you would expect, the content of the paragraph is dynamic, hence not easy to split at the template level.
Edit: css added
Instead of using a span, it's better to use a q, because that's what q elements were designed for!
So the HTML becomes
<p><q class="bigchar">This text is surrounded by quotes. I want
the text to wrap according it's parent width. This is no problem,
it's the default behaviour. However, I would like to avoid the
last span, containing a decoration quote, to wrap.</q></p>
with the CSS
q.bigchar::before {content:'\201C'; font-size:2em; line-height:0;
position:relative; top:.3em; margin-right:.13em;}
q.bigchar::after {content:'\201D'; font-size:2em; line-height:0;
position:relative; top:.3em; margin-left:.13em;}
resulting in this fiddle.
No extra markup is needed.
Note that since I leave the p alone, you can put all kinds of styles (like text-indent) on it, and it will behave as it should.
What about nesting span inside other span?
What we achieve this way is rdquo acting just as a regular text (that means: if you put either no space or non-breaking space between rdquo and last word, it's not going to break into two lines).
Demo here: http://jsfiddle.net/HFE9T/1/
Instead of using additional span elements, try using :before and :after on paragraph like this:
p:after {
color: #aaa;
font-size: 50px;
position: absolute;
content: '”';
bottom: -30px;
}
p:before {
color: #aaa;
font-size: 50px;
position: absolute;
content: '“';
top: -10px;
}
Updated fiddle here
Here is the final markup and CSS to achieve the expected behaviour, inspired by Michal Rybak but without the compromises (except the two span in the markup) :
HTML :
<p>
<span class="quote" attr-char="“"> </span>
Paragraph content Here.
Note the no-line-break here.<span class="quote" attr-char="”"> </span>
</p>
The attr-char attribute is pretty handy to be able to change the quote characters for different languages as with the q element (somewhat)
CSS :
p .quote {
position: relative;
margin-right: 30px; /* Indent text at paragraph beginning */
}
p .quote:before {
position: absolute;
top: 10px;
line-height: 20px;
font-size: 50px;
content: attr(attr-char); /* Take the character from markup */
}
p .quote:last-child:before {
margin-left: 10px; /* Give the closing quote some space */
}
Fiddle :
http://jsfiddle.net/HFE9T/4/
You can add a non-breaking spaces \00a0 before and after the quotes:
<style>
element:before {content: "“\00a0";}
element:after {content: "\00a0”";}
</style>
And then work your way around with negatives margins if you don’t want those space to show.

Inline-Block inside position:absolute element

My question is simple: what happens to inline-block elements inside of absolutely positioned elements? I have a little example to illustrate what I mean. It's hard to explain otherwise. The question is why the .icon inside of the .tag is not positioned like the previous .icon (that is, inline and to the right of the text)
The code below can be viewed # http://jsbin.com/itole4/5
<html>
<head>
<style>
.field { position: relative; border: 2px solid black;}
.tag { position: absolute; left: 100%; top: -2px; background: black; color: white;}
.icon { width:16px;height:16px; display: inline-block; background: gray; text-indent: -999px;}
</style>
</head>
<body>
<a>Some text <span class='icon'>X</span> </a>
<h2>
<span class='field'>Some Text<span class='tag'> tag<span class='icon'>x</span></span></span>
</h2>
<h2>
<span class='field'>Some Text</span>
</h2>
</body>
</html>
Actually, the icon is acting exactly the same. To test, try setting a's style to
display: inline-block; width: 50px;
When you make a tag position: absolute, it causes the tag to no longer have an automatic width of 100% of its parent, but rather to have the minimal width it can take according to heuristics within the browser (browser-dependent). The inline block acts like "inline", like an image, and is thus wrapped to the next line at the first chance (which is right after the word "tag").
So the short answer is: the icon is acting the same, but the block containing it is not.
In order to force the icon on the same line, as on the first line, you can add white-space: pre;. See: http://jsbin.com/itole4/6 (also see comment below)
because the .field has position relative and if you will add the .icon with style : position:absolute;top:0px; inside of the .field the .icon will be added on '0px' on top of the .field not of body
I can't explain it better in English >.<, i hope you can understand
it's not the positioning - it's the element containing the "icon" class..in one you've got a plain inline a the other a nested setup where the parent is an block level h2 this means your "inline-bock" has different line-heights and vertical alignment

HTML: can I place subscript text right under the superscript?

I have a word, which has both superscript and subscript. Now I render it like this word<sub>1</sub><sup>2</sup>
And get the following: word12.
How can I put the subscript exactly under the superscript?
Here's a clean solution. Create two CSS classes:
.nobr {
white-space: nowrap;
}
.supsub {
display: inline-block;
margin: -9em 0;
vertical-align: -0.55em;
line-height: 1.35em;
font-size: 70%;
text-align: left;
}
You might already have the "nobr" class as a <nobr> replacement. Now to express the molecular formula for sulfate, use the "supsub" class as follows:
<span class="nobr">SO<span class="supsub">2-<br />4</span></span>
That is, enclose your superscript/subscript within the "supsub" class, and put a <br /> between them. If you like your superscripts/subscripts a bit larger or smaller, then adjust the font size and then tinker with the vertical-align and line-height. The -9em in the margin setting is to keep the superscripts/subscripts from adding to the height of the line containing them; any big value will do.
There are many ways you can do this with CSS, and each has their pros and cons. One way would be to use relative positioning. A quick example might work like this:
<span class="fraction">
<span class="numerator">3</span>
<span class="denominator">4</span>
</span>
And the CSS to go along with this:
span.fraction { }
/* Or child selector (>) if you don't care about IE6 */
span.fraction span.numerator {
position:relative;
top:-0.5em;
}
span.fraction span.denominator {
position:relative;
top:0.5em;
left:-0.5em; /* This will vary with font... */
}
This particular example would work better if you use a monospaced font.
Use the CSS table style (except for IE8 and below). HTML:
<span class="over-under">
<span class="over">sup</span>
<span class="under">sub</span>
</span>
CSS:
span.over-under {
position: relative;
top: 1em;
display: inline-block;
}
span.over-under > .over {
display: table-row;
}
span.over-under > .under {
display: table-row;
}
Fiddle: https://jsfiddle.net/FredLoney/Loxxv769/4/
Besides being simpler than relative position tweaks, this solution avoids layout distortions that arise from those alternatives. See, e.g., https://jsfiddle.net/FredLoney/da89nyk2/1/.
Well, you can't do that with plain vanilla HTML. Like it's been mentioned, use CSS. But you will want some positioning aswell!