different css style only for children of a certain div [duplicate] - javascript

This question already has answers here:
CSS Child vs Descendant selectors
(8 answers)
Closed 5 years ago.
This is what I have:
I have a div id="navbar" and various styles for the ul and li elements there.
Now I want to know, if there is any selector in CSS where I can say "the following css-styles shall only be aplliedd to children of #navbar"
something like:
/* ***** NAVBAR ****** */
#navbar {
/* Add a gray right border to all list items, except the last item (last-child) */
li {
border-right: 1px solid #bbb;
}
li:last-child {
border-right: none;
}
.active {
background-color: #4CAF50;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
li {
float: left;
}
li a {
display: block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
/* Change the link color to #111 (black) on hover */
li a:hover {
background-color: #111;
}
}
are there any ways to apply various css-styles only to elements that are chil or child-child or child-..-child of a certain HTML-element?
Note I'm also using jQuery so if thats only possible with jQuery, it will not be a problem.
sincerly basti

You're looking for the descendant combinator: A space. For instance:
#navbar li {
/* styles */
}
That will only apply the styles to li elements that are descendants of #navbar.
You have to use it on every rule. If you want syntax more like what you have in your question, there are preprocessors that do that sort of thing: Sass, Less, and such.
But with just CSS itself, you need to repeat the #navbar on every rule.

Direct Children
#parent > #child {
color: #fff;
}
Descendants
#parent #descendant {
color: #fff;
}

Related

How to change button hover color dynamically through javascript? [duplicate]

This question already has answers here:
document.getElementsByTagName not working
(3 answers)
Closed 2 years ago.
I want to change all my buttons' hover color to match the theme of my websites. I have a default color, but need to change it depending on the referring page. I'm able to get the referrer page, but I can't figure out how to change the hover style. This is what I have:
var btn = {
hover: function (event) {
event.target.style.backgroundColor = "blue";
},
out: function (event) {
event.target.style.backgroundColor = "white";
}
}
var element = document.getElementsByTagName('button');
element.addEventListener("mouseover", btn.hover, false);
element.addEventListener("mouseout", btn.out, false);
HTML:
<div>
<button class="accountButton firstButton" id="FacebookExchange"></button>
</div>
Default Style:
.unified_container .row .panel-default #api .localAccount .entry .buttons button {
float: left;
background-image: none;
background-color: #f4f4f4;
border-radius: 0.2rem;
cursor: pointer;
display: inline-block;
font-size: 1em;
font-weight: 400;
height: inherit;
line-height: 1.3333333;
margin-top: 3rem;
margin-right: 0px;
margin-left: 0px;
padding: 10px 16px;
text-align: center;
touch-action: manipulation;
user-select: none;
vertical-align: middle;
white-space: nowrap;
width: inherit;
-moz-user-select: none;
-ms-touch-action: manipulation;
-ms-user-select: none;
-webkit-user-select: none;
color: #000;
width: 100%;
}
.unified_container .row .panel-default #api .localAccount .entry .buttons button:hover {
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
background-color: #d40000;
color: #fff;
}
The error message I get "element.addEventListener is not a function".
How do I change the button hover color?
PS I can't write inline css, javascript or html in the buttons because the buttons are dynamically created by the application.
The reason why you are getting this error is because document.getElementsByTagName('button') returns an array of elements that have the tag name button
So your variable element is an array.
To solve this error you need to identify which element in this array you are actually interested in adding a listener to.
For example if it is the first element then your code should look something like:
element[0].addEventListener("mouseover", btn.hover, false);
element[0].addEventListener("mouseout", btn.out, false);
if you want all your button elements to have the listeners then you can just use a simple foreach loop or map.
When you do document.getElementsByTagName('button') you get an array of Nodes.
You need to iterate over the list and add the event listeners on each of them.
var elements = document.getElementsByTagName('button');
elements.forEach(element => {
element.addEventListener("mouseover", btn.hover, false);
element.addEventListener("mouseout", btn.out, false);
});

Css class active

