Change css from sibling when hovered on with SCSS - css

I want to change the css from the sibling when I hover on the element. Is there a way to do this with SCSS?
Example: https://jsfiddle.net/rqb5ytav/
Like when I hover on .one how do I change the background color of .two?

Use + CSS selector. It's available from CSS2.
.one:hover + .two {
background-color:green;
}
Please look at the fiddle: https://jsfiddle.net/rqb5ytav/1/.

You can use previousElementSibling and nextElementSibling property to get the css properties.
var divOneColor = null;
var divTwoColor = null;
$(document).on('mouseover', 'div', function(e) {
var clName = $(e.target).attr('class')
if(clName == "one") {
divOneColor = $(this).css("background-color");
divTwoColor = $(this.nextElementSibling).css("background-color");
$(".two").css("background-color", divOneColor);
$(".one").css("background-color", divTwoColor);
}
else if (clName=="two"){
divOneColor = $(this.previousElementSibling).css("background-color");
divTwoColor = $(this).css("background-color");
$(".one").css("background-color", divTwoColor);
$(".two").css("background-color", divOneColor);
}
});
Please look at the fiddle.
https://jsfiddle.net/7ow38dve/

Related

Hide custom cursor on hover over selected div

I have a custom cursor with some hover effects on a page (wordpress). This custom cursor shall hide, when hovering a certain div, due to some text. Please take a look here: https://florianwmueller.com/work-test/
I tried a lot, including some javascript, but nothing works. Any idea?
I gave the pictures a special class: .no-cursor
Thankful for any help...
Add this script on your website.
<script>
var elements = document.getElementsByClassName("no-cursor");
var style;
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener("mouseover", function() {
style = document.createElement("style");
style.innerHTML = "body.cursor-element-shape a { cursor: default !important; } .wpcc-active > .wpcc-cursor { display: none !important; }";
document.head.appendChild(style);
});
elements[i].addEventListener("mouseleave", function() {
document.head.removeChild(style);
});
}
</script>

Using adjacent sibling CSS combinator (+) with HgClass and dynamic value

I'm just trying to figure out if this is possible or if I need to rethink the way I'm going about things.
Here's a very simple idea of where I'm at
My main list will be constantly having items added and removed by other processes. I use NgFor to generate my items and I'm using the adjacent sibling combinator in my style sheet (+) to add margin-top to all but the first item, then ngClass to apply the class itself.All god so far...
Now I want the value of margin-top to also be dynamic and linked to value coming in from another service.
So my question is just, can anyone give me a way of using the adjacent sibling selector and a dynamic value for the style it applies?
Since rendered CSS won't do variables cross browser yet, one option would be a small script adding a style like this
window.addEventListener('load', function() {
loadStyle(20);
setTimeout(function() { loadStyle(40); }, 1000);
setTimeout(function() { loadStyle(60); }, 2000);
})
function loadStyle(margin) {
var node = document.querySelector('my-app style') || document.createElement("style");
var css = ".my-item+.my-item{margin-top: "+margin+"px;}"
node.type = 'text/css';
if (node.styleSheet){
node.styleSheet.cssText = css;
} else {
node.appendChild(document.createTextNode(css));
}
document.querySelector('my-app').appendChild(node);
}
.my-item{
background-color: red;
}
.my-item+.my-item{
margin-top: 20px;
}
<my-app>
<div class='my-item'>A</div>
<div class='my-item'>B</div>
<div class='my-item'>C</div>
</my-app>
You can use style:
<div *ngFor="let user of userList" [ngClass]="'my-item'" [style.margin]="marginValue">{{user}}</div>
marginValue = '0 0 0 9px';

Apply style to first element in a row of similar elements

I have the following list (the numbers are just for reference)
<div class="A">alpha1</div>
<div class="B">alpha2</div>
<div class="A">alpha3</div>
<div class="A">alpha4</div>
<div class="A">alpha5</div>
<div class="B">alpha6</div>
<div class="A">alpha7</div>
I want to apply one style to DIVS 1, 3 and 7, because they are the first of their class (A) in a row of elements of the same class. Is there a pseudo element / magic I can use for that? Something like (inventing)
not(.A) & .A {color:red} -> if class is A and it is not preceded by an A
Thanks!
You use the :not() pseudo-class with an adjacent sibling combinator + to match an .A that is not immediately preceded by an .A:
:not(.A) + .A
You'll also need to use :first-child to select the very first .A element since it's not preceded by anything:
.A:first-child
Combine them, and you have:
:not(.A) + .A, .A:first-child { color: red; }
jsFiddle demo
Here is a cross browser solution using JavaScript:
http://jsfiddle.net/YhvGw/
function applyStyleToFirstDiv(className, styleAttr, val,baseSelector) {
//Allow to specify a base element to search in
if(baseSelector == null){
baseSelector = document
}
var divElements = baseSelector.getElementsByTagName("div"),
len = divElements.length;
var prevWas = false,currentIs;
// Go through all the divs
for (var i = 0; i < len; i++) {
var cur = divElements[i];
var classes = cur.className.split(" ");
currentIs = false;
for (var j = 0; j < classes.length; j++) {
//If you find a matching class
if (classes[j] === className) {
currentIs = true;
break;
}
}
//If the current one matches, and the last one didn't, apply the style, otherwise don't
if(currentIs && !prevWas){
cur.style[styleAttr] = val;
}
prevWas = currentIs;
}
}
//usage sample
applyStyleToFirstDiv("A","color","yellow");
Here is an example:
div:not(.A) + .A, .A:first-of-type{
color:red;
}

