Overriding border styles in CSS - javascript

I have a three types of boxes being displayed in the image (2,3, and 4)
The first element is the selected style of a box.
I would like to apply this selected style on the other three.
For 2 it is straight forward. The gray goes to black.
For 3 I would need to replace the dashed with a solid line.
For 4 I would replace the gray with the black, but I would want to keep the image.
However I am trying to understand how it would work with inheritance in CSS. I am just adding a class 'active' to mark it as selected. It works fine for 2, but for 3 and 4 it does not know how to process the order of class names. I cannot remove the classes of the elements, because obviously I want to cascade the changes through (like the image in option 4).
My CSS looks like this :
li {
padding: 0.125rem;
margin: 0.4375rem 1.0625rem 0.3125rem 0;
border: 0.0625rem solid #d9d9d9;
}
li.active {
border: 0.0625rem solid black;
}
li.sold {
display: inline-block;
border: 1px solid #ccc;
background: url(http://i.piccy.info/i7/c7a432fe0beb98a3a66f5b423b430423/1-5-1789/1066503/lol.png);
background-size: 100% 100%;
}
li.wait-list {
display: inline-block;
border: 1px dashed #ccc;
}
I have demonstrated this in a JSFiddle :
https://jsfiddle.net/561aLm4z/7/
It's probably an obvious question, but how do I get the 'active' style to overwrite the styles on box 3 and 4?

Overwrite the background and border and move the css to the bottom, or make the css more specific (read more about css specifity) (by adding ul)
add1 = false
add2 = false
add3 = false
add4 = false
$("#2").click(
function() {
if (!add2) {
$("#2").addClass("active")
add2 = true;
} else {
$("#2").removeClass("active")
add2 = false;
}
}
)
$("#3").click(
function() {
if (!add3) {
$("#3").addClass("active")
add3 = true;
} else {
$("#3").removeClass("active")
add3 = false;
}
}
)
$("#4").click(
function() {
if (!add4) {
$("#4").addClass("active")
add4 = true;
} else {
$("#4").removeClass("active")
add4 = false;
}
}
)
li {
padding: 0.125rem;
margin: 0.4375rem 1.0625rem 0.3125rem 0;
border: 0.0625rem solid #d9d9d9;
}
li.sold {
display: inline-block;
border: 1px solid #ccc;
background: url(http://i.piccy.info/i7/c7a432fe0beb98a3a66f5b423b430423/1-5-1789/1066503/lol.png);
background-size: 100% 100%;
}
li.wait-list {
display: inline-block;
border: 1px dashed #ccc;
}
ul li.active {
border: 0.0625rem solid black;
background: none;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="hse-product-variant ">
<li id="1" style="display: inline-block;" class="active">
1
</li>
<li id="2" style="display: inline-block;" class="">
2
</li>
<li id="3" style="display: inline-block;" class="wait-list">
3
</li>
<li id="4" style="display: inline-block;" class="sold">
4
</li>
</ul>

The issue you are having is called 'specificity' and is best explained by the blog post commonly known as 'specificity wars'.
In a nutshell, each element has a specificity value.
Elements, like li have a value of 1.
Classes, like .sold have a specificity of 10.
IDs, like #box have a specificity of 100.
By combining these values, you can overwrite less specific items.
The order of the rules also change the specificity. If you have two items with a matching specificity score, the later of the two will shine through.
As such, you can overwrite your li.sold rule (score of 11) by adding a li.sold.selected rule (score of 21).
You can also involve parent element ids to increase specificity. For example:
div.man (score of 11)
#house div.man (score of 111)
#London #house div.man (score of 211)
This is the basics of specificity. I recommend you read the article also - which puts the concept in terms of StarWars, which is always appreciated.

Related

How to change the scrollbar styling via javaScript

I have implemented a customized scrollbar (code is provided below).
I want to use the javaScript event "onScroll" to change the scrollbar thumb styling while scrolling, but I don't know the right way to do so.
Is there a way to access the scrollbar style, perhaps as a JavaScript object, i.e.:
Container.style.-webkit-scrollbar-thumb.backgroundColor = 'black';?
Here is some code to demonstrate how my scrollbar is implemented:
CSS:
#container::-webkit-scrollbar {
width: 10vw;
}
#container::-webkit-scrollbar-thumb {
background-color: grey;
border-radius: 50px;
border: 5px solid black;
}
#container::-webkit-scrollbar-thumb:hover {
border: 2px solid black;
background-color: grey;
}
#container::-webkit-scrollbar-track {
background-color: black;
border-bottom-left-radius: 12px;
border-top-left-radius: 12px;
}
JavaScript:
elementsContainer.addEventListener("scroll", function wheelStyle() {
//elementsContainer.WHAT??
});
Here is my solution:
The idea is to create a CSS stylesheet rule dynamically and update it while scrolling.
Here is the snippet I used to test in stackoverflow itself (by running it from the console directly):
// Based on https://stackoverflow.com/a/31126328/1941313
appendRule = (sheet) => {
console.log({sheet});
const len = sheet.cssRules.length;
sheet.insertRule('body{}', len);
return sheet.cssRules[len];
}
ruleForScroll = appendRule(Array.from(document.styleSheets).slice(-1)[0]);
randomColor = () => Math.floor(255 * Math.random());
component = document.querySelector('.left-sidebar--sticky-container.js-sticky-leftnav');
component.addEventListener("scroll", function wheelStyle() {
ruleForScroll.selectorText = '.left-sidebar--sticky-container.js-sticky-leftnav::-webkit-scrollbar-track';
ruleForScroll.style["background"] = `rgb(${randomColor()},${randomColor()},${randomColor()})`;
});
This specifically affects the side menu of stackoverflow, changing the scrollbar's color randomly while scrolling.
Here is an independent solution in a CodePen. Note that an important prerequisite for the style to apply is the following css rule:
.test::-webkit-scrollbar {
width: 10px;
height: 10px;
background-color: transparent;
}

