Responsive chords above lyrics without added whitespace in lyrics - html

I'm trying to render chords over lyrics using HTML and found a near perfect solution here on StackOverflow. My one problem with this solution is that it creates extra whitespace after lyrics if the chord name is longer than the associated word. This can be seen on the Csus4 of the first "Imagine" in the example at the end of this question.
To sum it up, I want to render chords over lyrics using HTML such that:
chords are always above the right lyrics
if screen is smaller than the line, lines overflow on word boundaries
if the chords are larger than the text below it doesn't create space between the lyrics
a chord can also be in the middle of a word
Edit:
chords never overlap
I have searched StackOverflow and googled a lot but every solution I found fails one of these criteria. All help is greatly appreciated!
Edit: Solutions may also involve javascript though I hope this can be solved without needing javascript.
body {
padding: 20px;
font-size: 30px;
}
.line {
display: flex;
align-items: flex-end;
flex-wrap: wrap;
}
.chord-letter {
display: flex;
flex-direction: column;
align-items: left;
}
.no-space {
margin-right: 0;
border: solid 1px red;
}
.space {
margin-right: 0.33em;
border: solid 1px green;
}
.chord {
color: gray;
font-style: italic;
font-weight: bold;
font-size: 1.2em;
border: solid 1px blue;
}
.no-space .chord {
margin-right: 0.33em;
}
.word {
display: flex;
flex-direction: row;
align-items: flex-end;
}
<div class="line">
<div class="word">
<span class="no-space">Ima</span>
<div class="chord-letter space"><span class="chord">Csus4</span>gine</div>
</div>
<span class="space">there's</span>
<div class="chord-letter space"><span class="chord">Cmaj7</span>no</div>
<div class="chord-letter space"><span class="chord">F</span>heaven</div>
<div class="word">
<span class="no-space">Ima</span>
<div class="chord-letter space"><span class="chord">C</span>gine</div>
</div>
</div>

Basically you just need to set the chords to be position: absolute so they won't be part of the flow. You'd still need to figure out what to do when they overlap.
body {
padding: 20px;
font-size: 30px;
}
.line {
display: flex;
align-items: flex-end;
flex-wrap: wrap;
}
.chord-letter {
display: flex;
flex-direction: column;
align-items: left;
}
.no-space {
margin-right: 0;
border: solid 1px red;
}
.space {
margin-right: 0.33em;
border: solid 1px green;
}
.chord {
color: gray;
font-style: italic;
font-weight: bold;
font-size: 1.2em;
border: solid 1px blue;
}
.no-space .chord {
margin-right: 0.33em;
}
.word {
display: flex;
flex-direction: row;
align-items: flex-end;
}
/* add these */
.word {
padding-top: 50px;
}
.chord {
position: absolute;
top: 0;
}
.line {
position: relative;
}
<div class="line">
<div class="word">
<span class="no-space">Ima</span>
<div class="chord-letter space"><span class="chord">Csus4</span>gine</div>
</div>
<span class="space">there's</span>
<div class="chord-letter space"><span class="chord">Cmaj7</span>no</div>
<div class="chord-letter space"><span class="chord">F</span>heaven</div>
<div class="word">
<span class="no-space">Ima</span>
<div class="chord-letter space"><span class="chord">C</span>gine</div>
</div>
</div>

Related

Divs don't stretch to fill screen

