Is it possible to group selector with :not() negation pseudo-class? - css

Is it possible to group selectors (e.g. p, li) with :not() negation pseudo-class? (Something like this, just to give an idea):
p, li a:not(.tags, .promo):link{
border-bottom: 1px solid;
padding: 0 0 0.06rem 0
}
p, li a:not(.tags, .promo):visited,
p, li a:not(.tags, .promo):hover,
p,li a:not(.tags, .promo):active {
border-bottom: 1px solid #ccc
}
Please note: not multiple arguments, but group the p and li.

It's not possible to combine multiple HTML tags with a pseudo-class like not() with pure CSS.
Note: I say pure, since using a CSS pre-processor like Sass, this would be possible
The only way of achieving the same, with fewer lines of CSS is to apply a class to the elements you wish to include
So instead of
p a:not(.something),
li a:not(.something) {
color: red;
}
Use a class:
.target:not(.something) {
color: red;
}
<p class='target'>
<a>Link</a>
</p>
<ol class='target'>
<li>
<a>Link</a>
</li>
</ol>

Related

Is conditional CSS possible?

Is it possible to give a particular styling to a child element only if say odd number of child elements are present? Let me elaborate.
I have a
<ul>
tag which gets dynamically populated with data as
<li>
child nodes. I want to apply a styling to the last element, say if only 3 child nodes are present or there are odd numbers. My present requirement is only for three child nodes. I know it is possible to do it easily with JavaScript, but I need a pure CSS solution.
You can combine :nth-last-child() and :nth-child()
li:nth-last-child(1):nth-child(odd) {
background-color: red;
}
li:nth-last-child(1):nth-child(odd) {
background-color: red;
}
<ul>
<li>x</li>
<li>x</li>
<li>x</li>
</ul>
vs
li:nth-last-child(1):nth-child(odd) {
background-color: red;
}
<ul>
<li>x</li>
<li>x</li>
<li>x</li>
<li>x</li>
</ul>
You can achieve this by combining the :last-child pseudo-class with the :nth-child selector.
To select the last element only when a specific number of elements are present, use that number for :nth-child:
*{color:#fff;font-family:sans-serif;font-size:14px;list-style:none;margin:0;padding:0;}
li{
background:#000;
height:20px;
line-height:20px;
margin:2px;
padding:0 2px;
}
li:last-child:nth-child(3){
background:#f00;
}
hr{margin:10px 2px;}
<ul><li></li><li></li><li>I'm red</li></ul>
<hr>
<ul><li></li><li></li><li></li><li>I'm not</li></ul>
To select the last element only when an odd number of elements are present, use odd for :nth-child:
*{color:#fff;font-family:sans-serif;font-size:14px;list-style:none;margin:0;padding:0;}
li{
background:#000;
height:20px;
line-height:20px;
margin:2px;
padding:0 2px;
}
li:last-child:nth-child(odd){
background:#f00;
}
hr{margin:10px 2px;}
<ul><li></li><li></li><li>I'm red</li></ul>
<hr>
<ul><li></li><li></li><li></li><li>I'm not</li></ul>

Is it possible to append CSS transform properties using Sass? [duplicate]

Is it possible, in Sass, to manipulate a value a given element already inherits?
I am aiming for something like this:
body
color: blue
.warning
color: red
strong
color: darken(inherit,20)
Inheritance
No. Sass doesn't 'know' what selector to inherit the color from. It would have to know that strong is a descendant of body. That seems like a reasonable enough assumption for you and I since strong is not allowed outside of the body, but that sort of assumption cannot be made about most selectors. Sass would also have to know that there are no cascades happening from other ancestor elements.
ul {
color: red;
}
ol {
color: blue;
}
li {
// which color do I inherit from ????
}
Well can I specify which selector I want to copy from?
Sass does not grant access to the values of any previously declared variables in any fashion, either. There is no way to specify "be darker than the body's color". CSS rules are not objects or mappings and are not accessible in any way. Your case may be simple, but consider a more complex case like this:
.foo {
background: mix(white, blue); // fallback for non-rgba browsers
background: rgba(blue, .5);
.baz & {
background: yellow;
}
#media (min-width 30em) {
background: orange;
}
#supports (flex-wrap: wrap) {
background: red;
}
}
.bar {
// access which background color from .foo ????
}
Well what can I do?
You'll either need to use variables or it has to be a feature of vanilla CSS to do what you want.
Old-Fashioned CSS
Some properties can give the illusion of being generated/inherited dynamically using stuff that's been supported by browsers for years:
ul.one {
background: white;
}
ul.two {
background: yellow;
}
ul {
background: rgba(0, 120, 255, .2);
padding: 1em;
}
<ul class="one">
<li><ul>
<li><ul>
<li>Foo</li>
</ul></li>
</ul></li>
</ul>
<ul class="two">
<li><ul>
<li><ul>
<li>Foo</li>
</ul></li>
</ul></li>
</ul>
CSS Variables
Generating CSS variables is about as close as you're going to get to being able to manipulate an inherited property. Browser support isn't quite there yet (check caniuse), but here's what that would look like:
Sass:
ul {
--list-color: orange;
--darker-color: darken(orange, 15%);
color: var(--list-color);
}
ol {
--list-color: green;
--darker-color: darken(green, 10%);
color: var(--list-color);
}
li {
background: var(--darker-color);
}
Output:
ul {
--list-color: orange;
--darker-color: #b37400;
color: var(--list-color);
}
ol {
--list-color: green;
--darker-color: #004d00;
color: var(--list-color);
}
li {
background: var(--darker-color);
}
<ul>
<li>Foo</li>
</ul>
<ol>
<li>Bar</li>
</ol>
If you're using a browser that supports CSS variables, the result should look like this:
I was looking for the same thing, and came across this. Your question was answered, but it didn't solve the problem.
Here's the solution: http://codepen.io/monsto/pen/tiokl
If your HTML was this:
<div class="main">
<header class="header">
<div class="warning">
<p><strong>Danger,</strong> Will Robinson!</p>
</div>
</header>
</div>
Then using SASS you could do this:
$bg: #f88;
#mixin colorize {
$bg: darken($bg,15%) !global; // !global flag required for 3.4 or later, remove if using 3.3 or older
background: $bg;
}
.warning {
background: $bg;
p {
#include colorize;
strong {
#include colorize;
}
}
}
SASS seems to have no idea of the results of it's output. Therefore, inherit means nothing to it. You're basically asking it to know what the output is before it's output.
It does however know it's variables as, by default, they're tightly scoped.
From the docs:
Variables are only available within the level of nested selectors where they’re defined. If they’re defined outside of any nested selectors, they’re available everywhere.
AND THEN variables in mixins:
The block of content passed to a mixin are evaluated in the scope where the block is defined, not in the scope of the mixin.
This allows the above mixin to take a known variable, defined in the parent level, and redefines it for the current level and available to it's children. It's like doing $x = $x + 1 inside a multi-nested loop
TBPH, this rather changes the way I think about SASS. It's clearly a lot more programmatic than I thought.
Given that an element cannot have multiple of the same properties that combine and the fact that inherit can't know what the current rendered state is, your options are to
1) Keep track of the past transforms yourself using SASS variables: Demo
.parent {
$firstTrans: translateX(50%);
transform: $firstTrans;
.child {
/* Old followed by new */
transform: $firstTrans rotate(10deg);
}
}
2) Apply the transform to a parent (perhaps adding another container if needed): Demo
3) Use Javascript to combine the current transform with the one you want to add (this is the only way you can make sure to remove the transform applied to the parent if that's desired): Demo
Note: This answer is from a merged post because of this meta post.
This answers addresses the darken function specifically: A possible alternative is using the CSS brightness() filter instead of SASS's (or LESS's) darken() function. You will basically need to wrap the color inside a span tag so the filter would not affect other elements.
Simple demo:
.red {color: red}
.blue {color: blue}
.green {color: green}
span {
display: inline-block;
padding: 1em;
}
.darken span {
-webkit-filter: brightness(0.4);
filter: brightness(0.4);
}
<span class="red">Red</span>
<span class="blue">Blue</span>
<span class="green">Green</span>
<div class="darken">
<span class="red">Red</span>
<span class="blue">Blue</span>
<span class="green">Green</span>
</div>
jsFiddle: https://jsfiddle.net/azizn/hhorhz9s/
You need to keep in mind browser compatibility, it should work for IE Edge, latest Firefox and Chrome. See caniuse or MDN for more information.
In the case of a background darken, you could use a pseudo selector with opacity or add a semi-transparent black PNG background-image.

