I have a block of text where I want to group words up as pairs so the two words do not break. There is an unintended consequence where when you have two <span></span> tags in a row he whole line turns into nowrap.
Example: <div><span style="white-space: nowrap;">...</span><span style="white-space: nowrap;">...</span></div>
Code below is baseline: The result will wrap at any " "(space) or "-" that the container has.
(NOTE: This example is meant to be on a responsive web-page.)
<div class="block-of-text" style="max-width: 550px">
One-two Buckle-my-shoe, Three-four Shut-the-door,
Five-six Pick-up-sticks, Seven-eight Lay-them-straight,
Nine-ten Do-it-again.
</div>
The Result of the Base line will look something like this.
|--------------- My Web Page ---------------| (550px)
| |
| One-two Buckle-my-shoe, Three-four Shut- |
| the-door, Five-six Pick-up-sticks, Seven-|
| eight Lay-them-straight, Nine-ten Do-it- |
| again. |
| |
|-------------------------------------------|
I want to make sure any hyphenated word surrounded by <span class="nowrap">...</span> stays on the same line.
Below is my attempt. (NOTE: I have One-two not surrounded by nowrap on purpose to show how it will not be included in the result.)
<style>
.nowrap {
white-space: nowrap;
}
</style>
<div class="block-of-text" style="max-width: 550px">
One-two <span class="nowrap">Buckle-my-shoe, </span>
<span class="nowrap">Three-four </span><span class="nowrap">Shut-the-door, </span>
<span class="nowrap">Five-six </span><span class="nowrap">Pick-up-sticks, </span>
<span class="nowrap">Seven-eight </span><span class="nowrap">Lay-them-straight, </span>
<span class="nowrap">Nine-ten </span><span class="nowrap">Do-it-again.</span>
</div>
My unintended result looks something like this and is NOT what I want. The <span> tags are acting as one giant nowrap.
|--------------- My Web Page ---------------| (550px)
| |
| One-two |
| Buckle-my-shoe, Three-four Shut-the-door, Five-six Pick-up-sticks, Seven-eight Lay-them-straight, Nine-ten Do-it-again.
| |
|-------------------------------------------|
What I want to have happen:
|--------------- My Web Page ---------------| (550px)
| |
| One-two Buckle-my-shoe, Three-four |
| Shut-the-door, Five-six Pick-up-sticks, |
| Seven-eight Lay-them-straight, Nine-ten |
| Do-it-again. |
| |
|-------------------------------------------|
SOLUTION
Thanks to everyone and especially #Kravimir for helping find the solution:
It works when adding style display: inline-block;, while having all spans on the same line, and adding spacing with inside the span.
<style>
.nowrap {
white-space: nowrap;
display: inline-block;
}
</style>
<div class="block-of-text" style="max-width: 550px; border: solid 1px red">
One-two <span class="nowrap">Buckle-my-shoe, </span><span class="nowrap">Three-four </span><span class="nowrap">Shut-the-door, </span><span class="nowrap">Five-six </span><span class="nowrap">Pick-up-sticks, </span><span class="nowrap">Seven-eight </span><span class="nowrap">Lay-them-straight, </span><span class="nowrap">Nine-ten </span><span class="nowrap">Do-it-again.</span>
</div>
Additional info on solution: If you put " "(space) or outside of the span it does not work as intended or you get 2 spaces between spans. Also the whitespace at the end of a line is not observed when the <span> tag is on a new line.
TLDR; Solution was edited in above.
Use display: inline-block.
span.nowrap {
white-space: nowrap;
display: inline-block;
}
<div class="block-of-text" style="max-width: 550px">
One-two <span class="nowrap">Buckle-my-shoe,</span>
<span class="nowrap">Three-four</span> <span class="nowrap">Shut-the-door,</span>
<span class="nowrap">Five-six</span> <span class="nowrap">Pick-up-sticks,</span>
<span class="nowrap">Seven-eight</span> <span class="nowrap">Lay-them-straight,</span>
<span class="nowrap">Nine-ten</span> <span class="nowrap">Do-it-again.</span>
</div>
This occurs because, without spaces between the spans, they act as characters in a single word. You need to put spaces between the spans, not inside them.
.nowrap {
white-space: nowrap;
}
<div class="block-of-text" style="max-width: 550px; border: 1px solid red">
One-two <span class="nowrap">Buckle-my-shoe,</span> <span class="nowrap">Three-four</span> <span class="nowrap">Shut-the-door,</span> <span class="nowrap">Five-six</span> <span class="nowrap">Pick-up-sticks,</span> <span class="nowrap">Seven-eight</span> <span class="nowrap">Lay-them-straight,</span> <span class="nowrap">Nine-ten</span> <span class="nowrap">Do-it-again.</span>
</div>
You are not closing span so
.nowrap {
white-space: nowrap;
}
<div class="block-of-text" style="max-width: 550px">
One-two <span class="nowrap">Buckle-my-shoe, </span>
<span class="nowrap">Three-four </span><span class="nowrap">Shut-the-door, </span>
<span class="nowrap">Five-six </span><span class="nowrap">Pick-up-sticks, </span>
<span class="nowrap">Seven-eight </span><span class="nowrap">Lay-them-straight, </span>
<span class="nowrap">Nine-ten </span><span class="nowrap">Do-it-again.</span>
</div>
Related
I want to have each text have a different color so I used a multiple span classes to set the color in css. I also want the text to have line breaks so I used div. This fiddle shows the result I want but the div tags used for the line breaks creates a large gap. Is there another way to have line breaks with multiple span classes?
Fiddle: https://jsfiddle.net/nh7vswco/
<pre id="info">
<div class = "fact-card">
<span class="animal"> animal</span>
<span class="colon"> : </span>
<span class="animal-name">tiger</span>
<span class="comma">,</span>
</div>
<div class = "fact-card">
<span class="animal"> species</span>
<span class="colon"> : </span>
<span class="animal-name">Mammal</span>
<span class="comma">,</span>
</div>
<div class = "fact-card">
<span class="animal"> type</span>
<span class="colon"> : </span>
<span class="animal-name">carnivore</span>
<span class="comma">,</span>
</div>
Result:
Each word and colon should have a different color.
animal : tiger,
species : mammal,
type : carnivore,
This fiddle has the result Fiddle: https://jsfiddle.net/nh7vswco/ but I would like to remove the gaps from the div tag.
1- There are many ways to make a line break like so: <br> or line-break CSS property.
2- To remove the gaps from the div tag. we can use the line-height: 0%;
<style>#info {
text-align: center;
padding-left: 20px;
padding-right: 20px;
}
.colon {
color: #cc7832;
}
.animal-name {
color: #2587be;
}
.animal {
color:#9473a5;
display: block;
}
.fact-card{
display: flex;
line-height: 0%;
}
.span {
font-family: Arial;
}
<pre id="info">
<div class = "fact-card">
<span class="animal"> animal</span>
<span class="colon"> : </span>
<span class="animal-name">tiger</span>
<span class="comma">,</span>
</div>
<div class = "fact-card">
<span class="animal"> species</span>
<span class="colon"> : </span>
<span class="animal-name">Mammal</span>
<span class="comma">,</span>
</div>
<div class = "fact-card">
<span class="animal"> type</span>
<span class="colon"> : </span>
<span class="animal-name">carnivore</span>
<span class="comma">,</span>
</div>
</pre>
This issue is actually due to the side-effects of using the pre tag. The additional spacing you have in between the divs inside your pre tag are being interpreted as line breaks as that is what pre is meant to do. If you do not want this extra spacing, eliminate the extra white space (line breaks, spaces, etc.) you have.
<pre id="info"><div class = "fact-card">
<span class="animal"> animal</span>
<span class="colon"> : </span>
<span class="animal-name">tiger</span>
<span class="comma">,</span>
</div><div class = "fact-card">
<span class="animal"> species</span>
<span class="colon"> : </span>
<span class="animal-name">Mammal</span>
<span class="comma">,</span>
</div><div class = "fact-card">
<span class="animal"> type</span>
<span class="colon"> : </span>
<span class="animal-name">carnivore</span>
<span class="comma">,</span>
</div>
I am looking for a HTML-based representation for song texts with chords above the syllables, in the following fashion:
Am C D F
There is a house in New Orleans
Now, I don't care how exactly the HTML looks like in the end, but there is an important constraint: the purpose is not only display, but also storage in a semantically meaningful representation. Specifically, the songs are converted from a LaTeX-based syntax and should be recoverable in their original form, as well as being readable in HTML and easily processable. So no fancy structure just for the purpose of presentation, and no JavaScript (yes, I have looked at how UltimateGuitar does it, that is exactly not what I want). I need every element to have a direct correspondence to some logical part, as in the original format.
On the other hand, this gives me a hard time designing a CSS that presents the stacked chords. The basic rule is that you have "boxes" consisting of a text part and a chord part, and the width of the whole box should be the maximum of either parts, which each can consist of arbitrarily long text:
Am Cmaj7/G Am G F Am/G E7 F#sus4 A
longstuff short multichord more end. e - ternal
The boxing structure is known in advance, so you can assume it as given:
((Am) (longstuff))
((Cmaj7/G) (short))
((Am G) (multichord))
((F Am/G) (more))
end.
((E7) ())
((F#sus4 A) (e))ternal
Note that in the last box, the word is hyphenated to compensate for the two chords on the first syllable. I fear this makes it very hard for CSS, so it might be represented in a slightly different way, e.g.
((F#sus4 A) (e) (ternal))
You can come up with alternatives, as long as they still have concise semantic meaning. Here is what I have come up with so far:
.verse {
line-height: 3rem;
font-family: serif;
}
.cbox {
border: 1px solid;
}
.chord {
position: absolute;
transform: translate(0, -1.1rem);
font-weight: bold;
font-family: monospace;
user-select: none;
font-size: large;
}
<p class="verse">
Test
<span class="cbox"><span class="chord">Abc</span>X</span>
<span class="cbox"><span class="chord">Abc</span>Xyzwv</span>
<span class="cbox"><span class="chord">Abc</span>Xyzw</span>abc
sd
<br/>
Test
<span class="cbox"><span class="chord">Abc De</span>Xy</span>zwv
sd
<br/>
<span class="cbox"><span class="chord">Ab</span>xyz</span>
<span class="cbox"><span class="chord">Abc#sus4/C</span>Zyzw xyz</span>
<span class="cbox"><span class="chord">Am</span>xyzw</span>
<br/>
<span class="cbox"><span class="chord">D</span>xyz</span>
<span class="cbox""><span class="chord">E7</span></span>
two
<span class="cbox"><span class="chord">E7</span>th</span>ree
</p>
The sizes and borders are chosen for debugging. As you can see, the width of the top (chord) part is not taken into account (because position: absolute prevents that).
I have tried some other variants, including this one: <span class="cbox" data-w="2" data-c="Am">longstuff</span>, where data-w is the number of letters in the chord name to be used in the min-width of the span, and data-c being put into a before pseudo-element, but I still didn't succeed at getting the width right.
For the hyphenation issue, I have no idea at all.
And I will likely be using XHTML, although I guess this won't make much of a difference.
I'd suggest using CSS grid to help keep things from overlapping.
You can specify a grid template of 1 column and 2 rows, and then use classes to tell the content which row it should fit into. The grid will fill nicely and create implicit new columns as needed. It even will work if you have a series of chords or text in a row, without needing to wrap chord/text pairs in a wrapping element.
For the hyphenation, if possible, I'd add an additional class to syllables that need hyphenation, and then create the hyphens using a pseudo element in CSS.
Here's a working example. Hope this is helpful. This was a fun challenge.
.line {
display: grid;
justify-content: start;
grid-template-columns: auto;
grid-template-rows: auto auto;
grid-auto-flow: column;
gap: 0 0.6em;
margin-bottom: 1em;
}
.chord {
grid-row-start: 1;
}
.text {
grid-row-start: 2;
}
.hyphenated:after {
content: ' - '
}
<span class="line">
<span class="chord">Am</span>
<span class="text">longstuff</span>
<span class="chord">Cmaj7/G</span>
<span class="text">short</span>
<span class="chord">Am G</span>
<span class="text">multichord</span>
<span class="chord">F Am/G</span>
<span class="text">more</span>
<span class="text">end.</span>
<span class="chord">E7</span>
<span class="chord">F#sus4 A</span>
<span class="text hyphenated">e</span>
<span class="text">ternal</span>
</span>
<hr>
<p class="verse">
<span class="line">
<span class="chord">C</span>
<span class="text">Frosty the</span>
<span class="chord">C7</span>
<span class="text">snowman</span>
</span>
<span class="line">
<span class="text">was a</span>
<span class="chord">F</span>
<span class="text">jolly</span>
<span class="chord">F#dim</span>
<span class="text">happy</span>
<span class="chord">C</span>
<span class="text">soul</span>
<span class="chord">C7</span>
</span>
<span class="line">
<span class="text">with a</span>
<span class="chord">F</span>
<span class="text">corncob</span>
<span class="chord">F#dim</span>
<span class="text">pipe and a</span>
<span class="chord">C</span>
<span class="text">button</span>
<span class="chord">A7</span>
<span class="text">nose</span>
</span>
<span class="line">
<span class="text">and two</span>
<span class="chord">Dm7</span>
<span class="text">eyes made</span>
<span class="chord">G7</span>
<span class="text">out of</span>
<span class="chord">C</span>
<span class="text">coal.</span>
<span class="chord">C7</span>
</span>
</p>
Edit: A downside to the above approach is that the content is hard to understand if unstyled.
A more semantic approach could be to combine CSS Grid with content defined in custom data-* attributes and CSS variable fallbacks. This way the chords stay stored as attributes rather than marked-up text interspersed with the lyrics.
.verse {
line-height: 2;
}
.lyric {
display: inline-grid;
grid-template-columns: auto;
grid-template-rows: auto auto;
line-height: 1;
}
.lyric[data-chord] {
--chord: attr(data-chord);
}
.lyric:before {
content: var(--chord, '\00a0');
}
<p class="verse">
<span class="lyric" data-chord="C">Frosty the</span>
<span class="lyric" data-chord="C7">snowman</span>
<br>
<span class="lyric">was a</span>
<span class="lyric" data-chord="F">jolly</span>
<span class="lyric" data-chord="F#dim">happy</span>
<span class="lyric" data-chord="C">soul</span>
<span class="lyric" data-chord="C7"></span>
<br>
<span class="lyric">with a</span>
<span class="lyric" data-chord="F">corncob</span>
<span class="lyric" data-chord="F#dim">pipe and a</span>
<span class="lyric" data-chord="C">button</span>
<span class="lyric" data-chord="A7">nose</span>
<br>
<span class="lyric">and two</span>
<span class="lyric" data-chord="Dm7">eyes made</span>
<span class="lyric" data-chord="G7">out of</span>
<span class="lyric" data-chord="C">coal.</span>
<span class="lyric" data-chord="C7"></span>
</p>
This creates a one-column, two-row, inline grid for each .lyric span. The value of --chord is set to the value of the data-chord property only on elements that have that property. It's then used in all .lyric elements to set the content of the :before pseudo-element, with a fallback to a non-breaking space if the variable is undefined. This is important because it pushes the text into the bottom row for .lyric spans that don't have a chord, and keeps the text horizontally aligned.
I am trying to align these elements in my Angular application - date, file total and file size.
If there is a larger number with more digits, then it is pushing the other elements away.
I have tried changing the padding margins and have tried display: Flex, inline and inline-block.
I want the start of each element to line up even if the numbers have more digits or less, so say we have - Apr 1, 2019 1 file 3445 G the start of each element will line up with Mar 28, 2019 34 files 29282 G.
The elements are in spans with a class of jobdate-item-date, jobdate-item-file-total and jobdate-item-file-length.
When you click on these they open up showing lists of job data. Here is a picture and my current code -
Html -
<div *ngFor="let date of selectedJob.dates" class="card-date-file">
<div class="detail-item" (click)="toggle()">
<span class="jobdate-item-date">{{ date.date | date: 'MMM dd, y' }}</span>
<span class="jobdate-item-file-total">{{ date.files.length }} files</span>
<span class="jobdate-item-file-length">{{ jobFileCalc(date.files) }} GB</span>
</div>
<ng-container *ngIf="show">
<div *ngFor="let file of date.files" class="list" >
<span class="file-item-filename">{{ file.filename }}</span>
<span class="file-item-incr">{{ file.incr? 'INCR':'FULL' }}</span>
<span class="file-item-time">{{ file.dttm | date:'h:mm' }}{{ file.dttm | date:'a' | lowercase }}</span>
<span class="file-item-size">{{ file.sizegb.toFixed(1)| number : fractionSize }} GB</span>
</div>
</ng-container>
</div>
</div>
CSS -
.jobdate-item-date {
padding: 0.1em 1.1em 0.3em 0.8em;
}
.jobdate-item-file-total {
padding: 0.3em 1.1em 0.3em 1.1em;
}
.jobdate-item-file-length {
padding: 0.3em 1.1em 0.3em 1.1em;
}
You could give every element a certain width (I used flexbox in my example), and if it is too long, you could truncate the text with some ellipses if you'd like. You can of-course play with the widths, or use percentages to achieve your wanted results.
.detail-item {
display: flex;
padding: 8px;
}
.jobdate-item-date,
.jobdate-item-file-total,
.jobdate-item-file-length {
flex: 0 0 100px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div class="detail-item" (click)="toggle()">
<span class="jobdate-item-date">Mar 29, 2019</span>
<span class="jobdate-item-file-total">12 files</span>
<span class="jobdate-item-file-length">2280.2 GB</span>
</div>
<div class="detail-item" (click)="toggle()">
<span class="jobdate-item-date">Apr 3, 2019</span>
<span class="jobdate-item-file-total">2 files</span>
<span class="jobdate-item-file-length">99.2 GB</span>
</div>
<div class="detail-item" (click)="toggle()">
<span class="jobdate-item-date">Apr 3, 2019</span>
<span class="jobdate-item-file-total">2 files</span>
<span class="jobdate-item-file-length">324324234234234232423 GB</span>
</div>
I have my template and for the most part it does work, there are two things wrong. I want the Progress bar to Align left of the page, and I also want the percentage to show.
<div style="
width:{{{width|25%}}};
{{#ifeq: {{{center|yes}}} | yes |
margin:auto;
text-align:center;}}">
{{#ifeq: {{{header|yes}}} | yes
| <p>
{{{text|completed <small>(estimate)</small>}}}
</p>
}}
<p style="border:{{{border|1px solid gray}}}; padding:{{{padding|1px}}}; overflow:hidden;">
<span style="
width: {{#expr: {{{1|<noinclude>2</noinclude>0}}} / {{{total|100}}} * 100}}%;
height: {{{height|2}}}px;
background:{{{color1|#5FDB00}}};
float:left;"> </span>
<span style="
width:{{#expr: 100 - {{{1|<noinclude>2</noinclude>0}}} / {{{total|100}}} * 100}}%;
height:{{{height|2}}}px;
background:{{{color2|#efefef}}};
float:left;
"> </span>
</p>
</div>
My example
{{Progress bar|90|text=KTG Image Rebuild}}
In this example the task is 90% complete but that doesnt show on or above the Progress bar.
Give this a try. You weren't actually trying to put the progress text in it, not sure why you'd expect it to be there. It's added as a div above the progress bar <p>.
<div style="float:left; width:{{{width|25%}}}; {{#ifeq: {{{center|yes}}} | yes | margin:auto; text-align:center;}}">
{{#ifeq: {{{header|yes}}} | yes | <p>
{{{text|completed <small>(estimate)</small>}}}
</p>
}}
<div style="float:right; text-align:right; font-size:10px; line-height:10px;">{{{1|20}}}%</div>
<p style="border:{{{border|1px solid gray}}}; padding:{{{padding|1px}}}; overflow:hidden; float:left; width:80%">
<span style="width:{{#expr: {{{1|20}}} / {{{total|100}}} * 100}}%; height:{{{height|2}}}px; background:{{{color1|#5FDB00}}}; float:left;"> </span>
<span style="width:{{#expr: 100 - {{{1|20}}} / {{{total|100}}} * 100}}%; height:{{{height|2}}}px; background:{{{color2|#efefef}}}; float:left;"> </span>
</p>
</div>
I don't know how to make text indent in my capitation in second line in html. I tried giving hardcoded whitespaces but in next in my HTML document they appear as grey field.
<capitation>
<span style="font-weight: bold; font-size: 12px;">xxx</span>
<span style="font-size: 12px;">YYYY</span>
<span style="font-weight: bold;font-size: 12px;">YYYYY</span>
<span style="font-size: 12px">YYYYY</span>
<br>
<span style="font-size: 12px "> XXXXXX</span>
<span style="font-weight: bold;font-size: 12px;"> xxxxxxxx</span>
<span style="font-size: 12px;">XXXXXXX</span>
<br>
<br>
</capitation>
Its appears as
XXXX! YYYY
ZZZZ
and I want
XXXXX! YYYYYY
ZZZZZZ
This code is a bit naff mate.
Inline CSS everywhere and so on.
It's not how I would write it. But you could use padding-left.
Jsfiddle:
http://jsfiddle.net/ev88su57/1/
<capitation>
<span class="bold">xxx</span>
<span>YYYY</span>
<span class="bold">YYYYY</span>
<span>YYYYY</span>
<br>
<span class="indent"> XXXXXX</span>
<span class="bold"> xxxxxxxx</span>
<span>XXXXXXX</span>
<br>
</capitation>
CSS:
.indent { text-indent:-2em;margin-left:2em; }
capitation span {font-size:.8em;}
.bold { font-weight:bold; }
You can use margin-left for this:
<span style="font-size: 12px; margin-left: 5em;">ZZZZZ</span>
Note: If you want the same font size, wrap the span elements in a div:
<div style="font-size: 12px;"><span ...></div>
since the children of the div inherit its styles.
I solved it
putted tab at start and after new line
<capitation>
<span class="bold"> xxx</span>
<span>YYYY</span>
<span class="bold">YYYYY</span>
<span>YYYYY</span>
<br>
<span class="indent"> XXXXXX</span>
<span class="bold"> xxxxxxxx</span>
<span>XXXXXXX</span>
<br>
</capitation>