Capitalize first letter of an inline element's text - html

I read elsewhere that the following should capitalize the first letter of the text of an inline element (e.g. a <span>).
However, if you run the code snippet you'll see that it doesn't work. If I replace the <span> with a <div> it works, but is there a way to capitalize the first letter without changing the element type?
.list .capitalize:first-letter {
text-transform: capitalize;
display: inline-block;
}
<div class="list">
<span class="capitalize">capitalize me</span>
</div>

The pseudo element ::first-letter only works if the parent element is a block element, so the span must be inline-block:
.list .capitalize {
display: inline-block;
}
.list .capitalize::first-letter {
/* you could use capitalize as well, but since it's just one letter, just use uppercase on it */
text-transform: uppercase;
}
<div class="list">
<span class="capitalize">capitalize me</span>
</div>

Span has not default display, so you have to set it to block or something else
And it's not correct to set display property of first-letter, you should do it for entire class
.list .capitalize{
display: block;
}
.list .capitalize::first-letter {
text-transform: uppercase;
}
<div class="list">
<span class="capitalize">capitalize me</span>
</div>

You need to make the span itself display: inline-block - not the ::first-letter pseudo element.
.list .capitalize {
display: inline-block;
}

Related

Use CSS :not() to target selected content in an element

I have a .header div with a span maindomain and a div otherdomains inside of it:
<div class="header"><span class="maindomain">LatestFooty.co.uk</span> is currently available for sale, along with:
<div class="otherdomains">
LatestFootie.com<br>
LatestFootie.co.uk
</div>
</div>
I'm trying to target the is currently available for sale, along with:, without touching the contents of .maindomain or .otherdomains. I understand that the best approach to this might be to wrap it in a span and target that instead, but at this point I'd like to figure out why I can't get the :not pseudo-class working.
Here is what I have:
#media (min-width:300px) and (max-width:450px) {
.header:not(.maindomain):not(.otherdomains) {
font-style: italic;
}
}
As far as I can tell, the syntax is correct, and I don't think it's a specificity issue because !important doesn't make a difference. What am I doing wrong?
.header:not(.maindomain):not(.otherdomains) only targets elements which have the .header class and don't have the .maindomain and/or the .otherdomain class themselves.
Your rules currently say:
<div class="header"> is targeted
<div class="header maindomain"> is not targeted
<div class="header otherdomains"> is not targeted
<div class="header maindomain otherdomains"> is not targeted
But this is not what you want to do here obviously.
You cannot apply rules to the .header class depending on classes of its children with CSS alone.
There's an approved answer to your question here which might guide you in the right direction (using JavaScript or jQuery in that case).
You will need two selectors:
.header {
font-style:italic;
}
.header .otherdomains,
.header .maindomain {
font-style:initial;
}
/* OR
.header * {
font-style:initial;
}
*/
<div class="header"><span class="maindomain">LatestFooty.co.uk</span> is currently available for sale, along with:
<div class="otherdomains">
LatestFootie.com<br>
LatestFootie.co.uk
</div>
</div>
I'm trying to target the "is currently available for sale, along with:", without touching the contents of .maindomain or .otherdomains.
You can't target anonymous elements in CSS.
CSS rules need a "hook" in the HTML to attach to. That hook is an HTML tag. Without the tag, CSS has nothing to target. This concept applies across box models.
From MDN:
An anonymous box is created when there is not an HTML element to use for the box. This situation happens when, for example, you declare display: flex on a parent element, and directly inside there is a run of text not contained in another element. In order to fix the box tree, an anonymous box is created around that run of text. It will then behave as a flex item, however, it cannot be targeted and styled like a regular box because there is no element to target.
(emphasis mine)
Everything is in the demo itself, the JavaScript is for demo purposes.
Demo
const lnx = [...document.links];
lnx.forEach(lnk => lnk.addEventListener('click', viewHTML));
function viewHTML(e) {
const link = e.target;
const headers = document.querySelectorAll('.'+this.dataset.tag);
headers.forEach(hdr => {
if (!hdr.matches('.hide')) {
link.className = 'off';
let str = hdr.outerHTML;
let txt = document.createElement('div');
txt.className = 'txt';
hdr.insertAdjacentElement('afterend', txt);
hdr.nextElementSibling.insertAdjacentText('beforeend', str);
hdr.classList.add('hide');
} else {
link.className = '';
hdr.classList.remove('hide');
hdr.nextElementSibling.remove();
}
});
}
body {
font: 400 2.5vw/1.5 Consolas
}
[class^=header] {
font-family: Arial;
}
/* Header (OP)
Selector fails -- :not() is prefixed incorrectly
.header:... means .header is targeted
.header :... means the descendants of .header is targeted
There is no .header.A, .header.B, nor .header.A.B
so .header without .A and/or .B will have everything in italics
*/
.header:not(.A):not(.B) {
font-style: italic;
}
/* Header 1
Best solution with no extra HTML tags:
Assign font-style: normal...
directly (.C1, .D1)
or by class (.N)
*/
.header1 {
font-style: italic;
}
.C1,
.D1,
.N {
font-style: normal;
}
/* Header 2
Using :not() needs extra HTML tag:
Wrap second textnode in an inline or inline-block tag
As content of a descendant tag, the text can be targeted
*/
.header2 *:not(.E):not(.F) {
font-style: italic;
}
/* Header 3
Smart solution with extra HTML tag:
Wrap second textnode in <i> or <em>
*/
.header3 {
/* no styles needed */
}
/* Header 4
Slickest solution with least HTML:
Wrap text that needs italics in <i> and then style lines with CSS
*/
.header4 {
white-space: pre-line;
}
/* For Demo Purposes */
.dash {
border-style: dashed;
}
.edge {
border-style: ridge;
border-width: 3px;
}
summary:hover {
color: lime;
background: #000;
cursor: pointer;
}
summary + u {
display: inline-block;
text-decoration: none;
white-space: pre-line;
}
code {
color: green;
background: rgba(0, 0, 0, 0.2);
white-space: pre;
}
summary + code {
display: block;
}
a {
display: block;
text-decoration: none;
text-align: center;
}
a:link,
a:visited {
color: cyan;
background: #000;
}
a:hover,
a:active {
color: blue;
background: none;
}
a::before {
content: 'View .'attr(data-tag);
}
a.off::before {
content: 'Hide .'attr(data-tag);
}
a::after {
content: ' HTML';
}
.hide {
display: none;
}
.txt {
color: blue;
background: rgba(0, 0, 0, 0.2);
white-space: pre;
}
<main>
<hr class='edge'>
<details><summary>Header (OP)</summary>
<u>Selector fails -- :not() is prefixed incorrectly
.header:... means .header is targeted 👎
.header<code>&blank;</code>:... means the descendants of .header is targeted 👍
There is no .header.A, .header.B, nor .header.A.B so
.header <em>without</em> .A and/or .B will have everything in italics</u></details>
<details><summary>CSS</summary>
<code>.header:not(.A):not(.B) {
font-style: italic;
}</code>
<a href='#/' data-tag='header'></a>
</details>
<hr>
<div class='header'>
<span class="A">LatestFooty.co.uk</span> is currently available for sale, along with:
<div class="B">
LatestFootie.com<br> LatestFootie.co.uk
</div>
</div>
<hr class='edge'>
<details><summary>Header 1</summary>
<u>Best solution with no extra HTML tags:
Assign <code>font-style: normal</code>...
directly (.C1, .D1)
or by class (.N)</u></details>
<details><summary>CSS</summary>
<code>.header1 {
font-style: italic;
}
.C1,
.D1,
.N {
font-style: normal;
}</code>
<a href='#/' data-tag='header1'></a>
</details>
<hr>
<div class="header1">
<span class="C1">LatestFooty.co.uk</span> is currently available for sale, along with:
<div class="D1">
LatestFootie.com<br> LatestFootie.co.uk
</div>
</div>
<hr class='dash'>
<div class="header1">
<span class="C2 N">LatestFooty.co.uk</span> is currently available for sale, along with:
<div class="D2 N">
LatestFootie.com<br> LatestFootie.co.uk
</div>
</div>
<hr class='edge'>
<details><summary>Header 2</summary>
<u>Using :not() needs extra HTML tag:
Wrap second textnode in an inline or inline-block tag
As content of a descendant tag, the text can be targeted</u></details>
<details><summary>CSS</summary>
<code>.header2 *:not(.E):not(.F) {
font-style: italic;
}</code>
<a href='#/' data-tag='header2'></a>
</details>
<hr>
<div class='header2'>
<span class="E">LatestFooty.co.uk</span> <span>is currently available for sale, along with:</span>
<div class="F">
LatestFootie.com<br> LatestFootie.co.uk
</div>
</div>
<hr class='edge'>
<details><summary>Header 3</summary>
<u>Smart solution with extra HTML tag:
Wrap second textnode in <code><i></code> or <code><em></code></u></details>
<details><summary>CSS</summary>
<code>.header3 {
/* no styles needed */
}</code>
<a href='#/' data-tag='header3'></a>
</details>
<hr>
<div class='header3'>
<span class="G">LatestFooty.co.uk</span> <i>is currently available for sale, along with:</i>
<div class="H">
LatestFootie.com<br> LatestFootie.co.uk
</div>
</div>
<hr class='edge'>
<details><summary>Header 4</summary>
<u>Slickest solution with least HTML:
Wrap text that needs italics in <code><i></code> and then style lines with CSS</u></details>
<details><summary>CSS</summary>
<code>.header4 {
white-space: pre-line;
}</code>
<a href='#/' data-tag='header4'></a>
</details>
<hr>
<header class='header4'>LatestFooty.co.uk <i>is currently available for sale, along with:</i>
LatestFootie.com
LatestFootie.co.uk
</header>
</main>

