How can I simplify these CSS selectors? - css

I have some code that I think may be bulky and could be simplified. I haven't found anything that helps in my situation. I am trying to make it so that when I hover over a div, an h2 and p get underlined. It works fine like this:
.test:hover h2, .test:hover p {
text-decoration: underline;
}
But I was wondering if I could simplify it in some way, not having to repeat .test:hover twice.

If you don't need to support Internet Explorer this can be accomplished with the :is pseudo-class:
.test:hover :is(h2, p) {
text-decoration: underline;
}
<div class="test">
<h1>An H1</h1>
<h2>An H2</h2>
<p>A paragraph</p>
</div>
An alternative would be to leverage a CSS preprocessor like Sass or Less, both of which support nesting which can make for DRY-er, more expressive style source code. This may be overkill in your case, though. Here's an example in Sass' SCSS format:
.test:hover {
h2, p {
text-decoration: underline;
}
}

There is a new pseudo-class :is which will allow this..
The :is() CSS pseudo-class function takes a selector list as its argument, and selects any element that can be selected by one of the selectors in that list.
.test:hover :is(h2, p) {
color: red;
text-decoration: underline;
}
<div class="test">
<h2>Heading</h2>
</div>
<div class="test">
<p>Lorem ipsum dolor sit amet.</p>
</div>

You can use it:
:is(h1, p) .test:hover {
text-decoration: underline;
}

Related

Is there better syntax for selecting multiple sub-elements? [duplicate]

I have some code that I think may be bulky and could be simplified. I haven't found anything that helps in my situation. I am trying to make it so that when I hover over a div, an h2 and p get underlined. It works fine like this:
.test:hover h2, .test:hover p {
text-decoration: underline;
}
But I was wondering if I could simplify it in some way, not having to repeat .test:hover twice.
If you don't need to support Internet Explorer this can be accomplished with the :is pseudo-class:
.test:hover :is(h2, p) {
text-decoration: underline;
}
<div class="test">
<h1>An H1</h1>
<h2>An H2</h2>
<p>A paragraph</p>
</div>
An alternative would be to leverage a CSS preprocessor like Sass or Less, both of which support nesting which can make for DRY-er, more expressive style source code. This may be overkill in your case, though. Here's an example in Sass' SCSS format:
.test:hover {
h2, p {
text-decoration: underline;
}
}
There is a new pseudo-class :is which will allow this..
The :is() CSS pseudo-class function takes a selector list as its argument, and selects any element that can be selected by one of the selectors in that list.
.test:hover :is(h2, p) {
color: red;
text-decoration: underline;
}
<div class="test">
<h2>Heading</h2>
</div>
<div class="test">
<p>Lorem ipsum dolor sit amet.</p>
</div>
You can use it:
:is(h1, p) .test:hover {
text-decoration: underline;
}

CSS h1-h3 color in .class

My code is
.simple-text h2 {color:red;}
.simple-text h3 {color:red;}
.simple-text h4 {color:red;}
<div class="simple-text">
<h1>Header 1</h1>
<h2>Header 2</h2>
<h3>Header 3</h3>
</div>
How to write short css?
.simple-text h1,h2,h3 {color:red;}
Don't work
I need all Headers in DIV with class "simple-text" were red
With plain CSS you're limited to:
.simple-text h1,
.simple-text h2,
.simple-text h3 {
color: red;
}
<div class="simple-text">
<h1>Header 1</h1>
<h2>Header 2</h2>
<h3>Header 3</h3>
</div>
Are you tried this ?
.simple-text h1,.simple-text h2,.simple-text h3 {color:red;}
I'm afraid there's no "short" way to do this in plain CSS. I would suggest you check out LESS though. It's a CSS Preprocessor that adds just this kind of thing. In LESS you can do the following:
.simple-text
{
h1,h2,h3,h4,h5,h6
{
color:red;
}
}
There's also lots more in LESS. There are other preprocessors like SASS, too. I recommend doing your homework, they can save you lots of time.
move the headers within the .simple-text css class
.simple-text {
h1, h2, h3 {
color: red;
}
}
EDIT: I misread the question. This is SASS.

LESS target every element of type unless it's within certain div

I'm looking for a neat way to solve the given problem:
Let's say we have an article, and I want to style every h1, h2 in unless they are located in the <div ="example">
<article class="article">
<h1>Direct Child 1</h1>
<h2>Direct Child 2</h2>
<div class="example">
<h1>Example Child 1</h1>
<h2>Example Child 2</h2>
</div>
<div class="other-div">
<h1>Indirect Child 1</h1>
<h2>Indirect Child 2</h2>
</div>
</div>
Now in pure CSS the solution is simple:
.article > h1,
.article *:not(.example) h1 {
color: red;
}
.article > h2,
.article *:not(.example) h2 {
color: blue;
}
All h1s are red, and h2s are blue, unless they're within <div class=example>" - Pen
In LESS, however, I can't find a clean way to do this.
.article {
& :not(.example) {
h1 {
color: red;
}
h2 {
color: blue;
}
}
}
I'm looking for a way to add <div class=article>" direct child h1s and h2 into the mix while keeping it DRY.
I guess the main show-stopper for your attempt is the limitation of Less requiring a selector combinator (like >) to always go before a selector element (so neither & > nor > alone can work).
There's workaround however:
.article {
#-: ~'>';
#{-}, *:not(.example) {
h1 {color: red}
h2 {color: blue}
}
}

<h2> class inheriting from general <h2>

I know many inheritance questions have been asked, but each case is unique and I'm having trouble with this one.
I have some h2 elements that need to have unique styling to them but they keep inheriting properties from previously defined h2 elements.
I've tried giving them a unique class, I've tried defining css properties through JS and Jquery, nothing's working.
Here's an example of what I'm talking about:
<div class="parent">
<h2>Original H2</h2>
<div class="child">
<h2>New H2</h2>
</div>
</div>
.parent h2 {
font-weight:bold;
color:red;
}
.child h2 {
font-weight:normal;
color:green;
}
Even with giving the child's h2 tag a unique class I get nowhere.
<div class="parent">
<h2>Original H2</h2>
<div class="child">
<h2 class="newh2class">New H2</h2>
</div>
</div>
.parent h2 {
font-weight:bold;
color:red;
}
.child h2.newh2class {
font-weight:normal;
color:green;
}
<!--or-->
h2.newh2class {
font-weight:normal;
color:green;
}
Can anyone help out?
you need to use !important value to make it so.
h2.newh2class {
font-weight:normal;
color:green !important;
}
You css should look like this
.parent > h2 {
font-weight:bold;
color:red;
}
.child h2 {
font-weight:normal;
color:green;
}
check it here http://jsfiddle.net/yNFUd/
Your issue is CSS because of how your are referencing the element. Read about stacking and precedence in CSS
http://jsfiddle.net/feitla/SmUGm/2/
.parent > h2 {
font-weight:bold;
color:red;
}
.parent .child h2 {
color:blue;
}
.child > h2 {
font-weight:normal;
color:green;
}
Changing the order and how they are called will affect how they are inherited and calculated.

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