Add line break to ::after or ::before pseudo-element content - css

I do not have access to the HTML or PHP for a page and can only edit via CSS. I've been doing modifications on a site and adding text via the ::after or ::before pseudo-elements and have found that escape Unicode should be used for things such as a space before or after the added content.
How do I add multiple lines in the content property?
In example the HTML break line element is only to visualize what I would like to achieve:
#headerAgentInfoDetailsPhone::after {
content: 'Office: XXXXX <br /> Mobile: YYYYY ';
}

The content property states:
Authors may include newlines in the generated content by writing the "\A" escape sequence in one of the strings after the 'content' property. This inserted line break is still subject to the 'white-space' property. See "Strings" and "Characters and case" for more information on the "\A" escape sequence.
So you can use:
#headerAgentInfoDetailsPhone:after {
content:"Office: XXXXX \A Mobile: YYYYY ";
white-space: pre; /* or pre-wrap */
}
http://jsfiddle.net/XkNxs/
When escaping arbitrary strings, however, it's advisable to use \00000a instead of \A, because any number or [a-f] character followed by the new line may give unpredictable results:
function addTextToStyle(id, text) {
return `#${id}::after { content: "${text.replace(/"/g, '\\"').replace(/\n/g, '\\00000a')} }"`;
}

Nice article explaining the basics (does not cover line breaks, however).
A Whole Bunch of Amazing Stuff Pseudo Elements Can Do
If you need to have two inline elements where one breaks into the next line within another element, you can accomplish this by adding a pseudo-element :after with content:'\A' and white-space: pre
HTML
<h3>
<span class="label">This is the main label</span>
<span class="secondary-label">secondary label</span>
</h3>
CSS
.label:after {
content: '\A';
white-space: pre;
}

I had to have new lines in a tooltip. I had to add this CSS on my :after :
.tooltip:after {
width: 500px;
white-space: pre;
word-wrap: break-word;
}
The word-wrap seems necessary.
In addition, the \A didn't work in the middle of the text to display, to force a new line.
worked. I was then able to get such a tooltip :

You may try this
#headerAgentInfoDetailsPhone
{
white-space:pre
}
#headerAgentInfoDetailsPhone:after {
content:"Office: XXXXX \A Mobile: YYYYY ";
}
Js Fiddle

For people who will going to look for 'How to change dynamically content on pseudo element adding new line sign" here's answer
Html chars like
will not work appending them to html using JavaScript because those characters are changed on document render
Instead you need to find unicode representation of this characters which are U+000D and U+000A so we can do something like
var el = document.querySelector('div');
var string = el.getAttribute('text').replace(/, /, '\u000D\u000A');
el.setAttribute('text', string);
div:before{
content: attr(text);
white-space: pre;
}
<div text='I want to break it in javascript, after comma sign'></div>
Hope this save someones time, good luck :)

Add line break to ::after or ::before pseudo-element content
.yourclass:before {
content: 'text here first \A text here second';
white-space: pre;
}

Found this question here that seems to ask the same thing: Newline character sequence in CSS 'content' property?
Looks like you can use \A or \00000a to achieve a newline

<p>Break sentence after the comma,<span class="mbr"> </span>in case of mobile version.</p>
<p>Break sentence after the comma,<span class="dbr"> </span>in case of desktop version.</p>
The .mbr and .dbr classes can simulate line-break behavior using CSS display:table. Useful if you want to replace real <br />.
Check out this demo Codepen: https://codepen.io/Marko36/pen/RBweYY,
and this post on responsive site use: Responsive line-breaks: simulate <br /> at given breakpoints.

Related

How to Add Content using :after?

