Active state in navigation bar (CSS only) - html

Currently I´m highlighting the active tab in my site with just a CSS class,
the problem is that I´m having more and more tabs and this list is getting bigger and every time I add a new tab I also need to add a new selector to the class
Is there a CSS only way to simplify this?
body.students li.students,
body.teachers li.teachers,
body.sports li.sports,
...,
... {
background-color: #000;
}
I´m adding the class to the body for each section
is there a way to do something like this with CSS?
body.[class] > li.[class] {
background-color: #000;
}
Basically I just want to add a property if both (body and li) have the same class
Example for students.html
<body class="students">
<ul>
<li class="students">students</li>
<li class="teachers">teachers</li>
</body>
In this example li.students is the one that will be highlighted
Example for teachers.html
<body class="teachers">
<ul>
<li class="students">students</li>
<li class="teachers">teachers</li>
</body>
In this example li.teachers is the one that will be highlighted
Thanks!

Change your HTML code - introduce a class "current_page" (or whatever you'd like to call it)
<body class="students">
<ul>
<li class="students current_page">students</li>
<li class="teachers">teachers</li>
</ul>
</body>
Or
<body class="teachers ">
<ul>
<li class="students">students</li>
<li class="teachers current_page">teachers</li>
</ul>
</body>
That way, you'll only ever need one selector:
li.current_page {
background-color: #000;
}
You could also do it in JavaScript if you don't like to change your HTML code:
var classname = document.querySelector("body").className;
var li = document.querySelector("li." + classname);
li.className = li.className + " current_page";

Related

Show current page on the menu Jquery

I'd like to change the background color of the current page the user is on. I've tried some code but they don't work.
My js code is in a different file and it's loading the menu to some of the pages.
$(function(){
$("#menu-nav").load("menu.html");
$("#footer").load("footer.html");
})
/* The menu code is in another file */
<div class="menu-nav">
<ul id="nav">
<li><a id="homeLink" href="index.html">home</a></li>
<li><a id="pessoal" class="a-borda" href="pessoal.html">pessoal</a></li>
<li><a id="galeria" href="galeria.html">galeria</a></li>
</ul>
</div>
The code I've tried, but the class is not added
var section = window.location.pathname;
if (section == "/index.html"){$("#homeLink").attr("class", "active");}
CSS:
.active {
background-color: red;
}
also tried with .addClass( className ), but doesn't add the class.
I don't know if the fact I'm bringing the files with Jquery it's interfering in the process or if I'm using the wrong syntax.
You can add a class dynamically depending on the page
$(document).ready(function() {
let section = window.location.pathname.substring(1);
$(`a[href='${section}']`).addClass("active");
})
You need to wrap your var section = window.location.pathname; ... if (section == "/index.html"){$("#homeLink").attr("class", "active");} into a $(function(){. This lets the script wait until the DOM finishes loading.
$(function(){
var section = window.location.pathname;
//Changed the section to /js as the script is run from https://stacksnippets.net/js
if (section == "/js") {
$("#homeLink").addClass("active");
}
})
.active {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu-nav">
<ul id="nav">
<li><a id="homeLink" href="index.html">home</a></li>
<li><a id="pessoal" class="a-borda" href="pessoal.html">pessoal</a></li>
<li><a id="galeria" href="galeria.html">galeria</a></li>
</ul>
</div>

custom class vs specific selector for lists (CSS)

I've been trying to write better CSS, I've seen some Harry Roberts conferences and read about the BEM methodology.So by now what I understand in general is that:
You should keep things modular and reusable
Make custom general classes and avoid nesting
Never use ID's (or almost never)
My question refers to the second one: in the case of a list, let's say I want to edit the color for both the normal and :hover state. Should I add a custom class to each <li> element or a custom class to the <ul> and refer to the <li> inside it?
Here is an example to better illustrate what I mean.
<h3>Custom class for ul</h3>
<ul class="list">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
<h3>Custom class for li</h3>
<ul>
<li class="list__element">One</li>
<li class="list__element">Two</li>
<li class="list__element">Three</li>
<li class="list__element">Four</li>
</ul>
<style type="text/css">
.list li {
color: black;
}
.list li:hover {
color: red;
}
.list__element {
color: black;
}
.list__element:hover {
color: red;
}
</style>
When you're using BEM, try applying classes to EVERY element. That way you are dealing with the same level of specificity across the board, and you won't have to deal with priority orders.
So to answer your question, having .list__element:hover is exactly what you want.
I provided a more elaborate example, to demonstrate modularization. Notice how I added a new module "utensils".
Hope this answers your question!
.kitchen {
&__utensils {
}
}
.utensils {
&__utensil {
&:hover {
}
}
}
// this gets compiled to
.kitchen
.kitchen__utensils
.utensils
.utensils__utensil
// that is exactly what you want because you are avoiding specificity. Which means you will never have to fight with your selectors, which means you will never have to use important tags.
<div class="kitchen">
<ul class="kitchen__utensils utensils">
<li class="utensils__utensil"></li>
<li class="utensils__utensil"></li>
<li class="utensils__utensil"></li>
<li class="utensils__utensil"></li>
</ul>
</div>

Nav highlight current page

Please help solve the problem, because my ideas have been exhausted...(
I have a :
<nav class="nav_editor" ng-show="status.editorMenuOn">
<ul class="menu_editor">
<li class=""><a ng-href="/articles/user/{{ status.userID }}">My Articles</a></li>
<li class="">Create Article</li>
<li class="">Comments</li>
</ul>
</nav>
And a CSS classes:
.menu_editor li a {
color: rgb(125,125,125);
font-size: 1.25vw;
margin-right: 20px;
text-decoration: none;
}
I want to make highlighting the item in the menu when this page is active (not pseudo ":active"), just when someone watching current page, for example "My Articles".
I have tried about 3 variants by CSS/HTML only, JavaScript and jQuery, but it is either not working properly or not working at all.
Please help solve this problem.
Thank you in advance!
When the myArticle page loads, just do jquery addClass method.
$(document).ready(function(){
//remove highlighted menu buttons on pageload
$(".menu_editor li").removeClass("activeMenuItem");
//add class only to the specific one
$(".foo").addClass("activeMenuItem");
});

Append horizontal rule to each <li>

For my <ul> list, I would like to add a <hr> after each element of a list. The Result should render like:
<ul class="mylist">
<li>
moooo!
<hr width="40%">
</li>
<li>
maaaaa!
<hr width="40%">
</li>
...
</ul>
It is bad style adding <hr> to each <li> so I would like to refractor this using css only. I cannot use:
.mylist > li: after{
content: "<hr>"
}
as content would escape the characters.
I also do not want to use jQuery:
$('.mylist').find('li').append('<hr width="40%">');
So the question is, how could I append <hr width="40%"> to each <li> of a certain list using css3 ?
jQuery Solution
Just realized that you wanted to nest the hr element inside the li before you close it, yes it's perfectly valid, so simply use append(), and note, you cannot do this using CSS only, as you cannot modify DOM using CSS, you need to use jQuery or JS
jQuery("ul li").append("<hr />");
Demo
CSS Solution
If you don't need an extra element, or you don't want a jQuery solution(As you want)
Using hr element as a direct child to ul element is not a valid markup, instead, you can use a border-bottom for each li which will behave same as hr does, still if you want an explicit way to do so, say for controlling the width of the separator without changing the width of li than you can do it like this
Demo
ul li:after {
content: "";
display: block;
height: 1px;
width: 40%;
margin: 10px;
background: #f00;
}
Here, am just creating a virtual block level element, which doesn't actually exists in the DOM, but it will just do the thing which you need. You can just design the element, the same way you style a normal div. You can also use border on this but to keep the thin line horizontally centered, I've assigned height: 1px; and than am using margin to space up.
I think it's better to use CSS for this. for example you can stop using <hr> tag, instead do something like:
<ul class="mylist">
<li>
moooo!
</li>
<li>
maaaaa!
</li>
...
</ul>
and then with CSS:
.mylist li { border-bottom: 1px solid black; }
There are other options too, for example if you want to show the horizontal line only for some list items, you can give them a class and add a CSS rule only for that class. like this:
<ul class="mylist">
<li class="hr">
moooo!
</li>
<li>
maaaaa!
</li>
...
</ul>
and CSS:
.mylist li.hr { border-bottom: 1px solid black; }
You can use like this:
<ul>
<li></li>
</ul>
<hr/>
Thats simple. If you have nested ul and li then you use li instead of <hr/> or simply <hr/> inside a <li></li> tag. See below. Its purely your choice.
<ul>
<li>
<ul><li></li></ul>
</li>
<li style="height:1px;border:solid 1px #666"> </li> // or you can also use
<li><hr/></li>
<li>
<ul>
<li></li>
</ul>
</li>
</ul>
Tags in content are not allowed and even if it would be very misleading (css { content: "text"}, How do i add tags?)
If you think is wrong to add <hr> in HTML than it is wrong adding with css (if it would be possible) or js. IMHO a first You should try to use border of <li> if result won't be as expected add that <hr>
Insert A Class That Creates A bottom-border: For Each <li>
<!--########## STYLE EACH li USING CLASS ##########-->
<style>
.hr {
width:40%;
border-bottom:1px solid rgba(0,0,0,.7);
}
</style>
<!--########### PAGE CONTENT ############-->
<ul class="mylist">
<li class="hr">
-CONTENT-
</li>
<li class="hr">
-CONTENT-
</li>
...
Try this CSS:
li:after {
content: " ";
display: block;
height: 2px;
width: 100%;
}

basic css li active only for some elements

I have two HTML lists I need one to select my "active" class and the other to ignore it.
Here is my css, I show an image "icon-plus.gif" and when user click the li the image change to "icon-minus.gif"
li:before {content: url("icon-plus.gif");}
li.active:before {content: url("icon-minus.gif");}
And then I have a two lists, and all the li show the image "icon-plus.gif" when I click it image change.
<ul>
<li>Coffee</li>
<li>Milk</li>
</ul>
<ul>
<li>Bread</li>
<li>Apples</li>
</ul>
both are showing the images!!! Really don't understand why, my idea it was having the class inside the li:
<ul>
<li class"active">Coffee</li>
<li class"active">Milk</li>
</ul>
Code was downloaded from internet.Thanks
Use JQuery:
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$("li").click(function () {
// Remove active class from all li elements
$("li").removeClass("active");
// add the active class to your clicked on element
$(this).addClass("active");
});
</script>
javascript onclick() event and jquery's css manipulation may help you. Here is a useful link:
http://api.jquery.com/category/css/