:first-letter selector doesn't work for link - css

The :first-letter pseudo-element selector works perfectly for a <p> element but not for links. This, for instance, has no effect:
a:first-letter
{
font-size:200%;
text-transform:uppercase;
color:#8A2BE2;
}
Why? How can I make the first-letter style different for an <a> element

According to the W3 spec, the :first-letter pseudo-element only work for a block element, which a is not.
Oddly, *:first-letter caused the first letter to transform, at Chrome 14 and Firefox 3.6.23. Fiddle: http://jsfiddle.net/8W7FF/3/

Check the specification. As of now, inline elements are not supported by ::first-letter:
In CSS, the ::first-letter pseudo-element applies to block-like containers such as block, list-item, table-cell, table-caption, and inline-block elements.
Note: A future version of this specification may allow this pseudo-element to apply to more display types.
https://www.w3.org/TR/selectors-3/#application-in-css
Thus, if you try to style the ::first-letter of something that isn't a "block-like container", like an inline element, it won't work. This doesn't just apply to links; you'll also find that, by default, you can't style the ::first-letter of a span either, as shown below:
div::first-letter, span::first-letter, a::first-letter {
font-size:200%;
text-transform:uppercase;
color:#8A2BE2;
}
<div>I'm a div</div>
<span>I'm a span</span>
I'm an anchor
A possible fix to this is to turn the element into a block container by, for instance, setting it to display: block or display: inline-block. Below is an example, using the former for the span and the latter for the a:
div::first-letter, span::first-letter, a::first-letter {
font-size:200%;
text-transform:uppercase;
color:#8A2BE2;
}
span {
display: block;
}
a {
display: inline-block;
}
<div>I'm a div</div>
<span>I'm a span</span>
I'm an anchor

Related

Div with CSS content, after pseudo element is not visible

I have a POC that I have to complete and I am only allowed to use CSS to update the styles of a product. I have replaced one of the images of the product with a logo by using the CSS content attribute.
I have to add a simple string with a phone number to be shown after this logo. I have tried to use the :after pseudo-element to do this. This works only if the content of the div is empty (logo is removed).
.demo {
content: url('http://placehold.it/350x150')
}
.demo:after {
content: 'test';
display: inline-block;
}
<div class="demo"></div>
I have tried changing the display to inline-block and hard coding the heightand width for both rules. Essentially everything I could find. Any help would be greatly appreciated.
JSFiddle here: https://jsfiddle.net/qykbjznm/
The content property replaces all content within the element. By adding content to a non-pseudo selector, that content will replace the ::before and ::after pseudo selector.
So try doing this using the content property within the ::before and ::after pseudo selectors only.
.demo:before {
content: url('http://placehold.it/350x150')
}
.demo:after {
content: 'some text';
display: block;
}
<div class="demo"></div>
You could replace the background from the CSS and put it as an image in the HTML:
.demo::after {
content: 'test';
display: inline-block;
}
<div class="demo">
<img src='http://placehold.it/350x150'/>
</div>
Or even do this:
.demo {
background: url('http://placehold.it/350x150');
height:150px;
width:350px;
}
.demo::after {
content: 'test';
}
<div class="demo"></div>
There are two different results.
Some browsers apply the content property to actual elements, despite it not being supported in CSS2. css-content-3 is expected to allow this, but until the level 3 spec becomes a standard, which realistically won't happen for another few years (especially considering it hasn't happened in the last 14 years), applying content to actual elements should be considered non-standard behavior.
When the value of the content property is an image, that image is inserted as replaced content. And when this is applied to an actual element, this prevents the element from having ::before and ::after pseudo-elements. This is why your ::after pseudo-element doesn't appear.
As mentioned, all you have to do is apply the image to the element's ::before pseudo-element, not the element itself.
I have messed around with your JSFiddle a bit and I found that the only real way of making the phone number display below the current div is by creating another div:
<div class="demo"></div>
<div class="demo2"></div>
<style>
.demo {
content: url('http://placehold.it/350x150');
height:150px;
width:350px;
}
.demo2:before {
content: "test";
}
</style>

CSS: Does the plus sign work with pseudo elements?

For markup similar to this:
<div>
<p>hello world</p>
</div>
<div>
<h4>hello world</h4>
</div>
Can you do something like this in CSS:
div:after {
content: "";
display: block;
border-bottom: 2px solid red;
}
p + div:after {
content: "";
display: block;
border-bottom: 2px solid blue;
}
...meaning to say "Give all :after pseudo elements immediately following a <p> a blue border. Give all others a red border".
This doesn't seem to work. I realize this is because the + sign is applying to the 'div' selector, not the 'div:after' selector as a whole. But is there another way to target these in CSS (without adding a new class specific to these instances and without manipulating the DOM)?
Basically, what Michael_B said:
You can't target a pseudo-element. A pseudo-element is added to a selector that has matched an element.
"Target" is a vague term, but the second sentence is on point here. Combinators only work with elements, because selectors match elements, not pseudo-elements. What you're really trying to do in selector nomenclature is to style the ::after pseudo-element of a div whose last child is a p element (in which case the ::after box immediately follows the p box in the formatting tree):
<div>
<p>hello world</p>
div::after <!-- Blue border -->
</div>
<div>
<h4>hello world</h4>
div::after <!-- Red border -->
</div>
And you can't do that, because there is no parent selector.
I imagine something like div:has(> p:last-child)::after from Selectors 4 will work, but it depends on whether :has() makes it into CSS in the first place. The only other good option is to figure out which of these div elements has a p as their last child and assign them a special class name.
See also:
Can I target a :before or :after pseudo-element with a sibling combinator?
Is there a CSS parent selector?