Can I accomplish this with CSS?

If I've got elements like this:
A
B
A
C
I know I can use something like
body
{
counter-reset:section;
}
a:before
{
counter-increment:section;
content:counter(section)". ";
}
to get
1. A
2. B
3. A
4. C
but is there a way to get the following?
1. A
2. B
1. A
3. C
ie. uniquely identify all links on a page by prefixing the text with the same number.
Note: hardcoding specific URLs isn't an option, I'm potentially dealing with hundreds of links and don't know the URLs ahead of time.
I realize this would be easy/possible with javascript, I am only interested in CSS-based solutions or an explanation of why this isn't possible with CSS.
Ok, I got what you mean with your question. Just with plain CSS it's not possible (at least not cross-platform..)
If you can use javascript, you have several possibilities.
My preference would be to use a data-attribute to hold the value, for this example I chose data-counter. If you do like this, the CSS becomes trivial:
CSS
a:before
{
content:attr(data-counter)". ";
}​
And the Javascript would look like this if you have jQuery:
JS with jQuery
var linkcounter = {};
var counter = 0;
$("a").each(function() {
if (!linkcounter.hasOwnProperty($(this).attr("href"))) {
counter++;
linkcounter[$(this).attr("href")] = counter;
}
$(this).attr("data-counter", linkcounter[$(this).attr("href")]);
});
​
or like this without jQuery:
vanilla JS
var linkcounter = {};
var counter = 0;
var anchors = document.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++) {
if (!linkcounter.hasOwnProperty(anchors[i].getAttribute("href"))) {
counter++;
linkcounter[anchors[i].getAttribute("href")] = counter;
}
anchors[i].setAttribute("data-counter", linkcounter[anchors[i].getAttribute("href")]);
}
You can view the version without jQUery here: http://jsfiddle.net/ramsesoriginal/CVW7Y/5
And the version with jQuery here: http://jsfiddle.net/ramsesoriginal/CVW7Y/4
Sadly there is no CSS only way to do this (yet). I hope this helps.
​
I don't think you can get this behaviour with pure CSS, and you need Javascript. And there are always cases like this:
http://google.com/
http://google.com
google.com
google.com/
www.google.com
You get the point.
In jQuery this is quite trivial, so I'd suggest you use that.
If using jQuery is OK, this can be done by manipulating the :before pseudo element's content:
Demo: http://jsfiddle.net/rwMWx/2/
JS
var labels = [
"1",
"2",
"1",
"3"
// and so on...
];
// OR maybe put in some algo for this sequence
$('a').each(function(i) {
$(this).attr('data-label', labels[i] + '. ');
});
CSS
a:before {
content: attr(data-label);
color: red;
text-align: left;
padding-right: 10px;
font-size: 11px;
display: inline;
}
You could use :contains but I'm not sure how supported it is so you might be better off with JavaScript.
a:contains("A") {
/* Styles here */
}
a:contains("B") {
/* Styles here */
}
EDIT:
Apparently :contains isn't supported at all. I'll leave this up here though so no one else bothers putting it.
You could use :contains in jQuery though and add a class accordingly.
$('a:contains(A)').addClass('CLASS_NAME');
try this code:
var counter = 0, cache = {};
$('a').each(function (i, a) {
a = $(a);
var href = a.attr('href');
var c = cache[href];
if (!c) {
counter++;
c = counter;
cache[href] = c;
}
a.text(c + '. ' + a.text());
});
​
I'm using jQuery, and that's how it works: http://jsfiddle.net/pDLbQ/

onfocus="this.blur();" problem

// I am trying to apply an "onfocus="this.blur();"" so as to remove the dotted border lines around pics that are being clicked-on
// the effect should be applied to all thumb-nail links/a-tags within a div..
// sudo code (where I am):
$(".box a").focus( // so as to effect only a tags within divs of class=box | mousedown vs. onfocus vs. *** ?? | javascript/jquery... ???
function ()
{
var num = $(this).attr('id').replace('link_no', '');
alert("Link no. " + num + " was clicked on, but I would like an onfocus=\"this.blur();\" effect to work here instead of the alert...");
// sudo bits of code that I'm after:
// $('#link_no' + num).blur();
// $(this).blur();
// $(this).onfocus = function () { this.blur(); };
}
);
// the below works for me in firefox and ie also, but I would like it to effect only a tags within my div with class="box"
function blurAnchors2()
{
if (document.getElementsByTagName) {
var a = document.getElementsByTagName("a");
for (var i = 0; i < a.length; i++) {
a[i].onfocus = function () { this.blur(); };
}
}
}
Thanks guys - I have gone for the css(a:focus):
img, a:focus{
outline: none;
}
It seems to be working right(tabbing is still working and the borders are gone when clicking) for me... in both ie and firefox. Will have to now retrofit some other links to use it...
Thanks again.
It's not recommended to blur. If all you're looking at doing is hiding the focus lines, use this instead:
a[i].onfocus = function () { this.hideFocus = true; };
This will work for all versions of IE. For other browsers (including IE8 in standards mode) you can set the outline CSS style to hide focus outlines:
a {
outline: none;
}
This would make your page much more keyboard friendly than blurring an element as it takes focus.
I would suggest using only CSS to remove the border.
img, a:active{
outline: none;
}
Or is there a specific reason why JS must be used?

Resources