Just finished a mini project and everything seemed to be going accordingly until I completed the footer this page. For each section, the divs do not stretch to the end, which wasn't an issue before. I'm assuming it's something to do with the pixels on the page?
Notice the gap on the left/right of the screen:
enter image description here
enter image description here
HTML:
<body>
<div class="header">
<div class="header-left">
<div class="logo">Header Logo</div>
</div>
<div class="header-right">
<div class="links-top">
<li>header link one</li>
<li>header link two</li>
<li>header link three</li>
</div>
</div>
</div>
<div class="hero">
<div class="hero-left-head">
<h1>This website is awesome</h1>
<p>This website has some subtext that goes here under the main title. It’s a smaller font and the color is lower contrast.</p>
<button class="hero-button">Sign Up</button>
</div>
<div class="sade">
<img src="https://s3.us-east-1.amazonaws.com/vnda-cockpit/www-streetopia-me/2020/09/11/5f5bfd8c2bb85sade01.jpg" alt="sade" height="200" width="350">
</div>
</div>
<div class="middle">
<div class="title"><h1>Some Information?</h1></div>
<div class="bmw-pics">
<div class="bmw-text">
<img src="https://aprperformance.com/wp-content/uploads/2015/01/BMW_M4_Lip_Installed_LR_7.jpg" alt="puke-green">
<p>Puke Green</p>
</div>
<div class="bmw-text">
<img src="https://cdn.bmwblog.com/wp-content/uploads/2015/03/Yas-Marina-Blue-BMW-F80-M3-Gets-Some-Essential-Updates-7.jpg" alt="yas">
<p>Yas Marina</p>
</div>
<div class="bmw-text">
<img src="https://f80.bimmerpost.com/forums/attachment.php?attachmentid=2671354&stc=1&d=1628858312" alt="Frost White">
<p>Frost White</p>
</div>
<div class="bmw-text">
<img src="https://1c2a8a2161d644d95009-22d26b38e78c173d82b3a9a01c774ffa.ssl.cf1.rackcdn.com/image/projectcars/f80m3/f80_m3_carbon_mirror_covers_7_w705.jpg" alt="Imola Red">
<p>Imola Red</p>
</div>
</div>
</div>
<div class="above-footer">
<div class="above-footer-p1">
<p>If you do what you've always done, then you'll get what you've always had, you dumb buffons!</p>
</div>
<div class="above-footer-p2">
<p>- A Wise Prophet</p>
</div>
</div>
<div class="last-space">
<div class="blue-box">
<div class="action"><strong>Call to action! It's time!</strong></div>
<div class="product-bit">Sign up for our product by clicking the button to your right :)</div>
<button class="last-button">Sign Up!</button>
</div>
</div>
<div class="footer">
<p>Copyright © The Odin Project 2021</p>
</div>
</body>
CSS:
.header {
background-color: #1F2937;
display: flex;
justify-content: space-around;
color: #f9faf8;
font-size: 24px;
padding: 10px;
}
.links-top {
list-style-type: none;
display: flex;
margin: 0;
padding: 0;
gap: 16px;
font-size: 20px;
}
a {
text-decoration: none;
color: #f9faf8;
}
p {
font-size: 15px;
}
.hero {
display: flex;
flex-direction: row;
background-color: #1F2937;
gap: 50px;
align-items: center;
justify-content: center;
padding-bottom: 30px;
}
.hero-left-head {
font-size: 24px;
color: #f9faf8;
}
.sade {
display: flex;
align-items: center;
justify-content: center;
border-radius: 10px;
}
.hero-button {
background-color: #3882F6;
color:#f9faf8;
border-radius: 25px;
padding: 0;
height: 30px;
width: 100px;
}
.middle {
display: flex;
flex-direction: column;
color:#1F2937;
}
.bmw-pics {
display: flex;
margin-left: auto;
margin-right: auto;
gap: 20px;
}
.bmw-text img {
height: 260px;
border-radius: 10px;
width: 250px;
}
.bmw-text p {
text-align: center;
}
.title {
text-align: center;
}
.above-footer {
background-color: #e5e7eb;
justify-content: center;
display: flex;
flex-direction: column;
}
.above-footer-p1 p,
.above-footer-p2 p {
font-size: 36px;
}
.above-footer-p2 {
display: flex;
justify-content: flex-end;
margin-right: 50px;
}
.above-footer-p1 p {
font-style: italic;
margin-top: 100px;
color: #1F2937;
display: flex;
align-items: center;
justify-content: center;
}
.last-space {
color: #f9faf8;
display: flex;
justify-content: center;
align-items: center;
}
.blue-box {
display: flex;
background-color: #3882F6;
width: 800px;
margin: 50px;
flex-direction: column;
padding: 50px;
border-radius: 15px;
}
.last-button {
align-self: flex-end;
padding:5px 25px 5px 25px;
color:#F9FAF8;
background-color: #3882F6;
border-radius: 10px;
border-color: #F9FAF8;
justify-content: center;
}
.footer {
background-color: #1F2937;
color: #F9FAF8;
display: flex;
justify-content: center;
align-items: center;
}
Please forgive the extensive css sheet, I'm still learning :) Any help is greatly appreciated!
There's margin on the body. By default the body element has 8px of margin on all sides. You can resolve this by adding this CSS to your project:
body {
margin: 0;
}
Some call this a CSS reset. You can learn more here. Hope this helps!
It's because the body html element (along with many other elements) has margin automatically applied. You can just clear it by adding this to your CSS:
body {
margin: 0px
}
You might want to try using something like Normalize.css for your projects. It really removes a lot of these "why is this happening" issues related to CSS. Also, you should read up on your browser's Devtools (on Chrome, for example, you can click Ctrl+Shift+i and it will open. You can then inspect specific elements and it will tell you why a certain element has a certain style.
For example, you can see that by hovering over the first paragraph of your post that it has a margin-bottom of 1.1em because it is selected by .s-prose p.
Hope that helps!

