Conditional styles with css custom properties - css

I enjoy using css custom properties, but there's this thing that I often find that I wish I could do.
I wish to be able to apply some styles conditionally based on the value of a css custom property. Here's some pseudo-code:
.something {
border: var(--is-dark-theme) ? 1px solid : none;
}
I understand that custom properties do not work like this. But may be there is some other way that I'm not aware of that could help me achieve a similar result?
Or perhaps there is some spec proposal that would this possible in the future?

Here is another idea similar to Ori Drori answer where I rely on the use of an invalid value inside border to remove the border. This can be useful in case you want to use keywords like false/true/yes/no
.something {
border: var(--is-dark-theme,2px) solid black;
}
<div class="something">Dark theme</div>
<div class="something" style="--is-dark-theme: false">Light theme</div>

You can sometimes use calc() to get roughly similar results. In this case if --is-dark-theme is 0 or 1, you can multiply it by the width of border, to show or hide it:
.something {
border: calc(var(--is-dark-theme) * 1px) solid black;
}
<div class="something" style="--is-dark-theme: 1">Dark theme</div>
<div class="something" style="--is-dark-theme: 0">Light theme</div>

In cases where you have something like "condition xyz is on or off" (like in the light theme vs dark theme example) you can use the following CSS trick (I know this looks completely weird if you see this trick for the first time, but in contrast to the tricks presented in the other answers, this one will work for all CSS properties):
For each on/off condition define two custom properties, one for the 'on' case, one for the 'off' case. Instead of on use the value initial, instead of off use value (space character).
.light-theme {
--is-light-theme: initial;
--is-dark-theme: ;
}
.dark-theme {
--is-light-theme: ;
--is-dark-theme: initial;
}
div {
font-family: Helvetica, Arial, sans-serif;
padding: 1rem;
color:
var(--is-light-theme, black)
var(--is-dark-theme, white);
background-color:
var(--is-light-theme, white)
var(--is-dark-theme, black);
border:
var(--is-light-theme, none)
var(--is-dark-theme, 5px solid #aaa);
}
<div class="light-theme">
light theme
</div>
<div class="dark-theme">
dark theme
</div>

Just FYI: The following is not working today (2023-02-06), but someday in future there might be this very nice CSS feature called "CSS style container queries":
/* not working today (2023-02-06), maybe in future */
#container style(--theme: dark) {
.box {
border: 1px solid #aaa;
}
}

Related

What does '--' dash dash mean in CSS property value

I bought a website template which used -- in their CSS property value. This gives the errors property value expected and at-rule or selector expected. I know of -- being used in for CSS property but never for property value. What does the -- used here mean?
.my-sm-nn1 {
margin-top: --0.25rem !important;
}
The use is absolutely useless. If you try run your code you will see the browser ignores it, it looks like:
Sorry to say, but unfortunately you bought a template which is not perfectly clean. This can happen. Maybe it was just a typo by the developer, maybe he didn't care. Hopefully the rest of your template works as expected.
You can run the code and try yourself. The line margin-top: --0.25rem !important; will just be ignored by any browser.
.outer {
background-color: orange;
border: solid 1px black;
}
.inner {
background-color: yellow;
border: solid 1px fuchsia;
margin-top: --0.25rem !important;
}
<div class="outer">
<div class="inner">
</div>
</div>
Note: if you wonder why is there now more CSS then in your question: I like to add background-colors and borders to elements to be 100% sure that some rules do or do not effect any styling of the elements.

Using an xp:checkBoxGroup and trying to put a simple box border around all the values

