Apply first 2 characters of string another styling - css

Is it possible to style the first 2 characters of a message another styling?
::first-letter
Does not do the trick, also looked at this question, but this only hides the other ones.
Is it perhaps possible with the new pseudo elements? Or use the ch in combination with ::first-letter?
This is what I want to achieve but I have no clue how to do it with pure CSS.
NOTE, I can not change the HTML.
<h4 class="date">10 Mar. 2022</h4>

This can't be done with pure CSS since there is no way of (dynamically) selecting the first 'word'.
Consider a javascript alternative that wraps the first part in an <em></em> that can be styled with some CSS.
const e = document.querySelector('.date');
const t = e.innerHTML.split(' ');
e.innerHTML = `<em class='up'>${t.shift()}</em> ${t.join(' ')}`
.up {
color: darkblue;
font-size: x-large;
position: absolute;
top: 5px;
font-style: unset;
}
h4 {
color: lightblue;
margin-top: 30px;
}
<h4 class="date">10 Mar. 2022</h4>

You can use a mixture of JS and css to achieve what you are looking for.
First, just split the different parts (day/month/year) into different spans and add styling accordingly. An example as follows.
var text = $('.date').text();
var textArr = text.split(/\s+/);
$('.date').html(`<span class="day">${textArr[0]}</span>
<span class="month">${textArr[1]}</span>
<span class="year">${textArr[2]}</span>`);
.month {
color: red;
}
.day {
color: blue;
}
.year {
color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h4 class="date">10 Mar. 2022</h4>

Related

css having a range after a class attribute

I have three class : product1, product2, product3. I can add css to all these class as follows:
.product1, .product2, .product3{
// add css here
}
But I am looking for more cleaner code to track 1 to 3 followed by 'product' and add css to these. My expectation can be Pseudocode Examples:
.product1to3{
// fun with css.
}
Is there any approach in css?
There is no such kind of css pseudo on what you wanted to achieve.
You can try to use SASS to achieve what you wanted.
and then use the #for Directive
SASS
#for $i from 1 through 3 {
.product#{$i} { width: 20px; }
}
CSS
.product1 {
width: 20px;
}
.product2 {
width: 20px;
}
.product3 {
width: 20px;
}
Also you can try to use LESS
Hope this helps
pure css implementation JSfiddle
So basically you need an "Attribute Begins With Selector" i.e select all classes which start with "product" and then you can use nth child attribute to select range
div[class^="product"]:nth-child(n+4):nth-child(-n+5) {
background: red;
}
Really good article on complex css and nth:child
/* This selects all the elements which have the class name starting with
"product"
*/
[class ^= "product"] {
//CSS
}
If you have an unknown / high number of ".product(x)", and for whatever reason don't want to use an extra class to target them, you can get away with an attribute selector that matches all elements that have a class containing "product".
[class*="product"]
div{
border:2px solid tan;
height:40px;
}
[class*="product"]{
background:steelblue;
}
<div class="product1"> product 1 </div>
<div class="product2"> product 2 </div>
<div class="not"> not a product</div>
<div class="product3"> product 3 </div>
<div class="product4"> product 4 </div>
It occupies just 1 line of compiled CSS, so it's minimal footprint, but be careful how you apply it.
Not an answer for the OP but for others that may find their way here remember that you can use multiple classes for each element.
html
<div class="product product1"></div>
<div class="product product2"></div>
<div class="product product3"></div>
css
/* shared styling */
.product {
display: flex;
background-color: gray;
border: 1px solid red;
}
/* individual styling */
.product1 {
color: black;
}
.product2 {
color: white;
}
.product3 {
color: blue;
}

How to use the CSS pseudo element :before in multiple classes of same element