Move column to next line in flex box WITHOUT wrap

I don't want to wrap any of the columns, just have the last row break to the next line. When I add flex-wrap: wrap; to the row, it looks close to the desired result, but I need the first column to break.
.month-box {
background: #fefcf8;
border: 1px solid #bbb4a8;
border-radius: 5px;
min-height: 138px;
padding: 0;
text-align: center;
width: 230px;
}
.month-row {
border-top: 1px solid #e9e7e1;
color: #3c3c3c;
font-size: 14px;
padding: 7px 20px;
text-align: left;
display: flex;
/*flex-wrap: wrap;*/
align-items: center;
justify-content: space-between;
gap: 0 15px;
}
.quick-adjust-row {
display: flex;
width: 100%;
}
.item-value {
margin-left: auto;
}
<div class="month-box">
<div class="month-row category-toggle">
<div>Show me the money</div>
<div class="item-value">$100000000</div>
</div>
<div class="month-row category-toggle">
<div>Please don't take my cash</div>
<div class="item-value">-$100000000</div>
<div class="quick-adjust-row">
<div class="quick-adjust-label">$1000</div>
<div class="item-value">$99999000</div>
</div>
</div>
</div>

flex-wrap: wrap; does not work correctly with mutltiple flex-boxes

I have a DIV with two flex-boxes, the DIV itself is also a flex-box. I want both flex-boxes to wrap; therefore, I assigned flex-wrap: wrap; to the parent DIV. However, this behaves correctly until the flex box has multiple lines.
I'll try to explain it with images:
The following images show the behavior I want everywhere. All the boxes wrap.
However, when I add multiple DIV's with the class .book so that the browser needs multiple lines to display it, the wanted behavior vanishes. The item with the big plus sign and the id #add-book takes up a whole new line. However, I want it to wrap.
This is the HTML code, every book/box added, is another DIV in the DIV[id="added-books"] with the class of .book. This code would be displayed as shown in the first screenshot. I've just duplicated the DIV with the class of .book and the ID of #Second Book five times.
#books,
#added-books {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
}
.book,
#add-book {
display: block;
border: solid 1px black;
border-radius: 5px;
box-shadow: 5px 5px 20px rgba(0, 0, 0, 0.4);
height: 20em;
width: 13em;
margin: 2em;
padding: 1em;
position: relative;
z-index: 1;
}
.book hr {
border: none;
background-color: black;
width: 80%;
height: 2px;
border-radius: 5px;
}
.book-title {
font-weight: bold;
text-align: center;
}
.book-author {
font-style: italic;
text-align: center;
font-size: smaller;
}
.book-pages {
font-size: xx-small;
position: absolute;
bottom: 0;
left: 0;
right: 0;
text-align: center;
}
#add-book {
display: flex;
justify-content: center;
align-items: center;
}
#add-book #plus {
font-size: 10em;
text-align: center;
}
<div id="books">
<div id="added-books">
<div id="The Hobbit" class="book">
<p class="book-title">The Hobbit</p>
<hr>
<p class="book-author">by J.R.R. Tolkien</p>
<p class="book-pages">295 pages</p>
</div>
<div id="Second Book" class="book">
<p class="book-title">Second Book</p>
<hr>
<p class="book-author">by any author</p>
<p class="book-pages">296 pages</p>
</div>
</div>
<div id="add-book">
<p id="plus">+</p>
</div>
</div>
How can I achieve that, if I have multiple lines of book/boxes/divs, the plus-sign DIV with the id of #add-book wraps as in the first screenshot? Thanks for your help in advance.
If you want the books and add-book to all wrap together, they must participate in the same flexbox.
This is what display:contents was designed for - to remove intermediate boxes from the box tree, so that elements at lower levels of the DOM could participate in the same flexbox or grid. Here, the box to be removed is the one that would otherwise be generated by the #added-books element.
So
#added-books {
display:contents;
}
#books {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
}
.book, #add-book{
display: block;
border: solid 1px black;
border-radius: 5px;
box-shadow: 5px 5px 20px rgba(0, 0, 0, 0.4);
height: 20em;
width: 13em;
margin: 2em;
padding: 1em;
position: relative;
z-index: 1;
}
.book hr {
border: none;
background-color: black;
width: 80%;
height: 2px;
border-radius: 5px;
}
.book-title {
font-weight: bold;
text-align: center;
}
.book-author {
font-style: italic;
text-align: center;
font-size: smaller;
}
.book-pages {
font-size: xx-small;
position: absolute;
bottom: 0;
left: 0;
right: 0;
text-align: center;
}
#add-book {
display: flex;
justify-content: center;
align-items: center;
}
#add-book #plus {
font-size: 10em;
text-align: center;
}
<div id="books">
<div id="added-books">
<div id="TheHobbit" class="book">
<p class="book-title">The Hobbit</p>
<hr>
<p class="book-author">by J.R.R. Tolkien</p>
<p class="book-pages">295 pages</p>
</div>
<div id="SecondBook" class="book">
<p class="book-title">Second Book</p>
<hr>
<p class="book-author">by any author</p>
<p class="book-pages">296 pages</p>
</div>
<div id="ThirdBook" class="book">
<p class="book-title">Third Book</p>
<hr>
<p class="book-author">by any author</p>
<p class="book-pages">296 pages</p>
</div>
</div>
<div id="add-book">
<p id="plus">+</p>
</div>
</div>

