Poetry line-breaks with semantic HTML and CSS - html

I would like to display poetry, using only HTML and CSS. To my understanding, the semantically correct way to structure poetry in HTML is using <p> tags for verses and <br /> tags for individual lines, like this:
<p>
poetry is very nice <br />
but kind of hard to style <br />
if only you could help me, guise, <br />
I'd give you my best smile.
</p>
When the poem has long enough lines to wrap, the accepted style would be to hanging indent the wrapped line, like this:
This is a very long line that
needs to be wrapped
Ideally the wrapped part would be right aligned, but a fixed dimension hanging indent would work too.
I have seen various solutions to this, but they all involve semantically superfluous HTML, such as using lists or <span> tags for each line. For example:
.verse {
margin-left: 2em;
}
.line {
margin-left: -2em;
}
<p class="verse">
<span class="line">poetry is very nice </span><br>
<span class="line">but kind of hard to style </span><br>
<span class="line">if only you could help me, guise, </span><br>
<span class="line">I'd give you my best smile.</span>
</p>
Is there a way I could accomplish this without cluttered HTML?
Edit (1): I had an error in the example code. Both .verse and .line should have a margin-left property declared, not padding-left and margin-left.
Edit (2): Regarding the possible duplicate, I am aware of the different opinions regarding what is the most correct to mark up poetry in HTML. I have selected what seemed to me to be the most semantically correct, and this question is about the CSS needed to display it correctly.
Edit (3): I corrected the error in the example incorrectly. Here is a screenshot:
To clarify, I would like to achieve the same effect as the above screenshot without the <span> tags, or any other semantically superfluous tags.

Considering you have 2em of padding along with 1.5em of negative margin, you can simply combine these two values by just giving the verses 0.5em of padding. This will allow you to cut out the <span> tags entirely, with the exact same visual output:
.verse {
padding-left: 0.5em;
}
<p class="verse">
poetry is very nice<br />
but kind of hard to style<br />
if only you could help me, guise,<br />
I'd give you my best smile.
</p>

You can use a negative text-indent for the first line of a paragraph and add padding to the whole paragraph, i.e. you need only a the <p> element.
.verse {
text-indent: -20px;
padding-left: 20px;
}
<p class="verse">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>

Use like :
div.a {
text-align: justify; /* For Edge */
-moz-text-align-last: right; /* For Firefox prior 58.0 */
text-align-last: right;
}
<div class="a">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit. Vestibulum volutpat tellus diam, consequat gravida libero rhoncus ut.</p>
</div>
Follow : https://www.w3schools.com/cssref/tryit.asp?filename=trycss3_text-align-last

The only easy solution I've come up with so far is to do paragraph breaks instead of line breaks and create a .poem class that takes away the spaces between paragraphs (so it acts as a line break rather than paragraph break).
.poem { text-indent: -2em; margin: 0 0 0 2em;}
But then you have to go through and put double paragraphs (double space) between stanzas. It's not a good solution but it's easier than pasting in classes on each line or making a list.
If anyone has a solution with breaks though, that would be awesome. text-align-last: right; has a similar effect, but it's not a traditional poetry format.

Related

Trying to make a scrollbox that trunicates sub elements vertically

