CSS conditions - if element has both classes - css

How to make conditions in a CSS stylesheet?
Here I got a stylesheet.. But if the div.menu_active is added on an element the class has to behave like its hovered? How can you do that?
Or is there an even better way to contruct the stylesheet for this solution?
<div class="menu">menu</div>
<div class="menu menu_active">menu</div> // has to behave like menu:hover
<div class="menu_green">menu</div>
<div class="menu_green menu_active">menu</div> // has to behave like menu_green:hover
div.menu {
background:url('menu_opacity50.png');
}
div.menu_green {
background:url('menu_green_opacity50.png');
}
div.menu_active {
}
div.menu:hover {
background:url('menu_opacity100.png');
}
div.menu_green:hover {
background:url('menu_green_opacity100.png');
}

If I understand correctly, this is what you need:
div.menu:hover, .menu.menu_active {
background:url('menu_opacity100.png');
}
div.menu_green:hover, .menu_green.menu_active {
background:url('menu_green_opacity100.png');
}
.menu.menu_active will select elements that have both of the listed classes, such as <div class="menu menu_active">.

I think you might mean this:
div.menu.menu_active,
div.menu:hover {
background:url('menu_opacity100.png');
}
div.menu_green.menu_active,
div.menu_green:hover {
background:url('menu_green_opacity100.png');
}

You might want to do this
div.menu {
background:url('menu_opacity50.png');
}
div.menu_green {
background:url('menu_green_opacity50.png');
}
div.menu.menu_active {
background:url('menu_opacity100.png');
}
div.menu_green.menu_active {
background:url('menu_green_opacity100.png');
}

Overlay the hover element exactly over normal state and hide it (display:none) then use JS/jQuery to toggle the display.

Related

How to select specific class prefix while excluding other prefix?

I need to select the body element when it has a class beginning with post-type- but not select it when there's also a class beginning with taxonomy-. Does anyone know how to get this to work?
body[class^="post-type-"],
body[class*=" post-type-"] {
&:not([class^="taxonomy-"]),
&:not([class*=" taxonomy-"]) {
.widefat {
.check-column {
display: none;
}
}
}
}
EDIT: 0stone0's answer below helped me realize the CSS it was outputting was completely wrong, so this new approach is working well:
body[class^="post-type-"]:not([class^="taxonomy-"]):not([class*=" taxonomy-"]),
body[class*=" post-type-"]:not([class^="taxonomy-"]):not([class*=" taxonomy-"]) {
.widefat {
.check-column {
display: none;
}
}
}
div[class*='post-type-']:not([class*="taxonomy-"])
This pure CSS should target the desired element
Select classes that contain post-type-, but not() containing taxonomy-
div[class*='post-type-']:not([class*="taxonomy-"]) {
border: 1px solid red;
}
<div class='post-type-something'>post-type-something</div>
<div class='post-type-something taxonomy-foobar'>post-type-something taxonomy-foobar</div>
<div class='taxonomy-foobar post-type-something'>taxonomy-foobar post-type-something</div>
Note: Demo uses <div> instead of <body> and applies a border when targeted

Is there a way to style elements based on flex-wrap state?