Hover overlay on a container with multiple divs within? (flexbox)

I have a flex container that has multiple divs within. I am trying to figure out how to set a hover overlay black overlay with copy that is the same size as the container and overlays the divs within the container. I'm assuming there's a way to do this with HTML & CSS without JS? The idea being that when you hover over one of the boxes on the page, a "READ MORE" notice comes up on a 75% transparent black overlay. I'm just rambling now in order to "add some more details"
.box {
display: flex;
transition: background-color 0.5s ease;
background: white;
width: 23%;
margin: 10px;
color: black;
font-weight: bold;
font-size: .7em;
text-align: center;
justify-content: space-between;
height: 40%;
border-left: .5px solid black;
border-right: .5px solid black;
flex-direction: column;
}
#header-box {
display: flex;
border-top: 1px solid black;
border-bottom: 1px solid black;
width: 100%;
justify-content: flex-star;
align-content: flex-start;
font-family: 'Big Caslon';
}
#end-matter {
display: flex;
border-top: 10px solid black;
border-bottom: 10px solid black;
border-width: .5px;
width: 100%;
justify-content: space-around;
}
#sign-photo {
display: flex;
justify-content: center;
}
#aries {
display: flex;
width: 50%;
justify-content: center;
}
.sign-copy {
display: flex;
padding-left: 5px;
}
<div class="box">
<div id="header-box">
<h2 class="sign-copy">
Aries
</h2>
</div>
<div id="sign-photo">
<img id="aries" src="CSS/images/aries2.svg">
</div>
<div id="end-matter">
<p>
wtf
</p>
<p>
weird content here
</p>
<p>
time something?
</p>
</div>
</div>
You can use :hover as well as :after on specific css classes.
For example:
.container {
border: 2px solid blue;
display: flex;
}
.eachDiv {
border: 1px solid red;
background-color: gray;
width: 33%;
height: 50px;
}
.eachDiv:hover {
color: purple;
background-color: yellow;
}
.one:hover:after {
content: "this is the first div!!!";
}
.two:hover:after {
content: "el segundo div";
}
.three:hover:after {
content: "three is the best";
}
<div class="container">
<div class="eachDiv one">one</div>
<div class="eachDiv two">two</div>
<div class="eachDiv three">three</div>
</div>
Note: this answer may be a better solution to your question.

How to align text on the same line in flexbox?

I have aligned two divs side-by-side using Flexbox and I want the text in both the divs to be pushed to the bottom of the divs at equal levels but there seems to be different level of spacing underneath the individual texts.
.wrapper {
display: flex;
flex-direction: row;
}
.block1 {
font-weight: bold;
font-size: 2em;
color: red;
border: 1px solid;
display: flex;
align-items: flex-end;
}
.block2 {
font-size: 1em;
color: grey;
border: 1px solid;
display: flex;
align-items: flex-end;
}
.block1.hack-fix {
line-height: 29px; /* HACK */
}
<h2>Current:</h2>
<div class="wrapper">
<span class="block1">
23
</span>
<span class="block2">
Quote
</span>
</div>
<hr/>
<h2>Needed:</h2>
<div class="wrapper">
<span class="block1 hack-fix">
23
</span>
<span class="block2">
Quote
</span>
</div>
Thanks for the help!
What you're looking for is called baseline alignment.
To achieve this in flexbox use align-items: baseline.
Here's a more complete explanation:
What's the difference between flex-start and baseline?
.wrapper {
display: flex;
flex-direction: row;
align-items: baseline; /* NEW */
}
.block1 {
font-weight: bold;
font-size: 2em;
color: red;
}
.block2 {
font-size: 1em;
color: grey;
}
<div class="wrapper">
<span class="block1">23</span>
<span class="block2">Quote</span>
</div>
Parents :
display: flex;
Children:
flex: 1;