changing display order of span - html

I'm helping a friend writing some articles for scientific magazines. Some publishers require the authors cited in the bibliography in the form "last name, first name", while others asked for "first name, last name" (of course with a list ordered by last name, and sometimes with the last name in small caps).
I know this would be better done with a database, but my friend's skills are not at that level.
If I write a very simple HTML page, using lines like this one
<p><span class="lname">Doe</span>, <span class="fname">John</span></p>
is there a CSS way to have the line shown as "John DOE" or must I use some JS?

You can do this with flexbox, using order (with a little adjustment).
The Code (https://jsfiddle.net/sebastianbrosch/7Lqr68ar/):
p {
display:flex;
}
.fname {
order:1;
}
.lname {
order:2;
}
.fname:after {
content:",\00a0";
}
<p>
<span class="lname">Doe</span>
<span class="fname">John</span>
</p>
You can use a more dynamic solution like this too:
#name {
display: flex;
}
#name.fl .firstname:after {
content: "\00a0";
}
#name.lf .lastname:after {
content: ",\00a0";
}
#name.fl .firstname,
#name.lf .lastname {
order: 1;
}
#name.fl .lastname,
#name.lf .firstname {
order: 2;
}
<p class="fl" id="name">
<span class="firstname">John</span><span class="lastname">Doe</span>
</p>
<p class="lf" id="name">
<span class="firstname">John</span><span class="lastname">Doe</span>
</p>
Hint: You can use this solution but it would be better to prepare the name with PHP or get the name in the right format from database. Setting the order is only setting the visual ordering but not the ordering on code or for screenreaders.

You could use float and hide the comma.
.fname {float: left; padding-right: 5px;}
.comma {display: none;}
<p><span class="lname">Doe</span><span class="comma">,</span> <span class="fname">John</span></p>

Here's a different approach using data-attributes and :before and :after
Assuming your author list is in a container that I've called .autherContainer that either has the additional class .lnLast or .lnFirst. And the author names are written as shown, with the last name written twice for each version
HTML:
<div class="authorContainer lnFirst">
<p data-ln-first="Doe, " data-ln-last=" DOE">John</p>
</div>
<div class="authorContainer lnLast">
<p data-ln-first="Dear, " data-ln-last=" DEAR">Jane</p>
</div>
CSS
.authorContainer.lnFirst p:before {
content: attr(data-ln-first);
}
.authorContainer.lnLast p:after {
content: attr(data-ln-last);
}
I made my assumptions based on the fact that if the lists were all in the same container then you could simply write them in the order they ought to be instead of following a format and adding superfluous code, but that's just me and others might disagree

Related

How add gap after every sentence inside a single element | Different line-height value in one element

I'm building a notes app like google keep with react. My html-css for a single note element is:
const NoteList = ({searchTerm}) => {
const [notes, setNotes] = useState([]);
useEffect(() => {
async function fetchNotes(){
const response = await fetch("url")
const notes = await response.json();
setNotes(notes)
};
fetchNotes();
}, []);
return (<div className="note-list">
{notes.map((note) => (
<div key={note.id}>
<Note
id={note.id}
title={note.title}
content={note.content}
/>
</div>
))}
</div>);
};
.card{
width: 100%;
height: fit-content;
background-color: var(--card-bg);
border-radius: 5px;
box-shadow: 0 2px 4px 0 var(--card-shadow);
padding: 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
line-height: 1.2;
}
And the data I got from json is something like this:
[{
"id": 31,
"title": "Personal Development Goals",
"content": "1. Read one book per month\n2. Practice mindfulness meditation daily\n3. Take a public speaking course\n4. Learn a new skill or hobby\n5. Volunteer regularly\n6. Start a gratitude journal\n7. Set and track personal fitness goals"
}]
The output look like this.
I want more space after every finished sentence. NOT SAME HEIGHT for every line (not line-height). But bigger gaps between sentences.
This should be the output
What I've tried
I've tried bunch of line and letter property.
.card{
line-height: 1.2;
line-break: loose;
letter-spacing: 0.3px;
word-spacing: 1px;
}
But it doesn't achieve what I want.
What I Want
If you look carefully, you would see that the red gap is smaller that blue . I've obviously tried line-height , word-wrap But I couldn't find any property that can achieve this.
I've seen some online solution but they used multiple span inside a single element. But my data isn't static it retrieves from API in JSON format.
Thanks in advance.
P.S. I am new in react.
Wrap each "goal" in a p tag, then apply a css rule for p tag margins. example:
html:
<p>goal 1</p>
<p>goal 2</p>
and so on...
Then -
CSS:
p {
margin-top: use px, em, or rem. whichever works best for you and play around with the sizes until you like the look.; }
That will apply a margin above each p tag forcing a space between tags and NOT individual lines.
have u try to use multiple p
like :
<div class="card">
<h5 class="card-title">Personal Development Goals</h5>
<div class="card-content">
<p>1. Read one book per month on personal development or self-improvement.</p>
<p>2. Exercise at least 3 times per week.</p>
<p>3. Practice mindfulness meditation for at least 15 minutes per day.</p>
<p>4. Learn a new skill or take a course to improve my career prospects.</p>
<p>5. Volunteer at least once per month to give back to my community.</p>
<p>6. Set aside time each week to work on personal projects and hobbies.</p>
<p>7. Practice gratitude by writing in a journal every day.</p>
<p>8. Improve my time management skills by setting and sticking to a daily schedule.</p>
<p>9. Set and work towards specific, measurable, achievable, relevant, and time-bound (SMART) goals.</p>
<p>10. Seek out opportunities for personal growth and development, such as attending workshops or events.</p>
</div>
</div>
You will have more control over what you do, you can also use the CSS functionality that allows you to select a child:
.card > p {
font-size: 18px;
color: blue;
}