How to change an ID depending on the color of an element with Javascript

I'm trying to learn javascript on my own, so I'm lacking a lot. I'm trying to change the color of multiples elements depending on the color in the css of another element.
I want the javascript to detect the <div id> with a specific color, and then change the id of another <div id2>
I tried this :
if (document.getElementById("name").css('color') == "#7a5cd4") {
document.getElementById('border').setAttribute('id', 'red');
document.getElementById('line').setAttribute('id', 'linered');
}
#name {
font-size: 35px;
color: #7a5cd4;
}
#border {
width: 25px;
height: 25px;
border: 3px solid black;
padding: 10px;
margin: 10px;
border-radius: 100%
}
#red {
width: 25px;
height: 25px;
border: 3px solid red;
padding: 10px;
margin: 10px;
border-radius: 100%
}
#line {
width: 200px;
height: 20px;
border: 1px solid black
}
#linered {
width: 200px;
height: 20px;
border: 1px solid red
}
<center>
<div id="name">name</div>
<div id="border"></div>
<div id="line"></div>
</center>
window.getComputedStyle is a function that takes an element as a parameter and returns an object containing all of the styles that are being used on that object. We can then call getPropertyValue on the result to get the value of a css property.
These functions return colours in the form rgb(r, g, b), so we will need to compare the value to rgb(122, 92, 212), instead of #7a5cd4.
HTMLElement.style, however, would not work in your case as it only gets the inline style, which is when you specify the style in your html, like <div style="color: red">.
Also, it is recommended to use classes for selecting elements, instead of ids, as you can place multiple of them on the same element.
const element = document.getElementById('name');
const styles = window.getComputedStyle(element);
if (styles.getPropertyValue('color') == 'rgb(122, 92, 212)') {
document.getElementById('border').setAttribute('id', 'red');
document.getElementById('line').setAttribute('id', 'linered');
}
In order to change the id of element you:
document.getElementById('oldid').id = 'newid'
This rest of this answer fit to inline style (element style="color: value") while #BenjaminDavies answer fit more to your original question:
In order to check/change color property you:
var divOldColor = document.getElementById('oldid').style.color; // get the color to variable
if (divOldColor == '#7a5cd4') { // do something }
Put it all together we get something like this:
if (document.getElementById('name').style.color == '#7a5cd4') {
document.getElementById('border').id = 'red';
document.getElementById('line').id = 'linered';
}
.css() is not a vanilla JS function. Use .style.cssPropertyName instead.
if (document.getElementById("name").style.color === "#7a5cd4") {
document.getElementById('border').setAttribute('id', 'red');
document.getElementById('line').setAttribute('id', 'linered');
}

Including style tag in javascript

I want to include style tag in the javascript. ie., I am printing notices and the number of notices change dynamically. I receive the notices in a JSON object and hence require styles to be applied to each notice separately.
For now I just want the border around each notice or text
function retrive()
{
/*var css = ' { border :2px dashed; }',
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
style.type = 'text/css'; Not working*/
var myObj = JSON.parse(localStorage.getItem("Notice"));
if(myObj.length == 0)
{
$('#title').append(
'<br><br>Currently There are no Notices to be displayed'
);
}
else
{
for(var i = 0; i < myObj.length; i++)
{
$('#heading').append(
'<br><br><strong><center>'+ myObj[i].title+'</center></strong><br>'+myObj[i].introtext
);
}
}
}
I am printing the notices in the else block using for loop by finding the object length and appending it to the heading. This is where I want to print border to be printed around each block
<div>
<ul id="heading" style = "font-size : 16px;">
</ul>
</div>
If I use style here, border is appears to whole block or a single border to all notices.
<div>
<ul id="heading" style = "font-size : 16px; border : 2px dashed">
</ul>
</div>
,which is obvious.
Thanks.
I believe that you could handle this entirely with CSS and applicable classes. If you need to make changes based on the number of items, you could define classes for the different sets of count values that would result in the same CSS settings and simply apply that class to the header. Based on what you have in your code, that doesn't look to be the case and the example below should approximate what you're trying to achieve.
Note: I'm assuming that you're using a standard CSS reset to remove list styles. If not, then I suggest that you should.
<style>
#title p {
padding-top: 1em;
}
#heading {
font-size: 16px;
}
#heading li {
border: 2px dashed;
}
#heading li span.item_title {
font-weight: bold;
display: block;
text-align: center;
}
#heading li span.item_text {
display: block;
}
</style>
function retrive()
{
var myObj = JSON.parse(localStorage.getItem("Notice"));
if(myObj.length == 0)
{
$('#title').append('<p>Currently There are no Notices to be displayed</p>' );
}
else
{
for(var i = 0; i < myObj.length; i++)
{
$('#heading').append('<li><span class="item_title">'+ myObj[i].title+'</span><span class="item_text"'+myObj[i].introtext+ "</span></li>" );
}
}
}
If you use CSS classes you will be able to change the design more easily later, by modifying the CSS, rather than the JavaScript and HTML.
<style>
.heading
{ font-size : 16px; border : 2px dashed; }
</style>
<div>
<ul id="heading" class="heading">
...
</ul>
</div>
You can put the HTML in your JavaScript as you already have it, and use as many classes as you need.
In addition, try to avoid using <strong> and <br> and use CSS to control the layout.
You can apply a css style to each notice inside of #heading.
Something like this should work fine (place this in your css file or inside of a style tag) :
#heading strong {
border: 2px dashed;
}
I would recommend surrounding each notice in a span and append this to your #heading inside of an li and then applying this style:
#heading li {
list-style:none;
margin: 0 auto;
text-align: center;
}
#heading li span {
border: 2px dashed;
font-weight: bold;
}
you html would look something like this:
<ul id='heading'>
<!-- your newly inserted notice -->
<li><span>text</span></li>
</ul>
This will remove the need for the center and br tags.

