Alter parent from child? - html

In CSS you can do this:
nav:hover a {
But is there a way of changing nav when a is hovered?

Use the javascript event onHover
In jquery, it's something like that:
$("a").hover(function () {
$('#nav').css("color","red");
});

Coming Soon, to CSS
Explicit subjects in a selector are coming in CSS, but we'll have to wait just a bit longer. Soon you will be able to explicitly declare which element is the subject, for instance with your code:
$nav a:hover {
background: red;
}
This would change a nav's background to read when any of its anchor descendants are hovered.
Source: Selectors Level 4 » Determining the Subject of a Selector
Until this is implemented, you'll have to use JavaScript (or one of the tools built with it, such as jQuery, Mootools, etc) to accomplish a task like this.
Doing it with jQuery
You can accomplish this with jQuery, by adding and removing a class when any of the elements nested anchors are hovered or exited:
$("nav").on("mouseenter mouseleave", "a", function(e){
$(e.delegateTarget).toggleClass("hovered", e.type === "mouseenter" );
});​
Demo: http://jsfiddle.net/jonathansampson/EPRRy/1/

This it the most compatible way
$("a").hover(function () {
$(this).parent().css({color:"red"});
});

No there isn't a way to ascend elements with CSS. To do explicitly what you described, it would require some JS.
#ssx had it close, but not quite, to do what your are asking with JS (and I'm going to simplify and use jQuery).
$("nav a:hover").hover(function() {
$(this).parent().css({'color': 'red'});
}), function() {
$(this).parent().css({'color': 'black'})
});
This gives changes the color to read, then back to black when the hover loses focus.

There is no solution for this in CSS 2 (dont know about CSS 3).
Javascript solution is easy and answered by other members.
You can try LESS. Using LESS you can do some conditional styling on DOM.

It will soon be intoduced in CSS 4. This is 5 or 6th question of the day i have seen today. I think it should be soon implemented by browser vendors.

Related

Can you set body id dynamically in React?

I am trying to implement dark mode in my app.
The idea is to add this to the root element:
<div id="dark">
And then this in CSS:
#dark {
background-color: #1A1A2E;
}
And then in Css, customize each dom element by using classes. For example, here I will work on cards:
#dark .card-body {
background-color: #16213E !important;;
}
#dark .card-header {
background-color: #0F3460 !important;
}
Now, this works perfectly fine.
But, with Modals, it does not work. I think it's because Modals are not rendered initially so for some reason the dark style does not apply to them.
What worked though is adding id="dark" to each modal:
#dark .modal-header {
background-color: #0F3460 !important;
}
#dark .modal-body {
background-color: #16213E !important;;
}
#dark .modal-footer {
background-color: #16213E !important;;
}
<Modal
// dark doesn't get applied automatically for modals because apparently modals are not rendered in the beginning
id="dark"
isOpen={this.state.isModalOpen}
toggle={this.toggleModal}
>
<div className="modal-header">
But, it'll be a pain to apply this to every single modal.
One solution mentioned here:
Modal should be the descendant of a tag which has id="dark". It is
loaded by the script right below the script tag and you are trying to
put 'dark' id on some div tag and the modal doesn't lie inside it,
thus the CSS selector not targeting it.
So, you need to put id="dark" on the body tag.
This solves the modals issue.
But, the problem is in my original implementation of dark mode, I am controlling that id in the root component like this:
// Root component
<div id={this.state.should_enable_dark_mode ? "dark" : "default"}>
And should_enable_dark_mode is managed like this:
manageDarkMode() {
window.addEventListener("storage", () => {
console.log("change to local storage!");
let should_enable_dark_mode = localStorage.darkMode == "true";
this.setState({
should_enable_dark_mode,
});
});
}
So the problem with the solution mentioned above is that I couldn't find a way to control the body tag from the react app. And I am not sure if it's a good thing to do.
What do you think I should do?
I see in the comments to your original question that you decided to just modify the body element in the browser DOM, which will probably work fine since the body element is not controlled by React and will likely not be changed by any other code.
I would however like to suggest a few improvements that makes it at bit less dirty:
use a data attribute like data-display-mode="dark" as a target for your CSS selectors instead of the ID. IDs are supposed to be stable and other tools and libraries (e.g. UI test tools) might rely on this.
use the Modal.container property to attach your Modals to the App element (the React-controlled global parent div defined in your React code, which you can control, not the app-root-div in index.html). Then set your data-display-mode attribute here by React-means. This way you will not bypass the virtual DOM.
use CSS custom properties for defining your colors, and then define all dark mode modifications in one place. Don't spread your dark-mode-styling code across multiple class selectors - you will have a hard time maintaining this.

Active state and display:none causes link not to work

Consider the following fiddle: http://jsfiddle.net/GMA76/
On the links active state I want to replace the content of the a tag, then it should continue to follow the link. However when I style it as shown in the fiddle and here:
a div:first-child{
display:block;
}
a div:last-child{
display:none;
}
a:active div:first-child{
display:none;
}
a:active div:last-child{
display:block;
}
The link doesn't work the first time you click it. It only replaces the content and then it seems the redirection fails.
How would I fix that?
Browsers don't take well to content changing on the :active event. Even if it did work, a CSS-only solution would likely mean that the user wouldn't even see the change in content before the new page had loaded (or started to load with a white screen). I tested a lot with the :after pseudo-selector and the content property, but this didn't work either.
And rightly so. Changes to content should only be done with a language like Javascript. This is a logic issue and is outside of the scope of a styling language. Therefore, I would suggest using Javascript.
I've created a quick fiddle here using Javascript with jQuery (doesn't need jQuery it but it's easier) to switch the text in the link and then go to the new page exactly 1 second afterwards. This way you only need to have the original link in the HTML rather than hiding separate links with CSS. There are more flexible and extensible ways to do this if it's not just for one or two links but for the sake of an example, take a look at the fiddle.
This is the jQuery:
$(".switch-link").click(function(){
$(this).text("Test Two");
var href = $(this).attr('href');
setTimeout(function(){
window.location = href
}, 1000);
return false;
});
1000 is the delay between the text changing and the browser starting to load the new page, you can change this to suit your needs.