I want to add some text after this using CSS:
div#option-box-ymq-variant-1.ymq-options-box ymq-options-box-15 ymq-shopify-option-box :after {
content: "Testing";
}
<div class="ymq-options-box ymq-options-box-15 ymq-shopify-option-box " id="option-box-ymq-variant-1" data-type="15" data-id="-ymq-variant-1" data-ymq-add-to-cart="1" data-name="ymq-option2" data-label="Modo de Color" data-onetime="0" data-class="ymq-attrib-ymq-variant-1"
name="option-box-ymq-variant-Modo de Color">Div</div>
Sorry if this is a basic question, I'm new to coding.
To match multiple classes you need to use . instead of (space):
div#option-box-ymq-variant-1.ymq-options-box.ymq-options-box-15.ymq-shopify-option-box::after {
content: "Testing";
}
<div class="ymq-options-box ymq-options-box-15 ymq-shopify-option-box " id="option-box-ymq-variant-1" data-type="15" data-id="-ymq-variant-1" data-ymq-add-to-cart="1" data-name="ymq-option2" data-label="Modo de Color" data-onetime="0" data-class="ymq-attrib-ymq-variant-1"
name="option-box-ymq-variant-Modo de Color">
Your previous selector:
div#option-box-ymq-variant-1.ymq-options-box ymq-options-box-15 ymq-shopify-option-box :after
Was selecting the after pseudo element of nothing that was a child of an element of type ymq-shopify-option-box (which doesn't exist) etc. as a space in a selector is a descendant combinator
Note: Use two colons for pseudo elements
This is the current way of differentiating a pseudo element (like before and after) from a pseudo class.
Note: Pseudo element text is for styling and not content
Adding a bit of text or styling in pseudo elements can be very useful, but be aware that the text is not part of the DOM and may get missed for example by screen readers so don't totally rely on them to convey vital information on their own, they are more of a useful embellishment.
you select wrong
div#option-box-ymq-variant-1:after{
content: 'test';
}

Can't make multi-line matTooltip, always getting single-line

Using [matTooltip]="myMultiLineStringGenerator()" combined with [matTooltipClass]="'my-tooltip'" I was expecting to give me multi-line tooltips, whoever I get one liner tooltip, and I have no control when lines ends and moves to the next line.
Steps to reproduce
HTML part
<p [matTooltipClass]="'my-tooltip'"
[matTooltip]="getTooltopScript(nearestStations)">
Hello World!
</p>
CSS part:
.mat-tooltip {
white-space: pre-line;
}
::ng-deep .mat-tooltip {
white-space: pre-line;
}
TypeScript
getTooltopScript(ns: any[]]){
let part1 = ns[0]['stationName'] ;
let part2 = ns[0]['regionName'];
return `${part1}.\r\n\
${part2}.`;
}
I have read a lot other stack flows, and all of them where ending to use whitespace:pre-line in css, and \r\n in js\type script to create string. I dont know what else I should do make it work
Please help :)
update in CSS from other stackflows, and first comment below. I still have no result
::ng-deep .mat-tooltip .cdk-overlay-container, ::ng-deep .mat-tooltip .cdk-
global-overlay-wrapper {
white-space: pre-line;
}
If you are having the text coming from ts file, then please find below solution:
In .ts file:
getTooltopScript(){
return 'Multiline Tooltip \n This is second line';
}
In HTML:
<p #tooltip2="matTooltip" [matTooltip]="getTooltopScript()">Hello World!</p>
In css file:
::ng-deep .cdk-overlay-container, .cdk-global-overlay-wrapper {
white-space: pre-line;
}
In order to see the tooltip properly, we need to add the material style import in global stylesheet (that is style.css):
In style.css:
#import '~#angular/material/prebuilt-themes/deeppurple-amber.css';
Please find the working example below:
https://angular-sf-tooltip-issue-fix.stackblitz.io
https://stackblitz.com/edit/angular-sf-tooltip-issue-fix?file=src%2Fapp%2Fapp.module.ts
For this to work we need to override the style for .cdk-overlay-container, .cdk-global-overlay-wrapper:
::ng-deep .cdk-overlay-container, .cdk-global-overlay-wrapper {
white-space: pre-line;
}
In HTML:
<p matTooltip="Multiline Tooltip 
 This is second line">Hello World!</p>
Hope this will do the fix for you. Please find the working example below:
https://angular-sf-tooltip-issue-fix.stackblitz.io
https://stackblitz.com/edit/angular-sf-tooltip-issue-fix?file=src%2Fapp%2Fapp.module.ts

Create Line Breaks in Data Description [duplicate]