I have small problem with css and jQuery. I have 2 buttons and I want to set the background of the one clicked to blue, and I want to do this with 'active' css property. It is not working for some reason. Whenever the button is not active anymore, it loses the background color. Here is the code:
HTML:
<div id = 'hey'>
<div class = 'b' id = 'b1' href="#">Button one</div>
<div class = 'b' id = 'b2' href="#">Button Two</div>
</div>
CSS:
body,html {
font: bold 14px/1.4 'Open Sans', arial, sans-serif;
background: #000;
}
#hey {
margin: 150px auto 0;
padding: 0;
list-style: none;
display: table;
width: 600px;
text-align: center;
}
.b {
color: #fff;
text-transform: uppercase;
text-decoration: none;
letter-spacing: 0.15em;
display: inline-block;
padding: 15px 20px;
position: relative;
}
.b:active {
background-color: blue;
}
JS:
$(".b").click(function() {
$(this).addClass('active');
});
:active is a pseudo-class meaning "while being activated" (typically while the mouse button is held down over it).
You are giving it a class active so you need to use a class selector: .active (with a . not a :).
I suggest not using class names which match pseudo-class names as it is an easy source of confusion.
:active is pseudo-element and you are trying to add active as a class. So the CSS should be
.b.active {
background-color: blue;
}

Responsive nav not appearing as intended