So basically I'm trying to have a fixed box that is always the same size on screen but if something is wider than the box it would get trunicated to the next line. But instead it keeps making the box start scrolling horizontally which I absolutly do NOT want to ever happen.
Inside the scrollbox could be <div> <p> <h1-6> <hr> <img> or <a> tags and I want it to only scroll vertically and I want anything that goes off the right side to get moved to the next line for any sub element.
But right now it just scrolls horizontally and vertically.
the ${html} being any given string of html to be put in
<div class="col-md-10">
<div class="Holder">
<pre>
${html}
</pre>
</div>
</div>
p{
overflow-wrap:normal;
}
pre{
overflow-x: auto;
border:0;
background-color:transparent;
}
.Holder{
display: flex;
flex-direction: column;
height: calc(100vh - 140px);
}
Any way to get this thing to do as I intend it to?
Note: I'm currently using v3.4.1 of bootstrap.min.css with the above CSS being loaded after.
I want it to only scroll vertically and I want anything that goes off
the right side to get moved to the next line for any sub element.
If I understand this correctly, which means you want to wrap the elements into next line, you can do that with white-space
Try this
p{
overflow-wrap:normal;
}
pre{
overflow-x: auto;
border:0;
white-space: inherit;
background-color:transparent;
}
.Holder{
display: flex;
flex-direction: column;
height: calc(100vh - 140px);
}
.Holder {max-width: 500px; max-height: 150px; overflow-y: auto;}
<div class="col-md-10">
<div class="Holder">
<pre>
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
</pre>
</div>
</div>
NOTE Here I have set max-height and max-width for the .holder just for you to see the vertical scrolling, you can remove that later.
Try white-space property to pre tag.
pre {
overflow-x: auto;
border: 0;
background-color: transparent;
height: 100%;
white-space: break-spaces;
}
.Holder {
display: flex;
flex-direction: column;
width: 300px;
height: calc(100vh - 140px);
}
<div class="wrapper">
<div class="Holder">
<pre>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</pre>
</div>
</div>
Check demo here →→ https://jsfiddle.net/Divya_Patel/hL5we9cm/4/

HTML5 Details/Summary Open at Top Close From Bottom

I'm using HTML5's Summary/Details tags to hide/show extra text on a documentation page. The extra text is lengthy and the open/close nature of the summary tag is that you have to click on the summary line to make it both open and close the details block. This means that after scrolling down through the length of the long text you must scroll back up to the summary tag in order to click to close it.
I would like to be able to click on the bottom of the details segment to close it. Using CSS, I am able to add a 'close' triangle at the bottom of the detail segment. What can be done (preferably in CSS) to cause a click on the triangle to close the detail block?
details[open]:after {
content:'▲';
}
Below is a CSS only solution, just use ::after on <summary> and absolute positioning.
details.test {
position: relative;
padding: 5px 0;
}
details.test[open]>summary::after {
display: inline-block;
content: "close";
position: absolute;
right: 0;
bottom: 0;
}
<details class="test">
<summary>Example</summary>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
</p>
</details>
I don't think it can be done using CSS. But you can use javascript:
<!DOCTYPE html>
<html>
<body>
<script>
function closeDetails() {
document.getElementById("details").removeAttribute("open");
window.location = "#details";
}
</script>
<details id="details">
<summary>Show Details</summary>
<p>yadda yadda</p>
<button onclick="closeDetails()">Close Details</button>
</details>
</body>
</html>
Since there were no other answers I’ll mark Sartoris’ as the correct one.
In case anyone else wants to use to it, I took the liberty of embellishing it a bit so that it would work with more than one ‘details’ element on a page and be a bit more generic. In this way the same function and close button definition can be used for all ‘details’ blocks as long as each has a unique ID.
<!DOCTYPE html>
<html>
<body>
<script>
function closeDetail(detailsElement) {
detailsElement.removeAttribute("open");
window.location = '#' + detailsElement.id;
}
</script>
<details id="details">
<summary>Show Details</summary>
<p>yadda yadda</p>
<button onclick="closeDetail(this.parentElement)">▲</button>
</details>
</body>
</html>

Place footer below taller of two overlapping elements in CSS

