I'm trying to find a CSS selector for an element that is the first child, taking any text nodes into account that might come before it (i.e. if any elements come before, possibly unwrapped text nodes, this is no longer considered the first child).
But it seems :first-child does not include text nodes, neither does :nth-child, etc.
This is where I'm at, but it's not working:
.red-if-not-first {
color: red;
font-weight: bold;
}
.red-if-not-first:first-child {
color: green;
}
<p>
Lorem ipsum. <span class="red-if-not-first">This should be red, not green, because some content comes before it.</span> Eum natus culpa officia a molestias, sed beatae aut in autem architecto iure repellat quam placeat, expedita maxime laborum necessitatibus repudiandae. Corrupti!
</p>
<p>
<span class="red-if-not-first">This is rightly green, not red, because it's first bit of content in this paragraph.</span> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eum natus culpa officia a molestias, sed beatae aut in autem architecto iure repellat quam placeat, expedita maxime laborum necessitatibus repudiandae. Corrupti!
</p>
Unfortunately I have little control over the markup.
I'm aware this has been asked before, but that was 3 years ago, which is as good as a thousand years in front-end!
If, for some strange reason, you can make do with only supporting Gecko, you can use-moz-first-node selector to do this.
https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-first-node
One workaround could be to make use of the :empty pseudo class. You will need more markup though.
p .red-if-not-first {
color: red;
font-weight: bold;
}
p > :empty + .red-if-not-first {
color: green;
}
<p>
<span>Lorem ipsum.</span> <span class="red-if-not-first">This should be red, not green, because some content comes before it.</span> Eum natus culpa officia a molestias, sed beatae aut in autem architecto iure repellat quam placeat, expedita maxime laborum necessitatibus repudiandae. Corrupti!
</p>
<p>
<span></span> <span class="red-if-not-first">This is rightly green, not red, because it's first bit of content in this paragraph.</span> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eum natus culpa officia a molestias, sed beatae aut in autem architecto iure repellat quam placeat, expedita maxime laborum necessitatibus repudiandae. Corrupti!
</p>
In essence, you're asking if text can affect the styling of dom elements and the answer is - no, because text is not a dom element of it's own.
We can prove this with a simple experiment. Just add a marker element at the beginning of the paragraph and then use a sibling selector to override color. You'll see that this works in both cases, because text has no effect on surrounding dom flow.
For the record, I thought I was onto something by initially doing this marker experiment with ::before pseudo elements but they can't be used with sibling selectors either. Pseudo elements are not real elements and will have no effect on the relationships of actual dom tree.
.red-if-not-first {
color: red;
font-weight: bold;
}
.red-if-not-first:first-child {
color: green;
}
.marker + span{
color: red;
}
<p>
<i class="marker"></i>
Lorem ipsum. <span class="red-if-not-first">This should be red, not green, because some content comes before it.</span> Eum natus culpa officia a molestias, sed beatae aut in autem architecto iure repellat quam placeat, expedita maxime laborum necessitatibus repudiandae. Corrupti!
</p>
<p>
<i class="marker"></i>
<span class="red-if-not-first">This is rightly green, not red, because it's first bit of content in this paragraph.</span> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eum natus culpa officia a molestias, sed beatae aut in autem architecto iure repellat quam placeat, expedita maxime laborum necessitatibus repudiandae. Corrupti!
</p>
This is 2017. The answer is "No". There is no such CSS selector that can help you with this.
Related
This question already has answers here:
nth-of-type vs nth-child
(7 answers)
Closed 3 years ago.
I'm messing around with trying to target the first <p> tag in a div that has a data attribute of data-item="8"
So far, I've tried this:
[data-item="8"] p:first-child {
font-size: 1.8rem;
}
as well as this:
p:first-child [data-item="8"]{
font-size: 1.8rem;
}
and it's not picking up on the style change. Not sure if I am going about this all wrong or if I am missing something where that's not going to work.
HTML:
<div data-item="8">
<h3>Test</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse ut aliquid perspiciatis a aliquam repellat non ipsum necessitatibus distinctio quos molestias asperiores quis eaque, laudantium ipsam nulla adipisci quo nemo!</p>
<p>Quam soluta quis doloribus, ut cum iste cumque earum aliquam ratione! Fugiat nemo animi ut corrupti tempora, omnis nulla. Culpa a quibusdam sequi quia totam dolores magni ducimus nesciunt expedita.</p>
</div>
Here you go man. Just the wrong css selector.
https://codepen.io/jackgisel/pen/dyPxrOG
[data-item="8"] p:first-of-type {
...
}
This question already has answers here:
What does a space mean in a CSS selector? i.e. What is the difference between .classA.classB and .classA .classB? [duplicate]
(3 answers)
Closed 3 years ago.
I'm trying to position the first text on entire row, second on half of the row and third on the other half of the row but I don't know why doesn`t work
.news-content{
display:grid;
grid-template-columns:repeat(3,1fr);
grid-template-rows:repeat(3,1fr);
}
.news-content.butoane{
grid-row:1/3;
grid-column:1/3;
}
.news-content.imagine{
grid-row:2/3;
grid-column:1/2;
}
.news-content p{
grid-row:2/3;
grid-column:2/3;
}
<div class="news-content">
<div class="butoane">
<button>Butonul1</button>
<button>Butonul2</button>
<p>FIRST TEXT FIRST TEXT sit amet consectetur adipisicing elit. Tenetur, ipsa! efgkermgmergmermgergmerirmg</p>
</div>
<div class="imagine">
<p> SECOND TET SECOND TEXT amet consectetur adipisicing elit. Harum deserunt perspiciatis autem aspernatur! Eum, a facilis qui maxime esse omnis consectetur tempore quisquam veritatis tenetur repudiandae, modi, fuga placeat est.</p>
</div>
<p>LAST TEXT LAST TEXT sit amet consectetur adipisicing elit. Cum, praesentium laboriosam obcaecati quae officia officiis voluptatem quia illum dicta mollitia itaque. Veniam labore quo itaque molestias quaerat, omnis cupiditate numquam!</p>
</div>
It doesnt work because of your css selectors, .news-content.butoane selects an element with those two classes, .news-content .butoane selects .butoane inside .news-content
.news-content{
display: grid;
grid-template-columns:repeat(3,1fr);
grid-template-rows:repeat(3,1fr);
}
.news-content .butoane{
grid-row:1/3;
grid-column:1/3;
}
.news-content .imagine{
grid-row:2/3;
grid-column:1/2;
}
.news-content p{
grid-row:2/3;
grid-column:2/3;
}
https://jsfiddle.net/wwWaldi/hy4pbnzx/1/
On a project I'm working on, there are a few places where there are two columns of text. As this is content manageable, I don't really want to make two separate text areas for the user to fill out, but rather one which I split into two columns with column-count: 2 in CSS. The content will be inside a single p element.
The issue is that I need to style the second column slightly differently. I need to change text-align to right, whilst keeping the first column text-align left.
I know I could do this in PHP and/or JavaScript, but I'd prefer to do this using CSS alone if possible.
Markup:
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab nostrum delectus iste sit officia! Molestiae ducimus, sunt omnis earum, vitae vel dolore blanditiis placeat, porro aliquid, non repudiandae recusandae quisquam sit enim. Aliquid placeat, obcaecati autem aut. Eum eaque nemo, voluptas repellat ab recusandae, culpa eos quam voluptates, molestias expedita ipsum debitis dolorem atque explicabo labore consequuntur cumque adipisci quos eveniet error. Sint, provident cum. Totam, nisi, quo. Hic, fugit, iusto. Veniam est nulla, debitis commodi provident fugiat quam earum incidunt, cum vel minima ipsum magnam cupiditate tenetur autem obcaecati aliquam soluta, repellat in quibusdam illo! Dicta numquam, saepe corrupti.</p>
</div> <!-- /.content -->
CSS:
.content p {
column-count: 2;
}
As of now, there is no way to target columns in pure CSS. The closest you could get is using JavaScript to split it with new elements, or amend your markup.
This has been asked similarly before: https://stackoverflow.com/a/21238260/271271
Can you try using this:
table.secondcolumn td:nth-child(2) { text-align: left; }
or alternatively try this SO link
EDIT/Update: Apparently, there are no direct ways (via CSS) to style a specific text column via CSS.
I try to select the red-colored paragraph and apply border to it. Why this piece of code is not working?
p[color="red"] {
border: 1px solid black;
}
<p style="color: green;">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae, provident, nam, et, consectetur molestiae aspernatur ratione placeat dignissimos odio cum non eveniet adipisci voluptas doloribus fugiat maiores odit sint repellat.</p>
<p style="color: yellow;">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae, provident, nam, et, consectetur molestiae aspernatur ratione placeat dignissimos odio cum non eveniet adipisci voluptas doloribus fugiat maiores odit sint repellat.</p>
<p style="color: lime;">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae, provident, nam, et, consectetur molestiae aspernatur ratione placeat dignissimos odio cum non eveniet adipisci voluptas doloribus fugiat maiores odit sint repellat.</p>
<p style="color: darkgray;">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae, provident, nam, et, consectetur molestiae aspernatur ratione placeat dignissimos odio cum non eveniet adipisci voluptas doloribus fugiat maiores odit sint repellat.</p>
<p style="color: red;">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae, provident, nam, et, consectetur molestiae aspernatur ratione placeat dignissimos odio cum non eveniet adipisci voluptas doloribus fugiat maiores odit sint repellat.</p>
<p style="color: cyan;">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae, provident, nam, et, consectetur molestiae aspernatur ratione placeat dignissimos odio cum non eveniet adipisci voluptas doloribus fugiat maiores odit sint repellat.</p>
<p style="color: indigo;">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae, provident, nam, et, consectetur molestiae aspernatur ratione placeat dignissimos odio cum non eveniet adipisci voluptas doloribus fugiat maiores odit sint repellat.</p>
Am I missing something?
fiddle: https://jsfiddle.net/kLx1gcq0/
[] is a attribute selector, so you would have to select the style attribute like:
p[style*="color: red"] {
border: 1px solid black;
}
JSFiddle Demo
*= selects the element if the attribute contains the string specified. An excellent article about CSS selectors can be found here.
That works, but only if there is a whitespace. If you don't know if it will have a whitespace or not, you could do it like:
p[style*="color: red"],
p[style*="color:red"] {
border: 1px solid black;
}
It doesn't work since color is not an HTML attribute, which is what [color=...] matches against.
In general, inline styling is deprecated. You should use CSS for styling and the common practice is to use classes.
Try this instead:
p.red {
color: red;
border: 1px solid black;
}
p.green {
color: green;
}
p.yellow {
color: yellow;
}
p.lime {
color: lime;
}
<p class="green">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae, provident, nam, et, consectetur molestiae aspernatur ratione placeat dignissimos odio cum non eveniet adipisci voluptas doloribus fugiat maiores odit sint repellat.</p>
<p class="yellow">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae, provident, nam, et, consectetur molestiae aspernatur ratione placeat dignissimos odio cum non eveniet adipisci voluptas doloribus fugiat maiores odit sint repellat.</p>
<p class="lime">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae, provident, nam, et, consectetur molestiae aspernatur ratione placeat dignissimos odio cum non eveniet adipisci voluptas doloribus fugiat maiores odit sint repellat.</p>
<p class="red">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repudiandae, provident, nam, et, consectetur molestiae aspernatur ratione placeat dignissimos odio cum non eveniet adipisci voluptas doloribus fugiat maiores odit sint repellat.</p>
The selector p[color="red"] isn't working because the element doesn't have a color attribute. Since you're trying to match based on the style attribute, your selector could be:
Example Here
p[style="color: red;"] {
border: 1px solid black;
}
However, it's worth mentioning that this will match the attribute's value exactly, so it likely won't work all the time. You could match based on whether the value contains color: red:
p[style*="color: red"] {
border: 1px solid black;
}
However, that may not work if whitespace varies or if the value is background-color: red. Of course you could select all the different variants, but if you can, I would highly suggest avoid using the attribute selector like this. Classes are better suited for this sort of thing.
The attribute selectors are designed to identify HTML attributes, not CSS properties. The following may work however (untested):
p[style*="color: red;"] {
border: 1px solid black;
}
<p style="color: green;">Green text</p>
<p style="color: yellow;">Yellow text</p>
<p style="color: lime;">Lime text</p>
<p style="color: darkgray;">Dark gray text</p>
<p style="color: red;">Red text</p>
<p style="color: cyan;">Cyan text</p>
<p style="color: indigo;">Indigo text</p>
The selector is wrong. p[color="red"] means "a P element that have an attribute "color" with a value of "red"... but you have "style" attribute, not "color".
Take a look to css selectors: http://www.w3.org/TR/css3-selectors/#selectors
Yeah, so simple mistake. Obviously, color is not an html attribute.
Working solutions:
p[style*="color"][style*="red"] {
border: 1px solid black;
}
p[style*="color: red"],
p[style*="color:red"] {
border: 1px solid black;
}
Special, thanks to Jacob Gray
Let's say I have this html:
<p class="test">foo</p>
<p class="test">bar</p>
Is there a way I can make it only select the first line. So the css would be something along the lines of
.test:(text="foo") {
}
but only using css?
Edit: Sadly it cannot be done with pure css.
thanks anyways
If you have multiple elements:
<p class="test">foo</p>
<p class="test">bar</p>
<p class="test">zed</p>
and want to select the first one, then you can use :first-child selector:
.test:first-child {
color: red;
}
You can check the jsFiddle demo.
If you have one element:
<p class="test">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ratione, quis, expedita, illo adipisci voluptates minus labore ex quos aspernatur impedit rerum nam! Officiis quas nam fugiat illum maiores repellat voluptas. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ratione, quis, expedita, illo adipisci voluptates minus labore ex quos aspernatur impedit rerum nam! Officiis quas nam fugiat illum maiores repellat voluptas. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ratione, quis, expedita, illo adipisci voluptates minus labore ex quos aspernatur impedit rerum nam! Officiis quas nam fugiat illum maiores repellat voluptas.</p>
and want to select the first line, then you can use :first-line selector:
.test:first-line {
color: red;
}
You can check the jsFiddle demo.
If you want to select your element, based on the content within it, it not possible by CSS, you must javascript for it, for example jQuery has one implementation:
<div>John Resig</div>
<div>George Martin</div>
<div>Malcom John Sinclair</div>
<div>J. Ohn</div>
<script>
$("div:contains('John')").css("text-decoration", "underline");
</script>
:contains() Selector - jQuery API Documentation
*EDIT: Question-asker doesn't want first-child, and instead wants it to be based on a string, which you cannot do with pure CSS. The following answer is for first-child implementation *
This answer is for first-child:
If it's only ever going to be the first one you need the :first-child pseudo-element.
There is also last-child and nth child, but :First-child is the one that's safe to use in IE8 and earlier, but you have to have a doctype:
http://www.w3schools.com/cssref/sel_firstchild.asp
http://quirksmode.org/css/selectors/firstchild.html
What you'd need to do is something like this:
p:first-child {
/* CSS Styles */
}
Here is a fiddle with it working:
http://jsfiddle.net/shayl/KwWjt/