using target in css to keep color

I have the following example in http://jsfiddle.net/uA97K/
What I am trying to achieve is to keep the same colour on a selected tab as the hover. So when a user clicks on a tab, that selected tab will remain blue until another tab is selected.
I thought this could be done by using a:target but does look to be working.
#bar a:target { background: #00A3EF; color: #003366;}
Any ideas what I may be doing wrong?
With only CSS, you can't do it. But you can use jQuery, and an .active class for this:
http://jsfiddle.net/uA97K/1/
$('#bar a').click(function(){
$('.active').removeClass('active');
$(this).addClass('active')
});
This is, as already noted, impossible with CSS currently. It is, however, possible with plain JavaScript (albeit the following demonstration works only with browsers that support document.querySelector(), addEventListener() and the element.classList API):
function hashMonitor() {
var D = document,
active = D.querySelector('a.active'),
link = D.querySelector('[href="#' + D.querySelector(':target').id + '"]');
if (active) {
active.classList.remove('active');
}
link.classList.add('active');
}
window.addEventListener('hashchange', hashMonitor, false);
JS Fiddle demo.
Conceivably, under Level 4 of CSS (currently entirely unsupported in the wild) this could become possible, but until implementations appear it seems fruitless to speculate on how such selectors might be used.
References:
CSS Selectors, Level 4.
document.querySelector().
element.classList.
EventTarget.addEventListener().

Is it possible to hide the title from a link with CSS?

I have an anchor element with a title attribute. I want to hide the popup that appears when hovering over it in the browser window.
In my case, it is not possible to do something like this,
$("a").attr("title", "");
Because of jQuery Mobile the title will reappear after certain events occur (basically everytime the anchor element gets redrawn).
So I hope to hide the title via CSS.
Something like:
a[title] {
display : none;
}
doesn't work, since it hides the entire anchor element. I want to hide the title only. Is this even possible? The popup shouldn't display.
Using the following CSS property will ensure that the title attribute text does not appear upon hover:
pointer-events: none;
Keep in mind that JS is a better solution since this CSS property will ensure that the element is never the target of any mouse events.
You can wrap your inner text in a span and give that an empty title attribute.
<a href="" title="Something">
<span title="">Your text</span>
</a>
As per #boltClock's suggestion, I'll say I don't feel that a CSS solution is appropriate here, as the browser decides what to do with the title attribute of a link, or anything for that matter. CSS, to my knowledge, is unable to handle this issue.
As mentioned, using jQuery to replace the title with an empty string wont work because jQuery mobile rewrites them at some points. This, however, will work independently of JQM, and doesn't involve entirely removing the title attribute which is SEO important.
This works:
$('a["title"]').on('mouseenter', function(e){
e.preventDefault();
});
I changed my initial code of $('body').on('mouseenter') to this after testing. This is confirmed to work.
In CSS it's not possible, because you can only add contents to DOM (tipically with :before :after and content: '...';, not remove or change attributes.
The only way is to create a live custom event (es. "change-something"):
$("a").on("change-something", function(event) { this.removeAttr("title"); });
and trigger to every changes:
... $("a").trigger("change-something");
More information and demo here:
http://api.jquery.com/trigger/
http://api.jquery.com/removeAttr/
try to change your code using this
$(document).ready(function() {
$("a").removeAttr("title");
});
this will remove title attribute so the hint label won't be appear when hover on the link
$("#test").tooltip({title: false});
There title attribute default value is true, make it false.
This will work only in case of Bootstrap Tooltip
Full working pure javascript solution
var anchors = document.querySelectorAll('a[title]');
for (let i = anchors.length - 1; i >= 0; i--) {
anchors[i].addEventListener('mouseenter', function(e){
anchors[i].setAttribute('data-title', anchors[i].title);
anchors[i].removeAttribute('title');
});
anchors[i].addEventListener('mouseleave', function(e){
anchors[i].title = anchors[i].getAttribute('data-title');
anchors[i].removeAttribute('data-title');
});
}

Active state on parent element when clicking element

I'm creating a button (actually just a link), which design is rather complicated, and as I am optimizing for IE8, can not be made with CSS3. I have therefore placed a <span> inside the <a>, and put a background image on both.
The image changes on :hover and :active. It works pretty great in all browsers, but not so much in IE. :hover works fine, but when clicking on the <span>, the :active state of the parent <a> is not triggered. It sort of makes sense, but I've seen it work before, so I guess there must be some workaround?
Here's a fiddle: http://jsfiddle.net/TheNix/EtjL3/
You can try using the following jQuery to add the css inline on click.
$("a, span").click(function(){
$(this).css("background", "green")
$(this).find("span").css("background", "lime")
});
Here's a jsFiddle for it http://jsfiddle.net/ollie/r5NDw/1/
alternatively you can add classes on click using addClass();
You can set a css class for the active state using jquery or javascript.
Edit
You can set a css class like this...
$(document).ready(function() {
$("a span").click(function() {
$(this).addClass("active");
$(this).parent().addClass("active");
});
});
and Css Style...
a.active { background:green; }
a.active span { background:lime; } ​