I want to display the letters of my logo text in different colors, but using span is very rough and using JavaScript slows the page loading time. So I tried to use the CSS pseudo element :before, using multiple classes of same element but it’s not working. It shows only the letter of last class, that is letter4. Here is the code:
.letter1:before {
content:"Z";
color:red;
}
.letter2:before {
content:"O";
color:green;
}
.letter3:before {
content:"N";
color:blue;
}
.letter4:before {
content:"E";
color:purple;
}
And the HTML:
<span class='letter1 letter2 letter3 letter4'> </span>
How do I make it work?
Here you are SIR
demo: http://jsfiddle.net/7UjgL/
the style:
.letter{
width:40px;
height:20px;
position:relative;
letter-spacing: 26px;
}
.letter:first-letter{
color:red;
}
.letter:before,.letter:after{
position:absolute;
top: 0px;
}
.letter:before{
content: 'o';
color: green;
left: 11px;
}
.letter:after{
content:'n';
color:blue;
left: 22px;
}
the markup:
<div class=letter>ze</div>
You should use separate span elements for it because it will be more readable in the long run.
CSS:
.letter1{color:red;}
.letter2{color:green;}
.letter3{color:blue;}
.letter4{color:purple;}
HTML:
<span class='letter1'>Z</span>
<span class='letter2'>O</span>
<span class='letter3'>N</span>
<span class='letter4'>E</span>

Place two font icons one above the other with CSS

I want to place two font icons one above the other. So I can use it as:
<span class="icon1-on-icon2" />
Is it possible to define CSS class(es) to achieve this? It's not permitted to use another elements inside a span i.e. something like that:
<span class="stack">
<span class="icon1"/>
<span class="icon2" />
</span>
Sure, why not use :after and :before pseudo-selectors?
CSS
.font-icon {
height: 40px;
width: 20px;
}
.font-icon:after, .font-icon:before {
color: white;
content: '';
display: block;
font-family: 'your-font-icon';
height: 20px;
position: relative;
width: 20px;
}
.font-icon:before {
background: red;
content: 'h';
}
.font-icon:after {
background: blue;
content: 'g';
}
HTML
<span class='font-icon'></span>
Codepen sketch here: http://cdpn.io/lehzr
UPDATE
To place them on top of each other, simply change the position to absolute, put a relative on the container element, and set top and left to 0 for both the after and before.
Example: http://cdpn.io/lehzr
Hope that helps!

Force Non-Monospace Font into Fixed Width Using CSS