Context menu using jquery

I have a context menu in jquery on Right Click.
But it is somehow not fulfilling my needs.
When i add new div on click and then try to have context menu operation on it, then it is not working.
It is applying operation on original div.
Can someone help me out in getting this problem solved and improving my Jquery or HTMl.
Js fiddle for Context Menu
Thanks
As marck said that there are many mistakes in your code.You used same ID on multiple elements multiple times. Anyway, I created a basic jsfiddle of what you are trying to achieve. You can build on top of that and modify it according to your needs.
Here is the link:
http://jsfiddle.net/PCLwU/
function add(){
//For adding new items.
}
function menu(){
//to show up context menu
}
function menuactions(){
//Define the actions performed when menu option is selected.
}
For different context menu for different list : http://jsfiddle.net/PCLwU/3/
Context menu div
<div id='contextMenu'>
<ul id='items'>
<li id="cutDoc">Cut</li>
<li id="copyDoc">Copy</li>
<li id="pasteDoc">Paste</li>
<li id="deleteDocs">Delete</li>
</ul>
</div>
menu Style
<style>
#items
{
list-style: none;
margin: 5px 0 0 5px;
}
#contextMenu
{
display: none;
position: fixed;
border: 1px solid grey;
width: 150px;
background-color:white;
box-shadow: 2px 2px 1px grey;
}
#items li
{
list-style-type: none;
border-bottom: 1px solid grey;
border-bottom-style: dotted;
padding: 10px;
font-size: 14px;
}
#items :hover
{
background: #0070FF;
color: white;
}
</style>
jQuery Script for applying on area where it will needed which
$("YOur class name").mousedown(function(e){
//to block browsers default right click
if( e.button == 2 ) {
$("#contextMenu").css("left", e.pageX);
$("#contextMenu").css("top", e.pageY);
$("#contextMenu").fadeIn(500, startFocusOut());
}
});
function startFocusOut() {
$(document).on("click", function () {
$("#contextMenu").hide(500);
$(document).off("click");
});
}
This will work fine.
Update:
here is the fiddle demo