I have a block of text that goes on top of a picture. Then below this there is a footer. But the text comes from a database, so sometimes the text is taller than the picture and sometimes shorter. I want the footer to come below the "whole thing" in either case.
Like this -- imagine the XXX's are the picture
Scenario 1:
XXXXXXXXXXXXXXXX
XXXX Short XXXX
XXXX text XXXX
XXXXXXXXXXXXXXXX
-- Footer --
Scenario 2:
XXXXXXXXXXXXXXXX
XXXX Long XXXX
XXXX text XXXX
XXXX runs XXXX
past
the
picture.
-- Footer --
It's easy enough to put the text on top of the picture with position: absolute for one or the other. But then the footer gets positioned without regard to the absolute element.
At the moment I've got two different versions of the screen, one where the picture is static and the text is absolute, for cases where I expect the text to be longer; and one where the text is static and the picture is absolute, for cases where the text is longer. This works, but only because I know what data is in the database today. I could have the program examine the text, but I have no way to know how tall it will lay out without knowing the size of the window the user sets for his browser, not to mention font sizes, etc.
Maybe position: absolute isn't the right way to do this?
Update *
Someone suggested I make a fiddle. I was about to, but I see Adam B Smith made one that illustrates my problem very well: http://jsfiddle.net/DIRTY_SMITH/EgLKV/6183/
That fiddle looks great if the text is taller than the image. Now delete a bunch of text so that the text is shorter than the image, and you see the footer overlaps the image.
OK this one will do it for you http://jsfiddle.net/DIRTY_SMITH/EgLKV/6185/
lol
#container{min-height: 400px;}
#image
{
position:absolute;
z-index:-9999;
left:0;
top:0;
}
#text
{
z-index:9999;
width: 200px;
color:red;
font-size:24px;
font-weight:bold;
}
.footer {
background:#ffab62;
width:100%;
height:100px;
z-index:9999;
bottom:0;
left:0;
}
If you know the size of the image, and set the container's size same as the image, it does work.
.container {
border: 1px solid red;
position: relative;
display: table;
width: 250px;
height: 193px;
}
.container img {
position: absolute;
z-index: -1;
}
.container span {
background: rgba(255,255,255,.7);
display: table;
width: 80%;
margin: auto;
margin-top: 25%;
margin-bottom: 5%;
}
.footer {
background: pink;
}
<div class="container">
<img src="http://albanyvisitors.com/WpContents/wp-content/uploads/2015/06/200px-Big-Lake-Big-Sky-Mt-Washington-by-Bill-Origer-2015-photo-contest.jpg" />
<span>Lorem ipsum dolor sit amet, consectetur adipiscing elit</span>
</div>
<div class="footer">foooooooter</div>
<br>
<div class="container">
<img src="http://albanyvisitors.com/WpContents/wp-content/uploads/2015/06/200px-Big-Lake-Big-Sky-Mt-Washington-by-Bill-Origer-2015-photo-contest.jpg" />
<span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</span>
</div>
<div class="footer">foooooooter</div>

Responsive Site Not Working: CSS

I have a website that I'm working on, and I'm trying to make it into a responsive website, so that if the page is accessed via a mobile device, everything is positioned in one column. Right now, only two of my elements are responsive. (The 200x150 images in my fiddle)
All other images overlap each other in the center of the page. I'm trying to make it so that the two images on the right panel (251x281 and 261x360) align in one column after the (200x150) image, in other words, so that those two images on the right are the last two elements of the page. This is my media query:
#media screen and (max-width: 768px){
.events .events-plugin{
max-width: 100%;
display:block;
width: auto;
height: auto;
}
.img-wrap{
width: 100%;
}
.container .slideshow{
top: 5%;
}
}
And my fiddle:
http://jsfiddle.net/UQdYX/
What am I doing wrong here? Any help would be appreciated. Thanks in advance.
I tried moving the code to my IDE and work it out there. But it's difficult without having an actual responsive framework behind it to test it with #media (min size - max size) etc..But I'll give you pointers on the obvious mistakes. Use floats and margins to control positioning.
refrain from using too much positioning, specially position:absolute. It's counter productive to the principle of responsiveness.
Watch your div nesting. It looks like your page architecture is off. Stick to the basics
<header><nav><section><aside><footer>, etc.
And then finally make a lot of use of your framework's pre-built sizes. Bootstrap will use <span1><span2> <span3>...<span12>...and bluprint will use grid1, grid2, gri3...grid12 etc. Each of these prebuilt sizes will allow you to align your divs to sum 1200px in width.
e.g.
<div class"span12">
<div class="span6></div>
<div class="span6></div>
</div>
Okay, yes, I think your HTML needs a bit of reworking. I understand the dilemma, though - when you're new to dynamic layouts it can seem a bit of a struggle at first.
I would suggest that one reasonable possibility would be something like this (this is just a simple solution which you can hopefully expand/refine for your purposes);
<div class="wrap">
<div class="left_column">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<div class="right_column">
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
CSS;
div.left_column,
div.right_column {
float: left;
width: 50%; }
#media (max-width: 640px) {
div.left_column,
div.right_column {
float: none;
width: 100%; }
}
This should display as a two-column layout until the browser window measures less than 640 pixels wide, at which point, it changes to one column.
Obviously, you would add further DIVs inside the left and right columns as you required them. Let me know if you want a more specific/detailed example.