Is there any way to force a font to be monospaced using CSS?
By this I mean, using a non-monospace font, can you force the browser to render each character at a fixed width?
If this is for aligning digits in tables where some fonts (with traditional typography) render them by default with variable width (e.g. Segoe UI on Windows), you should look into CSS properties for:
font-variant-numeric: tabular-nums;
(this disables the proportional-nums default value for the numeric-spacing variant supported at least by OpenType fonts, and possibly by other font formats supported by the text renderer of your web browser for your particular platform)
No JavaScript needed! It is the cleanest way to disable the variable-width glyphs in these fonts and force them to use tabular digits (this generally uses in the same glyphs in the same font, but their leading and trailing gap is increased so the 10 digits from 0 to 9 will render at the same width; however some font may avoid the visual variable interdigit spacing and will slightly widden some digits, or could add bottom serifs to the foot of digit 1.
Note that this does not disable the variable height observed with Segoe UI (such as some digits will be x-height only like lowercase letters, others will have ascenders or descenders). These traditional digit forms may be disabled with CSS too, using
font-variant-numeric: lining-nums;
(this disables the default oldstyle-nums value for the numeric-figure variant supported at least by OpenType fonts, and by possibly other font formats supported by the text renderer of your web browser for your particular platform)
You can combine both:
font-variant-numeric: tabular-nums lining-nums;
--
The snippet below demonstrates this using a single proportional font (not monospaced!) featuring shape variants for digits, such as 'Segoe UI' on Windows and shows the different horizontal and vertical alignments produced.
Note that this style does not prohibit digits to change width if different styles like bold or italic is applied instead of medium roman as shown below because these will use different fonts with their own distinct metrics (this is not warrantied as well with all monospace fonts).
html { font-family: 'Segoe UI'; /* proportional with digit variants */ }
table { margin: 0; padding: 0; border: 1px solid #AAA; border-collapse: collapse; }
th, td { vertical-align:top; text-align:right; }
.unset { font-variant-numeric: unset; }
.traditional { font-variant-numeric: proportional-nums oldstyle-nums; }
.lining { font-variant-numeric: proportional-nums lining-nums; }
.tabular-old { font-variant-numeric: tabular-nums oldstyle-nums; }
.tabular-new { font-variant-numeric: tabular-nums lining-nums; }
.normal { font-variant-numeric: normal; }
<table>
<tr><th>unset<td><table width="100%" class="unset">
<tr><td>Rs12,34,56,789.00/Gal<td><i>Difference Rs86,41,97,532.11/Gal
<tr><td>Rs98,76,54,321.11/Gal<td><b>Total Rs1,11,11,11,110.11/Gal
</table>
<tr><th>traditional<td><table width="100%" class="traditional">
<tr><td>Rs12,34,56,789.00/Gal<td><i>Difference Rs86,41,97,532.11/Gal
<tr><td>Rs98,76,54,321.11/Gal<td><b>Total Rs1,11,11,11,110.11/Gal
</table>
<tr><th>lining<td><table width="100%" class="lining">
<tr><td>Rs12,34,56,789.00/Gal<td><i>Difference Rs86,41,97,532.11/Gal
<tr><td>Rs98,76,54,321.11/Gal<td><b>Total Rs1,11,11,11,110.11/Gal
</table>
<tr><th>tabular-old<td><table width="100%" class="tabular-old">
<tr><td>Rs12,34,56,789.00/Gal<td><i>Difference Rs86,41,97,532.11/Gal
<tr><td>Rs98,76,54,321.11/Gal<td><b>Total Rs1,11,11,11,110.11/Gal
</table>
<tr><th>tabular-new<td><table width="100%" class="tabular-new">
<tr><td>Rs12,34,56,789.00/Gal<td><i>Difference Rs86,41,97,532.11/Gal
<tr><td>Rs98,76,54,321.11/Gal<td><b>Total Rs1,11,11,11,110.11/Gal
</table>
<tr><th>normal<td><table width="100%" class="normal">
<tr><td>Rs12,34,56,789.00/Gal<td><i>Difference Rs86,41,97,532.11/Gal
<tr><td>Rs98,76,54,321.11/Gal<td><b>Total Rs1,11,11,11,110.11/Gal
</table>
</table>
Reference: https://developer.mozilla.org/docs/Web/CSS/font-variant-numeric
Why not think outside the box and inside a table for this:
<table cellpadding="0" cellspacing="0">
<tr><td>T</td><td>h</td><td>e</td><td></td><td>r</td><td>a</td><td>i</td><td>n</td><td></td><td>i</td><td>n</td><td></td><td>S</td><td>p</td><td>a</td><td>i</td><td>n</td><td></td><td>s</td><td>t</td><td>a</td><td>y</td><td>s</td></tr>
<tr><td>m</td><td>a</td><td>i</td><td>n</td><td>l</td><td>y</td><td></td><td>i</td><td>n</td><td></td><td>t</td><td>h</td><td>e</td><td></td><td>p</td><td>l</td><td>a</td><td>i</td><td>n</td><td>s</td><td>.</td></tr>
</table>
You can't do this with CSS. Even if you could, the result will look horrible:
If you really do need to do this, you could use JavaScript to wrap each individual character in an element (or just do it by hand):
function wrap_letters($element) {
for (var i = 0; i < $element.childNodes.length; i++) {
var $child = $element.childNodes[i];
if ($child.nodeType === Node.TEXT_NODE) {
var $wrapper = document.createDocumentFragment();
for (var i = 0; i < $child.nodeValue.length; i++) {
var $char = document.createElement('span');
$char.className = 'char';
$char.textContent = $child.nodeValue.charAt(i);
$wrapper.appendChild($char);
}
$element.replaceChild($wrapper, $child);
} else if ($child.nodeType === Node.ELEMENT_NODE) {
wrap_letters($child);
}
}
}
wrap_letters(document.querySelectorAll('.boxes')[0]);
wrap_letters(document.querySelectorAll('.boxes')[1]);
.char {
outline: 1px solid rgba(255, 0, 0, 0.5);
}
.monospace .char {
display: inline-block;
width: 15px;
text-align: center;
}
<h2 class="boxes">This is a title</h2>
<h2 class="boxes monospace">This is a title</h2>
I've just found the text-transform: full-width; experimental keyword, which:
[...] forces the writing of a character [...] inside a square [...]
text-transform | MDN
Combined with negative letter-spacing, you can get not-so-horrible results:
<style>
pre {
font-family: sans-serif;
text-transform: full-width;
letter-spacing: -.2em;
}
</style>
<!-- Fixed-width sans-serif -->
<pre>
. i I 1 | This is gonna be awesome.
ASDFGHJK | This is gonna be awesome.
</pre>
<!-- Default font -->
. i I 1 | This is gonna be awesome.
<br>
ASDFGHJK | This is gonna be awesome.
Well, you didn't say using only CSS. It is possible to do this with just a little bit of Javascript to wrap each letter in a span. The rest is in CSS...
window.onload = function() {
const secondP = document.getElementById('fixed');
const text = secondP.innerText;
const newText = text.split('').map(c => {
const span = `<span>${c}</span>`;
return span;
}).join('');
secondP.innerHTML = newText;
}
p {
position: relative;
border: 1px solid black;
border-radius: 1em;
padding: 1em;
margin: 3em 1em;
}
p::after {
content: attr(name);
display: block;
background-color: white;
color: green;
padding: 0 0.5em;
position: absolute;
top: -0.6em;
left: 0.5em;
}
#fixed span {
display: inline-block;
width: 1em;
text-align: center;
}
<p id="variable" name="Variable Width">It might not look nice, but with a little Javascript, I can force a variable width font to act like a fixed-width font.</p>
<p id="fixed" name="Fixed Width">It might not look nice, but with a little Javascript, I can force a variable width font to act like a fixed-width font.</p>
In a paragraph with regular text, it looks terrible, but There are instances when this makes sense. Icon fonts and Unicode symbols could both make use of this technique.
I found this question while trying to find a solution for Unicode symbols that were shifting regular text to the right when they were replaced with other Unicode symbols.
I've done a verry pretty thing sometimes for countdowns:
HTML:
<div class="counter">
<span class="counter-digit counter-digit-0">2</span>
<span class="counter-digit counter-digit-1">4</span>
<span class="counter-digit counter-digit-divider">/</span>
<span class="counter-digit counter-digit-2">5</span>
<span class="counter-digit counter-digit-3">7</span>
</div>
SCSS:
$digit-width: 18px;
.counter {
text-align: center;
font-size: $digit-width;
position: relative;
width : $digit-width * 4.5;
margin: 0 auto;
height: 48px;
}
.counter-digit {
position: absolute;
top: 0;
width: $digit-width;
height: 48px;
line-height: 48px;
padding: 0 1px;
&:nth-child(1) { left: 0; text-align: right; }
&:nth-child(2) { left: $digit-width * 1; text-align: left;}
&:nth-child(3) { left: $digit-width * 2; text-align: center; width: $digit-width / 2} // the divider (/)
&:nth-child(4) { left: $digit-width * 2.5; text-align: right;}
&:nth-child(5) { left: $digit-width * 3.5; text-align: left;}
}
You can wrap the seconds digits in a span and style it like...
.time-seconds {display: inline-block;width: .52em;text-align: center;}
See Snippet.
function padlength(what) {
var output = (what.toString().length == 1) ? "0" + what : what;
return output;
}
function displaytime() {
var serverdate = new Date();
var dd = "am";
var hh = serverdate.getHours();
var h = hh;
if (h >= 12) {
h = hh - 12;
dd = "pm";
}
if (h == 0) {
h = 12;
}
h = parseInt(h);
var sec = String(padlength(serverdate.getSeconds()));
var timeFixed = h + ':' + padlength(serverdate.getMinutes()) + ':<span class="time-seconds">' + sec.charAt(0) + '</span><span class="time-seconds">' + sec.charAt(1) + '</span> ' + dd;
timeVariable = h + ':' + padlength(serverdate.getMinutes()) + ':' + sec + ' ' + dd;
document.getElementById("servertime-fixed").innerHTML = timeFixed;
document.getElementById("servertime-variable").innerHTML = timeVariable;
}
window.onload = function() {
displaytime();
setInterval("displaytime()", 1000);
};
center {
font-size: 3em;
font-family: Cursive;
}
.time-seconds {
display: inline-block;
width: .52em;
text-align: center;
}
<html>
<body>
<center id="servertime-fixed">H:MM:SS mm</center>
<center id="servertime-variable">H:MM:<span class="time-seconds">S</span><span class="time-seconds">S</span> mm</center>
</body>
</html>
i just had the same problem. my font didn't support font-variant-numeric: tabular-nums (which i knew about) and the other solutions didn't suit me, so i came up with this one - in my case i just had to expand letter spacing and then squash the (gigantic) zeros to make it look acceptable:
CSS:
.squashzeros { letter-spacing:.2em; }
.squashzeros span { display:inline-block; margin:0 -.09em; }
JS:
document.querySelectorAll('.squashzeros').forEach((o)=>{
o.innerHTML = o.innerText.replaceAll(/0/g,'<span>0</span>');
});
unfortunately i found no css-only solution.
No, not unless it's an actual mono-spaced font.
A mix of answers from Márton Tamás and nïkö:
document.querySelectorAll('pre').forEach( o => {
o.innerHTML = o.innerText.replace(/(.)/g, '<i>$1</i>');
});
pre i {
font-style: normal;
font-family: serif;
display: inline-block;
width: 0.65em;
text-align: center;
}
<!-- Fixed-width serif -->
<pre>
. i I 1 | This is gonna be awesome. 12:10
ASDFGHJK | This is gonna be awesome. 08:51
</pre>
<!-- Default font -->
. i I 1 | This is gonna be awesome. 12:10
<br>
ASDFGHJK | This is gonna be awesome. 08:51
No, there is no way to force anything in CSS. And there isn’t even a way to suggest that a non-monospace font be rendered as a monospace font.

Can we write selectors by only name of elements in CSS File

Can we write selectors by only name
For example,
<div name= "outer-name">
<img name="inner-image" src="images/ine.jpg" alt"" />
</div>
I want to take style of inner-mage in css file like [outer-name] [inner-image]
In CSS file
[outer-name] [inner-image] {
/*styles*/
}
I cant take selector as [outer-name] img etc .. only selecting by name
You can use attribute selectors:
[name="outer-name"] [name="inner-image"]
But keep in mind that name is not a valid attribute for <div> or <img>, even though the above selector will work. It's best that you either change them to classes, or if you're using HTML5, add the data- prefix to them, so it looks like this:
<div data-name= "outer-name">
<img data-name="inner-image" src="images/ine.jpg" alt"" />
</div>
Then use this selector:
[data-name="outer-name"] [data-name="inner-image"]
Given the following html:
<div data-name="something">
<p>Content in 'something'</p>
<span data-someAttribute="someAttribute">Content in 'someAttribute' div.</span>
</div>
And the CSS:
[data-name] {
background-color: red;
}
[data-name] [data-someAttribute] {
display: block;
background-color: #ffa;
}
This is perfectly valid (or, at least, it's implemented in Chromium 14/Ubuntu 11.04). I've changed from using name attributes (since they're invalid for div elements, or other non-form elements), and used, instead, data-* prefixed custom attributes, which are valid in HTML5 and, while perhaps not 'valid' in HTML 4, they seem to be understood by those browsers still.
JS Fiddle demo.
It's worth noting that you can also use attribute=equals notation, to select only certain elements based on the value of their data-* attributes:
<div data-name="something">
<p>Content in data-name='something' element.</p>
<span data-someAttribute="someAttribute">Content in 'someAttribute' div.</span>
</div>
And the CSS:
[data-name] {
background-color: red;
}
[data-name="something"] {
font-weight: bold;
}
[data-name] [data-someAttribute] {
background-color: #ffa;
text-decoration: underline;
font-weight: normal;
}
JS Fiddle demo.
Also, if CSS3 is an option for you, it's possible to use attribute-begins-with (^=) notation:
[data-name] {
background-color: red;
}
[data-name^="s"] {
font-weight: bold;
}
[data-name] [data-someAttribute] {
background-color: #ffa;
text-decoration: underline;
font-weight: normal;
}
JS Fiddle demo.
And attribute-ends-with ($=) notation:
[data-name] {
background-color: red;
}
[data-name$="ing"] {
font-weight: bold;
}
[data-name] [data-someAttribute] {
background-color: #ffa;
text-decoration: underline;
font-weight: normal;
}
References:
data-* attributes (W3.org).
data-* attributes, (HTML5 Doctor).
attribute-equals selector (W3.org).
attribute-starts-with, and attribute-ends-with selectors (W3.org).
As #Bolt said, name isn't valid there (yet it still works on my browser). You can use the HTML5 data- properties. Here's a fiddle showing how it's done.
The real solution here would be to use classes, but I assume you have a reason for not using them.

Resources