Quite straight forward, is there a way to know whether an element has been wrapped because of flex-wrap and therefore style it differently?
I would use javascript or jquery to achieve this.
My approach would be:
get the offsetTop of the element using :first-of-type selector.
use the each method of jquery to run through all elements and compare if offsetTop of $(this) is different of the offsetTop value you got on step1.
gotcha
Provide some code if you need help developing it.
You can make the different class with styling that should be applied to that flex-wrap property. You can manage these classes by javascript. Please check the implementation of this approach as:
Here is the code where 2 classes are made, flex-wrap-blue which set flex-wrap to wrap and change color to blue and other class is flex-wrap-green which set flex-wrap to wrap-reverse and change color to green. I am managing these 2 classes by javascript as show the code below:
HTML Code:
<!DOCTYPE html>
<html>
<head></head>
<body>
<button id="btn-wrap">Apply Wrap</button>
<button id="btn-wrap-reverse">Apply Wrap Reverse</button>
<br />
<div class="large-box">
<div class="small-box">One</div>
<div class="small-box">Two</div>
<div class="small-box">Three</div>
<div class="small-box">Four</div>
</div>
</body>
</html>
CSS Code:
.large-box {
display:flex;
width:100px;
border:1px solid #f00;
height:100px;
padding:1% 0 1% 0;
box-sizing:border-box;
}
.small-box {
width:30px;
border:1px solid #f0f;
height:20px;
padding:1%;
}
.flex-wrap-blue {
flex-wrap:wrap;
color:#00f;
}
.flex-wrap-green {
flex-wrap:wrap-reverse;
color:#0f0;
}
Javascript Code:
function addClass(elem, className) {
if (!elem.classList.contains(className)) {
elem.classList.add(className);
}
}
function removeClass(elem, className) {
if (elem.classList.contains(className)) {
elem.classList.remove(className);
}
}
const btnWrap = document.getElementById('btn-wrap');
const btnWrapReverse = document.getElementById('btn-wrap-reverse');
const box = document.getElementsByClassName('large-box')[0];
btnWrap.addEventListener('click', function(){
addClass(box, 'flex-wrap-blue');
removeClass(box, 'flex-wrap-green');
});
btnWrapReverse.addEventListener('click', function(){
addClass(box, 'flex-wrap-green');
removeClass(box, 'flex-wrap-blue');
});
You can find the code working at my Codepen.

CSS on :focus within child of contenteditable