This question already has answers here:
CSS data attribute new line character & pseudo-element content value
(5 answers)
Closed 9 years ago.
I have CSS that is using Data Description to display text on a page.
Code:
CSS
#nav a:after {
text-align:center;
content: attr(data-description);
display: block;
}
HTML
<li><a data-description="The Thinking Man,The Artist, The Philosopher" href="#">The Renaissance Man</a></li>
What I am having trouble with and would I would like to do is to have each part of the sentence on its on line. In other words
The Thinking Man
The Artist
The Philosopher
But when I insert a <br /> it doesn't creat a break it just displays <br /> in the code. How would I create line breaks in a data description using the following code?
You can add a new line by combining \A with white-space:pre-wrap;, for example:
p:after {
content:"Line 1\ALine 2";
white-space:pre-wrap;
}
/* Line 1
* Line 2 */
JSFiddle example.
Unfortunately it doesn't seem you can do this using attr().
<p data-description="Line 1\ALine 2"></p>
p:after {
content:attr(data-description);
white-space:pre-wrap;
}
/* Line 1\ALine 2 */
JSFiddle example.
What you could do to get around this is to use multiple data-* attributes:
<p data-description1="Line 1" data-description2="Line 2"></p>
p:after {
content:attr(data-description1) "\A" attr(data-description2);
white-space:pre-wrap;
}
/* Line 1
* Line 2 */
JSFiddle example.
I don't know if this is a usable solution to your problem, however.
The content attribute won't ever interpret your Html as markup, so you'll need to go about this another way.
One way would be escaping the newline and setting white-space: pre; in your pseudoelement. This value is an abbreviation for 'preserves,' which means the newline will be rendered by the browser.
The Thinking Man,\AThe Artist,\AThe Philosopher
View on JSFiddle
For more on the white-space property, refer to the MDN article on it..
For more on escaping new lines in content, check out the CSS2 specs on strings.

CSS text-transform capitalize on all caps