Changing the Text of a Span Class by script (magento)

Hello. First of all, sorry for eventual English mistakes, since I'm Brazilian:
I have a ecommerce based on magento 1.9.2.2, and the company that hosts it does not allow the user to access the server files (header, body, footer, etc). You can only edit the website via css and html external scripts.
So there's this div:
<p class="old-price">
<span class="price-label">De:</span>
<span class="price" id="old-price-1046">
R$2.500,00 </span>
</p>
<p class="special-price">
**<span class="price-label">Preço Promocional</span>**
<span class="price" id="product-price-1046">
R$2.299,90 </span>
</p>
Which I just need to replace the text "Preço Promocional" (within the "price-label" class) for "Por:"
So far I've tried:
document.getElementsByClassName('price-label').innerHTML = 'Por:';
javascript:document.getElementsByClassName('price-label').innerHTML = 'Por:';
javascript:void(document.getElementsByClassName('price-label').innerHTML = 'Por:');
Thanks for any help in advance...
getElementsByClassName returns a collection and not a single element. In your example you have two elements with the same class name, you'd access the first one with the index 0 and the second one with the index 1.
<p class="old-price">
<span class="price-label">De:</span>
<span class="price" id="old-price-1046">R$2.500,00</span>
</p>
<p class="special-price">
<span class="price-label">Preço Promocional</span>
<span class="price" id="product-price-1046">R$2.299,90</span>
</p>
<script>
document.getElementsByClassName('price-label')[1].innerHTML = "Por:";
</script>
This code will change the second one that says "Preço Promocional" for "Por:"
//EDIT
Now that I've seen the full page, in javascript you could achieve this with:
<script>
document.querySelectorAll('.special-price .price-label').forEach(function(node) {
node.innerHTML = 'Por: ';
});
</script>
This will target all elements with the class price-label inside elements with the class special-price, loop through each and change their contents. This will change the main, related and recommended products as long as it's put after they are created.
As a preferred alternative, try using the following css:
<style>
.special-price .price-label {
display:none !important;
}
.special-price::before {
content: 'Por: ';
}
</style>
This should hide the content and then prepend the text on the parent and doesn't required to be placed at the end to work.
// EDIT (To address new information added in the comments for this answer)
In order to avoid changing the homepage, you can use the :not() css' pseudo-class (info here) to exclude those instances of special-price that are found within the homepage. I searched for and id or class that was unique to the homepage (found the class cms-home on the body tag for the homepage) so I'm using that to both exclude and target the different price-labels. I also changed the font-size to match the original one:
<style>
// this targets price-label that's NOT in the homepage
body:not(.cms-home) .special-price .price-label {
display:none !important;
}
body:not(.cms-home) .special-price::before {
content: 'Por: ';
font-size:15px;
}
// this targets price-label on the homepage
.cms-home .special-price .price-label {
display:none !important;
}
</style>
If I understood correctly, on the homepage you're simply hiding the text, while on the other pages you're replacing it with "Por: ", this should do it (hopefully) unless there's another special case I'm unaware of.
Try this
<script>
$('.special-price .price-label').text('Por:');
</script>

How can I apply a style using LESS to a nephew element of a class