Using CSS to place a symbol linked to a text phrase into a document's margin

I'm looking for a way in CSS to place a symbol into the margin of the document to highlight/indicate the position of some special phrase in the text body of the document. Think of the usual text-editors in programming IDEs that place little warning icons in the margin next to lines that contain errors.
This is easy to do if the document consists of non-wrapped single lines. Then I can just check if the line needs the symbol and place it manually.
But it gets tricky if I want to, for example, place an icon for spelling mistakes in a document where the browser automatically breaks the lines. Then I would have to have a way to figure out which line the spelling mistake ended up in. This is probably also possible with JS by checking the y-coordinate of some wrapper-span that marks the spelling mistake, but I'm looking for something more elegant.
Is there some trick with float-left or absolute positioning that allows me to, for example, put this marker symbol into the span that marks the error and have it be placed in the left margin of the document instead of inside the boundaries of the span?
Actually, the answer is exactly as you described. Have spans wrapping your text, and inside the span, include an icon element. Then float it left, and set a negative margin on it. Example:
CSS:
.icon {
display: inline-block;
width: 10px;
height: 10px;
background: blue;
float: left;
margin-left: -15px;
margin-top: 5px;
}
Markup:
<span class="selected"><span class="icon"></span>this is some text in a span. </span>
Working example: http://jsfiddle.net/FQCsn/
I think there's also an application for the position: absolute in the context of the :before pseudoelement. Try this and see if it gives you what you're looking for:
<html>
<head>
<title>Lorem Ipsum</title>
<style>
.allowLeftMargin
{
margin-left: 5em;
}
.highlightThis
{
background-color: yellow;
}
.highlightThis:before
{
background-color: yellow;
content: "Note";
padding-left: 0.25em;
padding-right: 0.25em;
position: absolute;
left: 1em;
}
</style>
</head>
<body>
<div class="allowLeftMargin">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit
esse cillum dolore eu fugiat nulla pariatur.
<span class="highlightThis">Excepteur sint occaecat</span>
cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.</p>
</div>
</body>
</html>
You can quickly adjust the size of the browser window to confirm that the note moves with the highlighted span.
What you can do is put a strong around the spelling error, add another tag (a span for example) right after that spelling error, and set that span in position: absolute, but without the "top" property (because the top position is variable). Put that span in width: 100% in order to "select" the line, and add another tag inside that span (a i tag for convenience), and use it to put your icon.
p{ line-height:20px; margin:20px;}
strong{ color:red;}
span{ display:block; height:20px; left:0; position:absolute; width:100%;}
i{ background:red; display:block; height:12px; left:0; position:absolute;
top:-16px; width:12px;}
Example: http://jsfiddle.net/fwZqv/1/
Try to change the width of the "Result" window and see how it behaves.
It's not a perfect solution, and I would rather use JS for that matter.