How to select first character of <i> which is inside a <p> tag

I'm trying something like below,
p+i:first-letter
{
background-color:red;
}
or
p i:first-letter
{
background-color:red;
}
on html snippet like this
<p>
<i> Sample text</i>
</p>
:first-letter does not work on inline elements such as a i. :first-letter works on block elements such as a paragraph, table caption, table cell, list item, or those with the inline-block property applied.
<div>
<p>
<i>Sample text</i>
</p>
</div>
css
i { display: inline-block; }
div p:last-child i:first-child:first-letter { font-weight: bold }
Check jsfiddle
A first line has only meaning in a block-container box, therefore the ::first-letter pseudo-element has only an effect on elements with a display value of block, inline-block, table-cell, list-item or table-caption. In all other cases, ::first-letter has no effect.
https://developer.mozilla.org/en-US/docs/CSS/::first-letter

What CSS selector can be used to select the first div within another div

I have something like:
<div id="content>
<h1>Welcome to Motor City Deli!</h1>
<div style=" font-size: 1.2em; font-weight: bolder;">Sep 19, 2010</div>
<div > ... </div>
What is the css selector for the second div (1st div within the "content" div) such that I can set the font color of the date within that div?
The MOST CORRECT answer to your question is...
#content > div:first-of-type { /* css */ }
This will apply the CSS to the first div that is a direct child of #content (which may or may not be the first child element of #content)
Another option:
#content > div:nth-of-type(1) { /* css */ }
You want
#content div:first-child {
/*css*/
}
If we can assume that the H1 is always going to be there, then
div h1+div {...}
but don't be afraid to specify the id of the content div:
#content h1+div {...}
That's about as good as you can get cross-browser right now without resorting to a JavaScript library like jQuery. Using h1+div ensures that only the first div after the H1 gets the style. There are alternatives, but they rely on CSS3 selectors, and thus won't work on most IE installs.
The closest thing to what you're looking for is the :first-child pseudoclass; unfortunately this will not work in your case because you have an <h1> before the <div>s. What I would suggest is that you either add a class to the <div>, like <div class="first"> and then style it that way, or use jQuery if you really can't add a class:
$('#content > div.first')

Prevent linebreak after </div>

Is there a way to prevent a line break after a div with css?
For example I have
<div class="label">My Label:</div>
<div class="text">My text</div>
and want it to display like:
My Label: My text
display:inline;
OR
float:left;
OR
display:inline-block; -- Might not work on all browsers.
What is the purpose of using a div here? I'd suggest a span, as it is an inline-level element, whereas a div is a block-level element.
Do note that each option above will work differently.
display:inline; will turn the div into the equivalent of a span. It will be unaffected by margin-top, margin-bottom, padding-top, padding-bottom, height, etc.
float:left; keeps the div as a block-level element. It will still take up space as if it were a block, however the width will be fitted to the content (assuming width:auto;). It can require a clear:left; for certain effects.
display:inline-block; is the "best of both worlds" option. The div is treated as a block element. It responds to all of the margin, padding, and height rules as expected for a block element. However, it is treated as an inline element for the purpose of placement within other elements.
Read this for more information.
.label, .text {display: inline}
Although if you use that, you might as well change the div's to span's.
A DIV is by default a BLOCK display element, meaning it sits on its own line. If you add the CSS property display:inline it will behave the way you want. But perhaps you should be considering a SPAN instead?
<span class="label">My Label:</span>
<span class="text">My text</span>
try this (in CSS) for preventing line breaks in div texts:
white-space: nowrap;
The div elements are block elements, so by default they take upp the full available width.
One way is to turn them into inline elements:
.label, .text { display: inline; }
This will have the same effect as using span elements instead of div elements.
Another way is to float the elements:
.label, .text { float: left; }
This will change how the width of the elements is decided, so that thwy will only be as wide as their content. It will also make the elements float beside each other, similar to how images flow beside each other.
You can also consider changing the elements. The div element is intended for document divisions, I usually use a label and a span element for a construct like this:
<label>My Label:</label>
<span>My text</span>
div's are used to give structure to a website or to contain a lot of text or elements, but you seem to use them as label, you should use span, it will put both text next to eachother automatically and you won't need to wright css code for it.
And even if other people tell you to float the elements it's best that you just change the tags.
I don't think I've seen this version:
<div class="label">My Label:<span class="text">My text</span></div>
<div id="hassaan">
<div class="label">My Label:</div>
<div class="text">My text</div>
</div>
CSS:
#hassaan{ margin:auto; width:960px;}
#hassaan:nth-child(n){ clear:both;}
.label, .text{ width:480px; float:left;}
Try applying the clear:none css attribute to the label.
.label {
clear:none;
}
use this code for normal div
display: inline;
use this code if u use it in table
display: inline-table;
better than table
try float your div's in css
.label {
float:left;
width:200px;
}
.text {
float:left;
}
I have many times succeeded to get div's without line breaks after them, by playing around with the float css attribute and the width css attribute.
Of course after working out the solution you have to test it in all browsers, and in each browser you have to re-size the windows to make sure that it works in all circumstances.
display: inline-block worked for me

Resources