I have these elements on the HTML:
<div id="td-status" class="icongb-cancelled"></div>
<div class="ticket-header-text">
<span class="bet-text">TEXT1</span>
<span>TEXT2</span>
</div>
and I want to apply a certain style using LESS to TEXT1 ('bet-text' class) whether its uncle has a cercaion class (in this case icongb-cancelled). I'd like to apply it also to TEXT2 (no class). Would it be possible?
I'm using this code, but it doesn't work:
.icongb_cancelled ~ .ticket-header-text {
& .bet-text {
color: #959595;
}
}
NOTE: I don't want to use JQuery to add or remove any class.
I want to make it just using LESS wihtout any modifying on the HTML.
Thanks in advance.
EDIT: The code was fine, the problem was that I was using an underscore instead of a dash. so you can use that code to apply a style to a nephew element.
You're using .icongb_canceled in the selector, but the class is icongb-canceled.
Dash vs underscore. They need to match.
You can write .icongb-cancelled ~ .ticket-header-text .bet-text, which is valid in CSS, but also is LESS compatible:
.icongb-cancelled ~ .ticket-header-text .bet-text {
color: blue;
}
.icongb-cancelled ~ .ticket-header-text span {
color: green;
}
<div id="td-status" class="icongb-cancelled"></div>
<div class="ticket-header-text">
<span class="bet-text">TEXT1</span>
<span>TEXT2</span>
</div>

CSS: Will a nonsense value for the 'display' property cause problems?

I am using a CMS that allows data place holders with braces, like so:
Name: {First_Name} <br>
Email: {Email} <br>
Phone: {Phone} <br>
However it doesn't give me any way to do conditional output, like I can't hide the Phone line if the phone field is blank.
The CMS doesn't allow javascript or server side code. I came up with this trick:
Name: {First_Name} <br>
Email: {Email} <br>
<div style="display:none{Phone}">Phone: {Phone} <br></div>
If the person has no phone number, the div ends up display:none, but if they do, the div ends up with a nonsense value for display, and the whole div shows up.
It works in IE8, IE9, FF14, Chrome
Any reason I shouldn't do this?
No, that's absolutely fine; a value that's not understood by the browser, in CSS, doesn't result in an error, it simply ignores that value and displays the element with its default setting for that property.
[For] illegal values. User agents must ignore a declaration with an illegal value. For example:
img { float: left } /* correct CSS 2.1 */
img { float: left here } /* "here" is not a value of 'float' */
img { background: "red" } /* keywords cannot be quoted */
img { border-width: 3 } /* a unit must be specified for length values */
A CSS 2.1 parser would honor the first rule and ignore the rest, as if the style sheet had been:
img { float: left }
img { }
img { }
img { }
Citation: http://www.w3.org/TR/CSS21/syndata.html#parsing-errors

Which attribute of a <div> tag should reference the CSS?

This is probably a case of trying to run before I can walk, however... I have the following code:
<div class="hidden" id="repair_complete">
// some code
</div>
I was under the impression that if my CSS file contained:
#hidden {
display: none;
}
... then the div content wouldn't display. However, it seems to only adopt this behaviour if the CSS file contains a reference to the div id:
#repair_complete {
display: none;
}
In a book I'm working through the opposite seems to be true - the style sheet refers to the class name, not the id.
Any ideas where I'm going wrong?!
Your CSS syntax is incorrect.
If you want to access this div, you can do it like this:
/* By class: */
.hidden {
display: none;
}
/* By ID: */
#repair_complete {
display: none;
}
Note that to access an element by class you use a dot before the class name. You use a hash before the ID.
The other answers have the technical stuff right: you need .hidden, not #hidden.
Now you have to decide whether you want to attach CSS to divs by class or id. I find classes are better in the long run, unless you are really certain that there will ever really and truly be one of the thing you are making.
Also, don't forget that you can attach more than one class to an element:
<div class="red fat shallow">blah blah</div>
Then you can style this element with any of these selectors:
.red {...}
.fat {...}
.shallow {...}
.red.fat {...} /* Applies only to things that are both red and fat */
.red.fat.shallow {...} /* Very specific */
/* etc. */
A "." before the name will refer to classes, and a "#" will refer to ids:
.hidden
{
display: none;
}
You need:
.hidden{
display:none;
}
period is a class specifier, pound sign is for id's.
To use class name use the dot.
i.e.
.hidden refers to the class name
#repair_complete refers to the id.
To refer to an element's ID you use the # selector, to refer to it's class name you use the . selector.
So in your example you would use
#repair_complete {
display:none;
}
or
.hidden {
display:none;
}