Changing <span> without effecting <span class="something">

I have a problem to change <span> in CSS without changing anything on <span class="something">
HTML
<span class="something">Some text</span>
<span>Another text</span>
CSS
span.something {
color: #FFF;
}
span {
display: block;
}
I'm expecting that all other <span> will have the style of display:block except for <span class="something">. Appreciate if anyone could help me on this. Thanks!
I think you are looking for the :not selector which you can use as
span:not(.something) {
display: block;
}
The css negation pseudo-class is what you want.
span.something {
color: #FFF;
}
span:not(.something) {
display: block;
}

Heading elements on same line without breaks

I have a line of code which is styled using CSS. I wanted it to appear on a single line.
<style>
.thumb {
text-shadow:2px 2px #FF0000;
white-space: nowrap;
}
.click {
font-style: oblique;
}
</style>
<h2 class="click">
Click a <h3 class="thumb">thumbnail image</h3> to see it enlarged
</h2>
I have tried using the below code:
<h2 class="click">
Click a <span style="text-shadow:2px 2px #FF0000">thumbnail image</span> to see it enlarged
</h2>
It worked but I wanted to know is there any other way to perform this task?
<h3> is a block-level element. If you need to display it on the same line, you should change its default display type to inline or inline-block.
<h2 class="click">
Click a <h3 class="thumb">thumbnail image</h3> to see it enlarged
</h2>
h3.thumb {
text-shadow:2px 2px #FF0000;
white-space: nowrap; /* Is this really needed?? */
display: inline; /* Or inline-block */
}
Also note that, white-space is to handle the white space inside the element; Not around the element itself.
You can specify the display as inline:
<style>
.thumb {
text-shadow:2px 2px #FF0000;
white-space: nowrap;
display: inline;
}
.click {
font-style: oblique;
}
</style>
<h2 class="click">Click a <h3 class="thumb">thumbnail image</h3> to see it enlarged</h2>
However, note that h2 and h3 tags are designed for block-level header hierarchies. For something you want to display within the same line, span is usually more appropriate.
More info on the purpose of heading tags: http://accessibility.psu.edu/headingshtml