I am trying to detect focus on a child element of a contenteditable element, for the purposes of pure CSS styling. (I know I could detect this with JS, add an extra class and do it that way, but that is so long-winded.)
Basically, I have something along the lines of:
<div contenteditable="true">
Some text <span class="edit">that</span> goes here.
</div>
I tried CSS along the lines of:
.edit:focus {
color: #FF0000;
}
I want that span to change colour when the caret enters it, but apparently the focus is only applied to the div set to contenteditable, not to any child thereof. I have tried applying a second contenteditable to the span, but besides being a horribly sloppy approach, it doesn't work anyway.
Is there a solution to this?
Because of the limitation that elements within a contenteditable element can't generally receive focus, I suggest faking it by adding a class to your <span> element when the selection is contained within it, which you can do by monitoring the selection for changes (you'll have to use mouse and keyboard events and polling for thoroughness in Firefox until the selectionchange event is implemented in that browser).
var selectionContainer = null;
function updateSelectionContainer() {
var newSelectionContainer = null;
var sel;
if (window.getSelection && (sel = window.getSelection()).rangeCount) {
newSelectionContainer = sel.getRangeAt(0).commonAncestorContainer;
// Ensure we have an element rather than a text node
if (newSelectionContainer.nodeType != 1) {
newSelectionContainer = newSelectionContainer.parentNode;
}
}
if (newSelectionContainer != selectionContainer) {
if (selectionContainer) {
selectionContainer.className = selectionContainer.className.replace(/ ?containsSelection/, "");
}
if (newSelectionContainer) {
newSelectionContainer.className +=
(newSelectionContainer.className ? " containsSelection" : "containsSelection");
}
selectionContainer = newSelectionContainer;
}
}
if ("onselectionchange" in document) {
document.onselectionchange = updateSelectionContainer;
} else {
var el = document.getElementById("editor");
el.onmousedown = el.onmouseup = el.onkeydown = el.onkeyup = el.oninput = updateSelectionContainer;
window.setInterval(updateSelectionContainer, 100);
}
div {
font-size: 200%;
}
.edit.containsSelection {
color: red;
font-weight: bold;
}
<div contenteditable="true" id="editor">
Some text <span class="edit">that</span> goes here.
</div>
My understanding is that the type of elements that can receive focus (automatically) is limited.
See SO Question
One option is to add tabindex to the span.
body {
font-size: 3rem;
}
div[contenteditable=true] .edit:focus {
color: #FF0000;
}
<div contenteditable="true">Some text <span class="edit" tabindex="0">that</span> goes here.</div>
:focus > .edit { color: #cc0000; }
<div contenteditable="true">Some text <span class="edit">that</span> goes here.</div>
<div contenteditable="true">Some text that goes here.</div>
Just add this instead of :focus. Fiddle.
.edit {
color: #f00;
}

Select odd even child excluding the hidden child

Line 3 is a hidden <div> . I don't want that one to be taken from the odd/even css rule.
What is the best approach to get this to work?
.hidden {display:none;}
.box:not(.hidden):nth-child(odd) { background: orange; }
.box:not(.hidden):nth-child(even) { background: green; }
<div class="wrap">
<div class="box">1</div>
<div class="box">2</div>
<div class="box hidden">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
</div>
http://jsfiddle.net/k0wzoweh/
Note: There can be multiple hidden elements.
:nth-child() pseudo-class looks through the children tree of the parent to match the valid child (odd, even, etc), therefore when you combine it with :not(.hidden) it won't filter the elements properly.
Alternatively, we could fake the effect by CSS gradient as follows:
.hidden {display:none;}
.wrap {
line-height: 1.2em;
background-color: orange;
background-image: linear-gradient(transparent 50%, green 50%);
background-size: 100% 2.4em;
}
<div class="wrap">
<div class="box">xx</div>
<div class="box">xx</div>
<div class="box hidden">xx</div>
<div class="box">xx</div>
<div class="box">xx</div>
<div class="box">xx</div>
<div class="box">xx</div>
</div>
Pseudo-selectors don't stack, so your :not doesn't affect the :nth-child (nor would it affect :nth-of-type etc.
If you can resort to jQuery, you can use the :visible pseudo-selector there, although that's not a part of the CSS spec.
If you're generating the HTML and can change that, you can apply odd/even with logic at run-time, eg in PHP:
foreach ($divs AS $i => $div) {
echo '<div class="box ' . ($i % 2 ? 'even' : 'odd') . '">x</div>';
}
Even trying to do something tricky like
.box[class='box']:nth-of-type(even)
doesn't work, because the psuedo-selector doesn't even stack onto the attribute selector.
I'm not sure there's any way to do this purely with CSS - I can't think of any right now.
Here's a CSS-only solution:
.box {
background: orange;
}
.box:nth-child(even) {
background: green;
}
.box.hidden {
display: none;
}
.box.hidden ~ .box:nth-child(odd) {
background: green;
}
.box.hidden ~ .box:nth-child(even) {
background: orange;
}
<div class="wrap">
<div class="box">xx</div>
<div class="box">xx</div>
<div class="box hidden">xx</div>
<div class="box">xx</div>
<div class="box">xx</div>
<div class="box">xx</div>
<div class="box">xx</div>
</div>
Since my rows are being hidden with js, I found that the easiest approach for me was to just add an additional hidden row after each real row that I hide, and remove the hidden rows when I show the real rows again.
Hide the rows you want to hide calling .hide() for each table row, then call
$("tr:visible:even").css( "background-color", "" ); // clear attribute for all rows
$("tr:visible:even").css( "background-color", "#ddddff" ); // set attribute for even rows
Add your table name to the selector to be more specific. Using :even makes it skip the Header row.
As #Fateh Khalsa pointed out, I had a similar problem and since I was manipulating my table with JavaScript (jQuery to be precise), I was able to do the following:
(Note: This assumes use of JavaScript/jQuery which the OP did not state whether or not would be available to them. This answer assumes yes, it would be, and that we may want to toggle visibility of hidden rows at some point.)
Inactive records (identified with the CSS class "hideme") are currently visible.
Visitor clicks link to hide inactive records from the list.
jQuery adds "hidden" CSS class to "hideme" records.
jQuery adds additional empty row to the table immediately following the row we just hid, adding CSS classes "hidden" (so it doesn't show) and "skiprowcolor" so we can easily identify these extra rows.
This process is then reversed when the link is clicked again.
Inactive records (identified with the CSS class "hideme") are currently hidden.
Visitor clicks link to show inactive records from the list.
jQuery removes "hidden" CSS class to "hideme" records.
jQuery removes additional empty row to the table immediately following the row we just showed, identified by CSS class "skiprowcolor".
Here's the JavaScript (jQuery) to do this:
// Inactive Row Toggle
$('.toginactive').click(function(e) {
e.preventDefault();
if ($(this).hasClass('on')) {
$(this).removeClass('on'); // Track that we're no longer hiding rows
$('.wrap tr.hideme').removeClass('hidden'); // Remove hidden class from inactive rows
$('.wrap tr.skiprowcolor').remove(); // Remove extra rows added to fix coloring
} else {
$(this).addClass('on'); // Track that we're hiding rows
$('.wrap tr.hideme').addClass('hidden'); // Add hidden class from inactive rows
$('.wrap tr.hideme').after('<tr class="hidden skiprowcolor"></tr>');
// Add extra row after each hidden row to fix coloring
}
});
The HTML link is simple
Hide/Show Hidden Rows
scss for #tim answer's above, to keep class name changes to a minimum
$selector: "box";
$hidden-selector: "hidden";
.#{$selector} {
background: orange;
:nth-child(even) {
background: green;
}
&.#{$hidden-selector} {
display: none;
}
&.#{$hidden-selector} ~ {
.#{$selector} {
&:nth-of-type(odd) {
background: green;
}
&:nth-of-type(even) {
background: orange;
}
}
}
}
Another way, albeit on the fringe side, is to have an extra <tbody> and either move or copy rows there. Or, an extra div wrapper if using OPs example. Copying easiest of course in regards to restoring etc.
This approach can be useful in some cases.
Below is a simple example where rows are moved when filtered. And yes, it is ranking of stripper names, found it fitting as we are talking stripes ... hah
const Filter = {
table: null,
last: {
tt: null,
value: ''
},
name: function (txt) {
let tb_d = Filter.table.querySelector('.data'),
tb_f = Filter.table.querySelector('.filtered'),
tr = tb_d.querySelectorAll('TR'),
f = 0
;
tb_f.innerHTML = '';
if (txt.trim() == '') {
tb_d.classList.remove('hide');
} else {
txt = txt.toLowerCase();
for (let i = 0; i < tr.length; ++i) {
let td = tr[i].querySelectorAll('TD')[1];
if (td.textContent.toLowerCase().includes(txt)) {
tb_f.appendChild(tr[i].cloneNode(true));
f = 1;
}
}
if (f)
tb_d.classList[f ? 'add' : 'remove']('hide');
}
},
key: function (e) {
const v = e.target.value;
if (v == Filter.last.value)
return;
Filter.last.value = v;
clearTimeout(Filter.last.tt);
Filter.last.tt = setTimeout(function () { Filter.name(v); }, 200);
}
};
Filter.table = document.getElementById('table');
Filter.table.addEventListener('keyup', Filter.key);
table {
width: 200px;
border: 3px solid #aaa;
}
tbody tr { background: #e33; }
tbody tr:nth-child(even) { background: #e3e; }
.hide { display: none; }
<table id="table">
<thead>
<tr><th></th><th><input type="text" id="filter" data-keyup="filter" /></th></tr>
<tr><th>#</th><th>Name</th></tr>
</thead>
<tbody class="filtered">
</tbody>
<tbody class="data">
<tr><td>1</td><td>Crystal</td></tr>
<tr><td>2</td><td>Tiffany</td></tr>
<tr><td>3</td><td>Amber</td></tr>
<tr><td>4</td><td>Brandi</td></tr>
<tr><td>5</td><td>Lola</td></tr>
<tr><td>6</td><td>Angel</td></tr>
<tr><td>7</td><td>Ginger</td></tr>
<tr><td>8</td><td>Candy</td></tr>
</tbody>
</table>
You can use another type of CSS selector: tbody > tr:nth-of-type(odd)
to only target tr nodes, and then, instead of using class names to hide the rows, simply wrap them with some element (which hides them), so the CSS selector would only match odd table rows:
const searchElem = document.querySelector('input');
const tableElem = document.querySelector('table');
const tableBody = document.querySelector('tbody');
function search() {
const str = searchElem.value.toLowerCase();
const rows = tableElem.querySelectorAll('tr');
// remove previous wrappers
// https://stackoverflow.com/a/48573634/104380
tableBody.querySelectorAll('div').forEach(w => {
w.replaceWith(...w.childNodes)
});
// create a wrapper which hides its content:
const wrapper = document.createElement("div");
wrapper.setAttribute('hidden', true);
rows.forEach(function(row){
const text = row.textContent.toLowerCase();
if (str.length && !text.includes(str)) {
// replace row with wrapper and put the row inside it
row.replaceWith(wrapper);
wrapper.appendChild(row);
}
});
}
searchElem.addEventListener('keyup', search);
tbody > tr:nth-of-type(odd) {
background: pink
}
<input type="search" placeholder="search">
<table>
<tbody>
<tr><td>Apple<td>220
<tr><td>Watermelon<td>465
<tr><td>Orange<td>94
<tr><td>Pear<td>567
<tr><td>Cherry<td>483
<tr><td>Strawberry<td>246
<tr><td>Nectarine<td>558
<tr><td>Grape<td>535
<tr><td>Mango<td>450
<tr><td>Blueberry<td>911
<tr><td>Pomegranate<td>386
<tr><td>Carambola<td>351
<tr><td>Plum<td>607
<tr><td>Banana<td>292
<tr><td>Raspberry<td>912
<tr><td>Mandarin<td>456
<tr><td>Jackfruit<td>976
<tr><td>Papaya<td>200
<tr><td>Kiwi<td>217
<tr><td>Pineapple<td>710
<tr><td>Lime<td>983
<tr><td>Lemon<td>960
<tr><td>Apricot<td>647
<tr><td>Grapefruit<td>861
<tr><td>Melon<td>226
<tr><td>Coconut<td>868
<tr><td>Avocado<td>385
<tr><td>Peach<td>419
</tbody>
</table>

How Can I write the Css for this Style

Hi I try to edit the css of wordpress themes but I get stuck when I saw this DIV Style.
<li id="text-3" class="widget sbg_widget Phubadee widget_text">
<h2 class="widgettitle sbg_title">Title Header</h2>
How Can I make the CSS When I want the : Title Header : font-size: 1.6em;
Thank you so much.
h2.widgettitle.sbg_title { font-size:1.6em }
Explanation:
. is a class selector in css, your h2 has class widgettitle and sbg_title, so we would like to select those two by using ..
Note that there can't be any space between widgettitle and the next ., having space means entirely different thing, which is selecting any descendant of widgettitle that has class sbg_title
There are alot of way you can do it. Any of these will work, and there are more ways to do it!
li.widget h2 { font-size:1.6em }
li.sbg_widget h2 { font-size:1.6em }
h2 { font-size:1.6em }
h2.widgettitle { font-size:1.6em }
h2.sbg_title { font-size:1.6em }
.widgettitle { font-size:1.6em }
.sbg_title { font-size:1.6em }
li h2 { font-size:1.6em }
li>h2 { font-size:1.6em }
li#text-3 h2 { font-size:1.6em }
li#text-3 h2.widgettitle { font-size:1.6em }
li#text-3 h2.sbg_title { font-size:1.6em }
If you want to learn about CSS selectors, Sitepoint has a good breakdown of what they are and how they work
There is more way to do that.If you want you can add this to you css
h2.widgettitle {font-size:1.6em;}
or if you want to be more specific
h2.widgettitle .sbg_tittle
You can select that item in many ways, try for example
li#text-3 h2.sbg_title {
font-size: 1.6em;
}
Option 1:
.widgettitle.sbg_title {font-size:1.6em;}
Option 2:
.sbg_title {font-size:1.6em;}
Option 3:
.widgettitle {font-size:1.6em;}

Resources