Enable hover when the checkbox is not selected & disable it once the checkbox is selected

I'm trying to enable hover (adding '.add_link_twitter_hover' class) when the checkbox is not selected & disable it (removing the '.add_link_twitter_hover' class) once the checkbox is selected the same way Pinterest does it for Twitter/Facebook checkboxes when a user adds a pin:
I tried this, but it doesn't disable hover (doesn't remove '.add_link_twitter_hover' class) once mouse pointer is away:
var hoverTwitter = "add_link_twitter_hover";
$(postTwitter + " input").click(function(e) {
$(this).parent().removeClass(hoverTwitter);
$(this).parent().toggleClass(activePostTwitter);
});
$("label.add_link_twitter").hover(function(e) {
if($("input.publish_to_twitter").is(":checked")) {
$(this).removeClass(hoverTwitter);
return;
}
$(this).addClass(hoverTwitter);
});
Any idea how to enable hover when the checkbox is not selected & disable it once the checkbox is selected? Thanks in advance!
Here's the jQuery:
var postTwitter = ".add_link_twitter";
var activePostTwitter = "active";
$(postTwitter + " input").click(function(e) {
$(this).parent().toggleClass(activePostTwitter);
});
Here's the html:
<label class="add_link_twitter">
<input type="checkbox" name="publish_to_twitter" class="publish_to_twitter"><span>Share on Twitter</span>
</label>
Here's the css:
.add_link_twitter{
position:absolute;
left:15px;
bottom:16px;
color: #a19486;
border: 2px solid transparent;
border-color: #F0EDE8;
border-radius: 4px;
font-size: 13px;
font-weight: bold;
cursor: pointer;
padding: 7px;
padding-top: 5px;
padding-bottom: 5px;
}
.active {
border-color: #468BD0;
color: #468BD0;
background-color: whiteSmoke;
}
.add_link_twitter_hover
{
color: #A19486;
border: 2px solid transparent;
border-color: #C2B1A2;
border-radius: 4px;
background-color: white;
padding: 7px;
padding-top: 5px;
padding-bottom: 5px;
}
Try this:
$("label.add_link_twitter").hover(function(e) {
if(!$("input.publish_to_twitter").is(":checked"))
$(this).addClass(hoverTwitter);
}, function() {
$(this).removeClass(hoverTwitter);
});
The usual way to use the .hover() method is to supply two functions: the first is called when the mouse moves over the element in question, and the second is called when the mouse moves out.
So what I've done above is in the first function (mouseenter) I've added your class if the checkbox is not checked. In the second function (mouseleave) I just remove the class.
This can be done without any javascript at all. if you expect to always have the class "publish_to_twitter", just separate the two states with pseudoclasses:
.publish_to_twitter:hover{
width:50px;
}
input.publish_to_twitter:checked{
width:500px;
}
I added the input element in the selector to ensure that the checked style took precedence. Just make sure that for every style you set with :hover, you have an equivalent style in :checked.

Categories

Resources