Why does the text in the span tags not center?

I am not exactly sure why the text does not center in the title class span.
<div id="vid_display">
<span class="title">SampleText</span></br>
<span class="desc">Sample Desc</span>
</div>
Stylesheet
#vid_display {
height: 500px;
width: 700px;
box-shadow: 10px 10px 5px #888;
}
.title {
font-family: cursive;
font-size: 20px;
font-style: bold;
text-align: center;
}
text-align doesn't have any effect on inline elements like span tags. You need to apply your text-alignment onto the parent element that is display:block; like the <div> or <p> that is wrapping the span.
You might be better off with something like this:
HTML
<div id="vid_display">
<p class="title">SampleText</p>
<p class="desc">Sample Desc</p>
</div>
CSS
.title { text-align: center; }
Update: Here is a working sample: http://codepen.io/anon/pen/jEnys
is an inline element and not a block. Use div instead:
<div id="vid_display">
<div class="title">SampleText</div><br>
<span class="desc">Sample Desc</span>
</div>
Use
<div class="title">SampleText</div></br>
The <span> tag is used to group inline-elements in a document.
The <span> tag provides no visual change by itself.
<span> defaults to being display:inline; whereas <div> defaults to being display:block;.

CSS display multiple span/textboxes inline

I have the following code:
<div class="filter-field">
<span class="filter-title">Number From</span>
<span class="filter-control">
<dx:ASPxTextBox ID="FilterNumberFrom" runat="server" />
</span>
<span class="filter-extension">To</span>
<span class="filter-control">
<dx:ASPxTextBox ID="FilterNumberTo" runat="server" />
</span>
</div>
and this stylesheet:
.filter-field {
height: 20px;
display: inline;
}
.filter-title {
width:90px;
display: inline;
padding-right:10px;
}
.filter-extension {
width: 40px;
display: inline;
padding-left: 10px;
padding-right: 10px;
}
.filter-control {
display: inline;
}
but each span is displayed on a new line like this:
Number From
TextBox
To
TextBox
when it's supposed to be something like
Number From [space] TextBox [more
spaces] To [space] TextBox
How can I achieve this through css without changing the tags I'm using? (actually read: without using tables.)
What you have displays inline already, you have some other CSS (that has a more specific selector) creating the block type display. Or...the textboxes (whatever the rendered version looks like) are display: block; themselves.
Those custom ASP textboxes are almost certainly rendering the textbox within a <div>. Adding this to your CSS should do the trick:
.filter-control * { display:inline !important;}
If that textbox control accepts the CssClass attribute, you could also try
.inline { display:inline; }
<dx:ASPxTextBox ID="FilterNumberXXXXXX" runat="server" CssClass="inline" />
Wrap your text in a block-level element such as a paragraph or heading:
<div class="filter-field">
<p>
<span class="filter-title">Number From</span>
<span class="filter-control">
<dx:ASPxTextBox ID="FilterNumberFrom" runat="server" />
</span>
<span class="filter-extension">To</span>
<span class="filter-control">
<dx:ASPxTextBox ID="FilterNumberTo" runat="server" />
</span>
</p>
</div>
Your styles shouldn't need to be set to inline if they're spans, so your CSS becomes:
.filter-field {
height: 20px;
}
.filter-title {
width:90px;
padding-right:10px;
}
.filter-extension {
width: 40px;
padding-left: 10px;
padding-right: 10px;
}
.filter-control {
}
At worst, you might replace your display: inline; declarations with float: left; but I don't see why you'd need to.
If you are still having problems, I would suggest your span styles are probably inheriting a display: block; property from elsewhere in your CSS.
Try
.filter-field {
height: 20px;
display:block;
overflow:hidden;
}
The problem might be that you actually don't mean to display a box (div) but a paragraph (p). You can do the following and it should work.
In your styles:
.filter-field span{
padding-right:10px;
}
In your markup:
<p class="filter-field">
<span class="filter-title">Number From</span>
<span class="filter-control">
Hello
</span>
<span class="filter-extension">To</span>
<span class="filter-control">
Goodbye
</span>
</p>
Also remember that CSS inherits rules, so the problem could be somewhere else. Using Firebug or any other browser inspection tool could de helpful to determine what's going on.
Use firebug to check which rules are being applied to your elements. As Nick suggested there is probably a more specific selector adding a display: block style to the spans that should be inline by default.
If there is a specific rule (based on an id) you can make your rules more specific by:
Adding an id to your div and making your css rules apply to that id
Finding the applied rule, to which ID it refers, and making your CSS rules apply to that ID:
#the_id .filter-field span {
display: inline;
}