Why directly defined CSS class not applies?

If I have this list:
<ul class="parent">
<li class="child">li1</li>
<li>li2</li>
<li>li3</li>
</ul>
Now if I apply
.parent li {
background-color: blue;
}
.child {
background-color: red;
}
then the red background is ignored. Don't want to make it !important, but understand why class not work. If I change these selectors either to ul li & .child , or extend them to .parent li & .parent .child , then background applies. So maybe simple question: is there any rule, why this selector must be defined with a "full path"? Why it's not working when defined directly only with the class name ?
The answer lies in CSS selector specificity. Short version: the most-specific selector wins.

How to style the vertical bar i.e. "|"?

How do I style the vertical bar i.e. "|"? I need to vary the width and the height of the "|".
This is what I am trying to do.
Link 1 | Link 2
Put it in an element, and style the element:
<span class="bar">|</span>
In your style sheet, for example:
.bar { font-size: 20px; }
You shouldn't be using the pipe (|) as a separator, use css instead.
Say the anchors were in a div, with id equal to breadcrumbs, like this:
<div id="breadcrumbs">
One
Two
Three
</div>​
You could then add separators between them with a couple css rules, like this:
#breadcrumbs a {
padding: 0.5em;
border-right: 5px solid green;
}
#breadcrumbs a:last-child {
border-right: none;
}​
You could vary the size, style and color of the separator with the border-right: 5px solid green rule. Here's an example(updated) in action. Here's some documentation on border styling.
The second rule with :last-child prevents an extra separator after the last element.
To vary the height of the separator, you would change the padding on the first rule.
By popular demand, a list version:
If you put the links in a list:
<ul id="breadcrumb-list">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>​
And use rules like this:
ul#breadcrumb-list li {
display: inline-block;
margin: 0;
padding: 1em 1em 0 1em;
border-right: 1px dotted blue;
}
ul#breadcrumb-list li:last-child {
border-right: none;
}
You can use a ul to markup your list of links for better semantics. You have to add the inline-block to put them on one line, li is by default a block level element.
I've also shown a different style you can achieve by varying the padding and border rules.
| is a character, and as such, takes any stylings that you might apply to text. I get the impression though, that you might be trying to use | to construct a box border. If that is the case, you're much better off styling a block level element to have a border that attempting to use characters.
You can't really style individual characters easily with css, unless that's the only character in your element. If it's in a textarea you have no hope. If it isn't, you have hope: you have to manually augment it with <span class="specialBar">...</span> tags whenever it occurs in the text you want to style it in.
You can also just use another unicode vertical-bar character which is more to your liking.
edit, In response to:
"I basically wanted a seprator between links. Am i going in the wrong direction? – original poster"
Ideally you would use spans, which you can shape with CSS to emulate a thin vertical line:
emulate-with-a-span technique - (live demo):
.linkSeparator {
display:inline-block;
margin-bottom:-1em; /*value should be (height-1em)/2*/
height:3em; width:0.25em;
background-color:grey;
margin-left:0.5em; margin-right:0.5em;
}​
link1<span class="linkSeparator"></span>link2<span class="linkSeparator">...
images technique:
You could also use images (less elegant, won't go into detail).
sibling selector technique - (live demo):
You can also set the border-left on all links which aren't the first. According to the w3c spec on CSS2 adjacency selectors, "E + F Matches any F element immediately preceded by a sibling element E." Therefore:
.separatedLinks a+a {
border-left: 2px solid black;
}
<??? class="separatedLinks">
link1
link2
link3
</???>
You might be able to find more examples at this google hit: http://meyerweb.com/eric/articles/webrev/200007a.html

How can i overwrite the parent Style to an element

<div class="jqueryslidemenu">
<ul>
<li class="menuitem">TEST1</li>
<li class="navOFFTDDisabled" id="TEST2">TEST2</li>
<li class="navOFFTDDisabled" id="TEST3">TEST3</li>
<li class="navOFFTDDisabled" id="TEST4">TEST4</li>
</ul>
</div>
CSS FILE
.jqueryslidemenu ul li {
display: block;
background: #FFCC00;
color: white;
padding: 4px 12px 6px 5px;
border-right: 1px solid #778;
color: #2d2b2b;
text-decoration: none;
font-weight: bold;
cursor: hand;
}
.navOFFTDDisabled{
//Aplly Style
}
I cannot Apply class="navOFFTDDisabled" to each (li) Items because the "jqueryslidemenu" is overwriting the navOFFTDDisabled style .How can i apply both styles
Make it a better match,
.jqueryslidemenu ul li.navOFFTDDisabled{
//I'm more important neener neener.
}
Just to be more useful, you can actually calculate which selector with take precedence as described in the specification
You have three possibilities to override a selector:
order of the selector: a selector further down in your stylesheet overrides a selector that is further to the top
selector specifity: http://www.w3.org/TR/CSS2/cascade.html and http://www.molly.com/2005/10/06/css2-and-css21-specificity-clarified/
basically it depends on how many tags, classes and ids you have in your selector. classes add more weight than tags and ids add more weight than classes
the last thing you can do is to add an !importantto your style rule, which overrides any other selector. To be correct you can still have more !importantrules, than the selector specifity rule comes into play again. E.g. .klass{color:red !important}

Resources