Here is my HTML:
small caps &
ALL CAPS
Here is my CSS:
.link {text-transform: capitalize;}
The output is:
Small Caps & ALL CAPS
and I want the output to be:
Small Caps & All Caps
Any ideas?
You can almost do it with:
.link {
text-transform: lowercase;
}
.link:first-letter,
.link:first-line {
text-transform: uppercase;
}
It will give you the output:
Small Caps
All Caps
There is no way to do this with CSS, you could use PHP or Javascript for this.
PHP example:
$text = "ALL CAPS";
$text = ucwords(strtolower($text)); // All Caps
jQuery example (it's a plugin now!):
// Uppercase every first letter of a word
jQuery.fn.ucwords = function() {
return this.each(function(){
var val = $(this).text(), newVal = '';
val = val.split(' ');
for(var c=0; c < val.length; c++) {
newVal += val[c].substring(0,1).toUpperCase() + val[c].substring(1,val[c].length) + (c+1==val.length ? '' : ' ');
}
$(this).text(newVal);
});
}
$('a.link').ucwords();​
Convert with JavaScript using .toLowerCase() and capitalize would do the rest.
Interesting question!
capitalize transforms every first letter of a word to uppercase, but it does not transform the other letters to lowercase. Not even the :first-letter pseudo-class will cut it (because it applies to the first letter of each element, not each word), and I can't see a way of combining lowercase and capitalize to get the desired outcome.
So as far as I can see, this is indeed impossible to do with CSS.
#Harmen shows good-looking PHP and jQuery workarounds in his answer.
I'd like to sugest a pure CSS solution that is more useful than the first letter solution presented but is also very similar.
.link {
text-transform: lowercase;
display: inline-block;
}
.link::first-line {
text-transform: capitalize;
}
<div class="link">HELLO WORLD!</div>
<p class="link">HELLO WORLD!</p>
HELLO WORLD! ( now working! )
Although this is limited to the first line it may be useful for more use cases than the first letter solution since it applies capitalization to the whole line and not only the first word. (all words in the first line)
In the OP's specific case this could have solved it.
Notes: As mentioned in the first letter solution comments, the order of the CSS rules is important! Also note that I changed the <a> tag for a <div> tag because for some reason the pseudo-element ::first-line doesn't work with <a> tags natively but either <div> or <p> are fine.
EDIT: the <a> element will work if display: inline-block; is added to the .link class. Thanks to Dave Land for spotting that!
New Note: if the text wraps it will loose the capitalization because it is now in fact on the second line (first line is still ok).
JavaScript:
var links = document.getElementsByClassName("link");
for (var i = 0; i < links.length; i++) {
links[i].innerHTML = links[i].innerHTML.toLowerCase();
}
CSS:
.link { text-transform: capitalize; }
What Khan "ended up doing" (which is cleaner and worked for me) is down in the comments of the post marked as the answer.
captialize only effects the first letter of the word. http://www.w3.org/TR/CSS21/text.html#propdef-text-transform
You can do it with css first-letter!
eg I wanted it for the Menu:
a {display:inline-block; text-transorm:uppercase;}
a::first-letter {font-size:50px;}
It only runs with block elements - therefore the inline-block!
May be useful for java and jstl.
Initialize variable with localized message.
After that it is possible to use it in jstl toLowerCase function.
Transform with CSS.
In JSP
1.
<fmt:message key="some.key" var="item"/>
2.
<div class="content">
${fn:toLowerCase(item)}
</div>
In CSS
3.
.content {
text-transform:capitalize;
}
If the data is coming from a database, as in my case, you can lower it before sending it to a select list/drop down list. Shame you can't do it in CSS.
After researching a lot I found jquery function/expression to change text in first letter in uppercase only, I modify that code accordingly to make it workable for input field. When you will write something in input field and then move to another filed or element, the text of that field will change with 1st-letter capitalization only. No matter user type text in complete lower or upper case capitalization:
Follow this code:
Step-1: Call jquery library in html head:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
Step-2: Write code to change text of input fields:
<script>
$(document).ready(function(){
$("#edit-submitted-first-name,#edit-submitted-last-name,#edit-submitted-company-name, #edit-submitted-city").focusout(function(){
var str=$(this).val();
str = str.toLowerCase().replace(/\b[a-z]/g, function(letter) {
return letter.toUpperCase();
});
$(this).val(str);
});});
</script>
Step-3: Create HTML input fields with same id's you use in jquery code like:
<input type="text" id="edit-submitted-first-name" name="field name">
The id of this input field is: edit-submitted-first-name (It using in jquery code in step-2)
**Result:
Make sure the text will change after you move your focus from that input field at another element. Because we using focus out event of jquery here.
Result should like this: User Type: "thank you" it will change with "Thank You".
**
Best of luck
The PHP solution, in backend:
$string = 'UPPERCASE';
$lowercase = strtolower($string);
echo ucwords($lowercase);
I know this is a late response but if you want to compare the performance of various solutions I have a jsPerf that I created.
Regex solutions are the fastest for sure.
Here is the jsPerf: https://jsperf.com/capitalize-jwaz
There are 2 regex solutions.
The first one uses/\b[a-z]/g. Word boundary will capital words such as non-disclosure to Non-Disclosure.
If you only want to capitalize letters that are preceded by a space then use the second regex
/(^[a-z]|\s[a-z])/g
if you are using jQuery; this is one a way to do it:
$('.link').each(function() {
$(this).css('text-transform','capitalize').text($(this).text().toLowerCase());
});
Here is an easier to read version doing the same thing:
//Iterate all the elements in jQuery object
$('.link').each(function() {
//get text from element and make it lower-case
var string = $(this).text().toLowerCase();
//set element text to the new string that is lower-case
$(this).text(string);
//set the css to capitalize
$(this).css('text-transform','capitalize');
});
Demo
all wrong it does exist --> font-variant: small-caps;
text-transform:capitalize; just the first letter cap

css { content: "text"}, how do I add tags?

I wrote some dummy css. Instead of a tag I got escaped characters. How can I add a div tag instead?
.HeaderName:after{
content: "<div class=\"Name2\">text</div>";
}
.Name2 {
color: red;
}
The content declaration cannot add tags to the page (tags are structural); additionally, CSS is meant for presentation changes, not structural content changes.
Consider using jQuery, instead, such as:
$(".HeaderName").after("your html here");
If you need that extra tag only to make the added text red, just do this:
.HeaderName:after{
content: "text";
color:red;
}
Tested on Chrome.
You can't insert tags using content: in CSS. Here is the relevant part of the spec; see the 'content' property in the CSS 2.1 spec.

Resources