I am trying to create a responsive nav bar, but I am coming across issues making it appear in the way intended.
Here is an image of how it looks when window is maximized:
Here is an image when the window is resized:
Here is an image of what I want the page to look and function like:
Issues:
As the images show, the header currently shows the links "stretches, mobility" etc, when I want it to display "Join / Log In" etc (image 3).
When menuis clicked, I want the nav to dynamically display the other links.
Here is what I have tried so far: https://jsfiddle.net/hudnybux/
Ok, I think I got it to look almost exactly like your screenshots. One of the main things I had to do was move your nav-trigger up within html.
<div id="header-main">
<div id="nav-trigger"><span>Menu</span></div>
<nav id="main-navigation" role="navigation">
<ul>
<li>Stretches</li>
<li>Mobility</li>
<li>Posture</li>
</ul>
</nav>
<!--<nav id="nav-mobile"></nav>-->
</div>
Technically you no longer need nav-mobile nav. I also fixed your caret triangle next to "menu". It needed a height and width of 0.
width: 0;
height: 0;
Edit:
I have revisited my solution. Just as a suggestion, I am recommending css transitions instead of jQuery slideDown and slideUp. You were already applying a class and that is all we need to create dynamic animations. jQuery's methods apply the styles inline and frankly leave you with less flexibility.
https://jsfiddle.net/qnco3x7e/8/
You will need to add another media query
#media all and (max-width: 460px) {
nav#main-navigation li {
display:block;
border-bottom: 1px solid #fafafa;
}
}
You can use flexbox css properties. It's very powerfull. http://www.alsacreations.com/tuto/lire/1493-css3-flexbox-layout-module.html
Writing others' code for them is not in the spirit of Stack Overflow, but, as I prefer teaching by showing and not telling, I went ahead and did the task for you. Observe how I changed your implementation and learn as much as you can!
The Strategy
Use the same HTML markup for the main menu (Stretches, Mobility, Posture) on both large and small screen widths, instead of using JavaScript to duplicate it in two places.
Use the same CSS for both menus as a starting point; in the media query for small screen sizes, change the main menu to be horizontal
Show everything by default; use display: none only on screen sizes you don't want to show something on.
JSFiddle
$(document).ready(function() {
$("#main-nav-mobile-trigger span").click(function() {
$(this).toggleClass("open");
if ($(this).hasClass("open")) {
$("#main-nav").addClass("open").slideDown(250);
} else {
$("#main-nav").removeClass("open").slideUp(250);
}
});
});
.pageOverlay {
width: 900px;
margin: 0 auto;
}
/******************/
nav {
background-color: #fefefe;
/*NAV COLOUR*/
padding: 10px 0;
border-bottom: 1px solid #e3e3e3;
text-align: center;
}
nav ul li a {
color: #a4a4a5;
text-decoration: none;
}
nav ul li a:hover {
color: black;
}
nav ul {
display: inline-block;
list-style-type: none;
margin: 0;
padding: 0;
text-align: center;
}
nav li {
display: inline-block;
padding: 0 2px;
}
nav li:last-child {
border-right: none;
}
nav a {
display: block;
color: white;
padding: 10px 20px;
}
/****************************************************************/
/* Menu CSS which pops up when window is resized */
#main-nav-mobile-trigger {
text-align: center;
}
#main-nav-mobile-trigger span {
display: inline-block;
padding: 10px 30px;
cursor: pointer;
text-transform: uppercase;
}
#main-nav-mobile-trigger span:after {
display: inline-block;
margin-left: 10px;
width: 20px;
height: 10px;
content: "";
border-left: solid 10px transparent;
border-top: solid 10px #e3e3e3;
border-right: solid 10px transparent;
}
#main-nav-mobile-trigger span:hover {
background-color: #e3e3e3;
}
#main-nav-mobile-trigger span.open:after {
border-left: solid 10px transparent;
border-top: none;
border-bottom: solid 10px #fff;
border-right: solid 10px transparent;
}
#media all and (min-width: 901px) {
#top-nav {
text-align: right;
}
#main-nav {
text-align: left;
}
#main-nav-mobile-trigger {
display: none;
}
}
#media all and (max-width: 900px) {
#main-nav:not(.open) {
display: none;
}
#main-nav ul {
display: block;
}
#main-nav li {
display: block;
border-bottom: solid 1px #e3e3e3;
}
#main-nav li:last-child {
border-bottom: none;
}
#main-nav a {
padding: 10px 30px;
}
#main-nav a:hover {
background-color: #e3e3e3;
color: #fff;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pageOverlay">
<nav id="top-nav" role="navigation">
<ul>
<li>Join / Log In</li>
<li>Help</li>
<li>Shop</li>
</ul>
</nav>
<div id="main-nav-mobile-trigger"><span>Menu</span></div>
<nav id="main-nav" role="navigation">
<ul>
<li>Stretches</li>
<li>Mobility</li>
<li>Posture</li>
</ul>
</nav>
</div>
<!-- pageOverlay closed-->
The HTML
I removed your container <div>s (#header and #header-main), as they serve no purpose as far as layout is concerned.
There are now only three parts to the header area. In order they are:
#top-nav - Join/Login, Help, Shop
#main-nav-mobile-trigger - MENU button
#main-nav - Stretches, Mobility, Posture
The JavaScript
When the MENU button (#main-nav-mobile-trigger span) is clicked:
Toggle its .open class.
If it has the .open class,
Add #main-nav's .open class.
Otherwise,
Remove #main-nav's .open class.
The CSS
You had duplicates of the styling rules for each horizontal menu (formerly #nav-main and #main-navigation, which are very easy to confuse). These are now combined into one set of rules under the more general selector, nav. Additionally, their text-align is set to center by default (the desired alignment on small screen widths).
For big screen widths (#media all and (min-width: 901px)):
Align #top-nav to the right and #main-nav to the left.
Hide the MENU button.
For small screen widths (#media all and (max-width: 900px)):
If #main-nav doesn't have the .open class, hide it.
Display the menu items in #main-nav horizontally.
I hope this helps you. Best of luck with your future adventures in front-end development!

CSS hover does not affect on other element

CSS :hover works when I use it for it's own element, but when i tried to affect another element, it had no effect.
For example, when I hover this button, the hidden links should appear, but they do not.
.dropdown {
position: relative;
display: inline-block;
border: 1px solid black;
width: 200px;
}
.dropbutton {
width: 100%;
height: 60px;
color: white;
background: #017678;
border: none;
}
.dropcontent a {
color: black;
text-align: center;
line-height: 40px;
text-decoration: none;
height: 40px;
background-color: #DDD;
border-width: 0 0 1px 0;
border-style: solid;
border-color: #9fa0a8;
display: none;
}
a:last-of-type {
border: none;
}
.dropbutton:hover .dropcontent {
display: block;
}
<div class="dropdown">
<button class="dropbutton">SHOW CONTENT</button>
<div class="dropcontent">
c1
c2
c3
</div>
</div>
A space is a descendant combinator. It targets descendants, but the div is not a descendant of the button, it is a sibling.
You need to use the adjacent sibling combinator instead: a plus sign.
You also need to target the links (which are descendants of .dropcontent so you should use a descendant combinator there) since it is those which you have set display: none on and not the div.
.dropbutton:hover + .dropcontent a {
Are you using Javascript to do this?
var button = document.getElementsByClassName('.dropbutton')[0],
menuContent = docuemnt.getElementsByClassName('.dropcontent')[0];
button.onmouseover = function(event) {
menuContent.style.display['block'];
}
button.onmouseout = function(event) {
menuContent.style.display['none'];
}
With a slight change to your CSS: .dropbutton should have display: none, and you should remove the display: none from .dropcontent a
I'd move the display: none; to the .dropcontent itself - as it now pertains to its anchors, that is, links, and as such, neither current answer would work -, then use
.dropbutton:hover + .dropcontent
{
display: block;
}
But you must not add anything between dropbutton and dropcontent afterwards, or it will not work any more.

Maintaining a css :hover effect for all items up a nested list chain

So, I have DOM that looks like this:
<ul id="nav">
<li><a>Hello</a></li>
<li>
<a>OuterMenu</a>
<ul>
<li><a>InnerMenu1</a>
<ul><li><a>InnerMenu2</a></li><li><a>Item 1</a></li><li><a>Item 2</a></li></ul>
</li>
</ul>
</li>
</ul>
which looks like this:
+Hello +OuterMenu
----InnerMenu1--------------InnerMenu2
----Other list item Item 1
Item 2
That is, the first menu is horizontal, the next menu is directly below the first menu, and all subsequent inner menus appear directly to the right [see example here].
This works fine, but I need the hover styles for each outer menu to persist as each inner menu is selected. When the user is hovering over Item 1, Item 1, InnerMenu, and OuterMenu should be highlighted, and when the user moves off of the whole menu tree, then and only then should OuterMenu no longer be highlighted. Is there a better way to do this than trying to manage a hover and mouseout event on every single list item?
I'm looking for a clean implementation here.
Check out Stu Nicholls great css-only work on just this issue.
I donĀ“t know what you have already, but if you use something like:
#nav > li:hover > a {
// outer menu highlight
}
it should highlight the outer menu also when you are on a sub-menu item.
The same technique can be applied to all levels, but it depends on your browser compatibility requirements as li:hover will not work in older IE versions.
For completeness
/* second level */
#nav > li > ul > li:hover > a {
}
/* third level */
#nav > li > ul > li > ul > li:hover > a {
}
Simply using the :hover psuedo-class on your li will apply even when you are over a descendant element. Here's a working example showing that this is true: http://jsfiddle.net/eMyHE/; hover over InnerMenu2 and you'll see InnerMenu1 and OuterMenu highlight.
Also, you might be interested in my 8-years-old CSS-only hierarchical menu tests, part of some ancient code that uses JavaScript for hierarchical menus.
This isn't my work, I'm just passing it on. It looks like it's the same answer as JakeParis's, but in JSFiddle form. http://jsfiddle.net/XPE3w/7/ This is for HTML with a ul>li>a structure (see the link if this doesn't make sense).
ul {
font-family: Arial, Verdana;
font-size: 14px;
margin: 0;
padding: 0;
list-style: none;
}
ul li {
display: block;
position: relative;
float: left;
}
li ul {
display: none;
}
ul li a {
display: block;
text-decoration: none;
color: #ffffff;
border-top: 1px solid #ffffff;
padding: 5px 15px 5px 15px;
background: #2C5463;
margin-left: 1px;
white-space: nowrap;
}
ul li a:hover {
background: #617F8A;
}
li:hover ul {
display: block;
position: absolute;
}
li:hover li {
float: none;
font-size: 11px;
}
li:hover a {
background: #617F8A;
}
li:hover li a:hover {
background: #95A9B1;
}

Categories

Resources