It seems the only option available today is border=x where x is the thickness of the border. It looks really ugly as it outlines each choice in the group.
I want a simple border around all the choices. When I go into debug it I can manually add fram="box" to the generated Table html and it looks great.
I can't figure out how to add frame="box" to the xp:checkBoxGroup I've tried using attributes without success.
Any ideas?
If you use a xp:checkBoxGroup the XPages runtime puts the checkboxes in table cells and wraps it with a fieldset element. You can easily target that using some CSS. That's how I would solve this.
If you want a simple border around your checkbox group you can do this:
<style>
fieldset.xspCheckBox {
border: 1px solid #333333;
}
</style>
<xp:checkBoxGroup id="checkBoxGroup1">
<xp:selectItem
itemLabel="Blue"
itemValue="blue">
</xp:selectItem>
<xp:selectItem
itemLabel="Green"
itemValue="green">
</xp:selectItem>
</xp:checkBoxGroup>
Or if you want a border around every option you can use this:
<style>
fieldset.xspCheckBox {
border: 0;
}
fieldset.xspCheckBox label {
border: 1px solid #444444;
padding: 5px;
cursor: pointer;
}
fieldset.xspCheckBox label:hover {
background: #eeeeee;
}
</style>
(note that the :hover class isn't really necessary, but adds a hover effect to all options: depending on your browser requirements that might not be supported)
Just add a style with a border definition to your xp:checkBoxGroup:
<xp:checkBoxGroup id="..." value="..." style="border:1px solid black;">
...
</xp:checkBoxGroup>
Instead of putting the style directly into xp:checkBoxGroup definition you can use a css class.

Changing checkbox layout without using label

Is it possible to change the layout of a checkbox without adding the label tag in CSS?
Things like this do not have any effect:
input[type=checkbox][disabled] {
background-color: green;
border: 10px solid red;
}
The only thing I found so far is how to change the opacity.
I'm not sure if this will be much use to you, but it does allow you to "style up" a checkbox without the need for a label. I've remove the disabled flag so you can swap between the different styles. Shouldn't be difficult to add it back in if this will work for you.
Fiddle is here.
input[type=checkbox]:checked:before {
background-color: green;
border: 10px solid red;
}
input[type=checkbox]:before {
content:'';
display:block;
height:100%;
width:100%;
border: 10px solid green;
background-color: red;
}
The above only works on Chrome, however, it seems like Chrome is in the wrong where the specification is concerned.
A fuller answer here: CSS content generation before or after 'input' elements
As of today there is no solution, if we assume a cross browser functional styling, to style the <input type="checkbox" > alone, other than a few properties like opacity, width, height, outline (and maybe a few more).
Using a label (or other content elements) is what you need to do that and here is a good (which this question is likely a duplicate of) post with lots of options: How to style checkbox using CSS?
Note: If you know more properties, feel free to update this answer.

CSS Best Practice/Newbie Question

Ok, a really quick question - which is the best way out of these to apply css styles:
1 - Use lots of different classes that apply different parts of the style i.e. class='font-1 red-bkg border-1' etc etc.
Or
2 - Style up individual parts of the site seperately
What you should do for font for example is to apple it to body, same for background colour, font colour etc...
body{font: Verdana 38px; color: #000; background: #fff;}
Then for individual features (e.g. margins, padding, borders etc) they should be defined in a per-class way.
.classname {
margin: 0px 5px 10px 5px;
padding: 10px 5px 10px 6px;
}
It is better for maintainability and makes your HTML less messy.
I believe to justify shared classes you should have more than one property in it, otherwise you are not gaining anything from using CSS's modularity.
I.e. things like this are not good ideas:
.bold { font-weight: bold; }
Style up individual parts of the site seperately. The other solution would kind of screw the intention behind it - separating content from styling.
Seems like you will enjoy this read, I certainly did:
http://net.tutsplus.com/tutorials/html-css-techniques/30-css-best-practices-for-beginners/
You should name logically classes, because when you change your layout and currently you have style like
.bold .5px-brd .red.bg
then changing this to another colour and style will include grep'ing through entire application code in order to correct css styles.
As you may notice approach like
.bold .5px-brd .red.bg
it's good, and don't go with philosophy of CSS.
Classes with name like
.bold
should be used as auxiliary style. Never as basic construction block.
http://jsfiddle.net/sheriffderek/RMfEn/
html
<section class='container blocks'>
<h2>Blocks of content</h2>
<div class='block highlight-theme'>
<p>None of the styling should be done in the html.</p>
</div>
<div class='block base-theme'>
<p>You can use modular classes to style common pieces of the layout and then modify them with more specific classes.</p>
</div>
<div class='block contrast-theme'>
<p>So the stuff in this box could be a dark-theme with .contrast-theme or something</p>
</div>
</section>
css
.container, .block { /* structural elements */
width: 100%;
float; left;
padding: .5rem;
overflow: hidden; /* use a clear-fix instead */
}
/* mini themes /// mix and match */
.base-theme {
background: lightgray;
color: black;
}
.highlight-theme {
background: yellow;
color: red;
}
.contrast-theme {
background: gray;
color: white;
}

Removing underline from specific anchor tag

Why does the following anchor tag has text underlined?
.pagerLink {
background-color: #E4F5F8;
border: 1px solid #C0DEED;
text-decoration: none;
}
<a class="pagerLink" href="#">test</a>
Probably because another style block has better precedence than your pagerLink class. Try:
.pagerLink {
background-color: #E4F5F8;
border: 1px solid #C0DEED;
text-decoration: none !important;
}
use text-decoration:none for a in your styles
Ex:
<head>
<style>
.pagerLink
{
background-color: #E4F5F8;
border:1px solid #C0DEED;
}
.pagerLink a
{
text-decoration:none !important;
}
</style>
</head>
<body>
<div class="pagerLink">
test
</div>
</body>
You can use firebug(a firefox plugin) to findout which style is being used for the element now and whether its being overwritten by some other style definition
http://getfirebug.com/
I cant yet leave comments and I respect this is an old question but be extremely careful when using !important in your declarations:
text-decoration: none !important;
You'll probably get away with it in smaller projects but with any non-trivial project that involves collaboration from multiple sources this sort of thing can be incredibly annoying when it over-rides a property I need to set further down the line. Not only do I have to change this to make my fix stick but I also have to check that changing it does not break anything else, which it probably will.
Better is to refactor your declaration or restructure your code so that you dont need to use !important and only fall back to !important when you cant.
To remove underline you need to follow following style code snippet.
.pagerLink{
background-color: #E4F5F8;
border:1px solid #C0DEED;
text-decoration:none !important;
}

Resources