How to change a css value in javascript? - javascript

So I want to change a css value in javascript, without having an element in html, I'll explain like:
<style>
.box{
width: 10%;
}
</style>
<script>
// I want to change the width value of (.box) to something like "90%"
</script>
So what I mean to say is that I want to change the (.box) width value between the two style tags, I know my question sounds weird, but am just new coding and I really need it, any help appreciated!

Use media queries.
I don't remember the exact way to do this, but something like:
.box { width: 90%; }
#media screen and (min-width: 1000px) {
.box { width: 40%; }
}

You can change the properties (e.g. width) of a CSSStyleDeclaration with its setProperty() method.
You can get a CSSStyleSheet of a specific <style> element with its sheet property.
In our case, the stylesheet's first CSSStyleRule (sheet.cssRules[0]) is for the CSS class .box. You get the CSSStyleDeclaration object of a CSSStyleRule with its style property.
Example:
const iClass = document.getElementById("i-class");
const classRule = document.getElementById("my-style").sheet.cssRules[0];
// Set input.value to initial width-value (10%)
iClass.value = classRule.style.getPropertyValue("width");
// Update width-value on each input
iClass.addEventListener("input", () => {
classRule.style.setProperty("width", iClass.value);
});
/* Ignore; presentational styling */
.box {
margin-bottom: .5rem;
aspect-ratio: 1/1;
background-color: coral;
text-align: center;
}
<style id="my-style">
.box{
width: 10%;
}
</style>
<div>
<label for="i-class">Class width:</label> <input id="i-class">
</div>
<div class="box">class</div>
Unlike adding a new CSS rule, this changes the existing rule.

Here's one option, adding a <style> tag dynamically. This will add a style which overrides previous, obviously. See other answers for other options of changing existing rules.
var inline_style = `
.box {
width: 90%;
background: pink;
}`;
// from https://stackoverflow.com/a/28662118/3807365
document.head.insertAdjacentHTML("beforeend", '<style>' + inline_style + '</style>')
.box {
width: 10%;
background: blue;
}
<div class="box">i'm a box</div>

Related

Change css class attribute values using javascript

I want to change the value of one of the attributes of css class dynamically
Here's my scenario:
I've many elements using one class, instead of getting them all and looping them over and applying style, I want to change the value of one of the attributes of class, which is alredy applied on them. for example
.prodName {
max-width: 270px;
display: block;
}
above class is being used by many elements, and I want to alter one of the attributes of that class like
.prodName {
max-width: 350px <---
display: block;
}
is there any simple method for this in javascript.
Before I post this question, I already searched but didn't find anything easy and useful.
thanks in advance to helping hands.
You can use CSS variables for this case.
const root = document.querySelector(':root');
function play() {
root.style.setProperty('--size', '300px');
}
:root {
--size: 100px;
}
.container {
background-color: red;
width: var(--size);
height: var(--size);
cursor: pointer;
}
<div class="container" onclick="play()"></div>
The only problem with the above approach is support in older browsers. If you have to support IE, and older browsers where CSS variable support is not present, you can handle this problem by adding a class to the body/parent container.
function play() {
document.body.classList.add('large')
}
.container {
background-color: red;
width: 100px;
height: 100px;
cursor: pointer;
}
.large .container {
width: 300px;
height: 300px;
}
<div class="container" onclick="play()"></div>
Add new class to CSS:
.mw350 {
max-width: 350px;
}
Then add new class to the element in JS:
document.querySelector('.prodName').className += ' mw350'; // <-- better to select using unique IDs, like '#prodNameElement'
If you are going to control the css class/attribute change from ts, maybe with a function or var change, you might want to use ngClass: https://www.freecodecamp.org/news/angular-ngclass-example/ and have all the logic where you want it, easily accessible.

Dynamically increase and decrease an input text box size depending on another selector width

I have an input text box which has some padding to it. I also have a wrapper class selector which is used next to that input text box. I am trying to remove set padding from the input text box and make that space dynamic so that the element size would (especially width) increase and decrease depending on the screen size (i.e. Mobile or Large view as large screen) without effecting the wrapper.
The text box looks like the following. a, c, d, e are buttons which appear dynamically. So the space for b here should expand if the there is only one button on the right and decrease if there are all the buttons on the right.
|____|________________________ |_____|_____|_____|
a b c d e
so the css class selectors that I have includes b and another one includes all the c, d, e (wrapper).
I assume this can't only be done through CSS. Any suggestion?
CSS:
.input {
position: relative;
width: 100%;
max-width: var(--grid-main-max-width);
padding: 1.188rem 2.9rem 1.188rem 4.5rem;
margin: 0;
font-size: 16px;
border: 1px solid var(--color-gray);
border-radius: 0.375rem;
outline: 0;
}
.wrapper {
position: absolute;
top: 0;
right: 1.5rem;
bottom: 0;
display: flex;
justify-content: center;
}
HTML
<div>
<input class="input">
<div class= "wrapper">
<button>c</button>
<button>d</button>
<button>e</button>
</div>
</div>
The solution only needed to count the width of the input text box and the wrapper and assign the difference as a padding to the right of the input text box. The following little change was added to an onInput event.
document.getElemendById("inputTextBox").style.paddingRight = document.getElemendById("searchFieldWrapper").clientWidth;
And also needed to use Media Queries for #media (--large-viewport) / #media (--medium-viewport) to assign different padding for the input. as #Scott Marcus mentioned in a comment.
Lets say you have div child blocks for those child elements or you can specify some class.
div:first-child:nth-last-child(1){
width: 100%;
}
div:first-child:nth-last-child(2),
div:first-child:nth-last-child(2) ~ div{
width: 50%;
}
div:first-child:nth-last-child(3),
div:first-child:nth-last-child(3) ~ div{
width: 33.3%;
}
div:first-child:nth-last-child(4),
div:first-child:nth-last-child(4) ~ div{
width: 25%;
}
//and so on
Source refer to here
Also if you want to modify other elements you can use
div:first-child:nth-last-child(2) > .someClass{
style:goesHere
}
(UPDATE: I figured out you used a wrapper element, and that a is'nt a label but a button. But this answer is easily adaptable to your question.)
You can use the calc function provided by CSS. Given this piece of HTML (I joined all the elements to remove side effects of the blank characters; we can fix it in an other way but I wanted to keep the answer simple):
<html>
<head>
</head>
<body>
<article id="demo">
<label>a</label><input type="text" placeholder="b" /><button>c</button><button>d</button><button>e</button>
</article>
</body>
</html>
This piece of CSS allow the input text element to fill the available space.
article#demo {
/* the width (80vw) includes border and padding */
width: 80vw;
}
article#demo label {
/* to make label resizable */
display: inline-block;
width: 30px;
}
article#demo button {
width: 20px;
margin: 0;
padding: 0;
background-color: #f0f0ff;
box-sizing: border-box;
/* see above */
}
article#demo input[type="text"] {
box-sizing: border-box;
/* text input width = 100% minus other items */
width: calc(100% - 30px - 3 * 20px);
}
You can set the width of article#demo using any unit (em, ex, etc.) it should work.
In your final design, use box-sizing:border-box to set the whole element, including borders and padding, within the CSS width. Otherwise, you'll have to adjust the calc parameter.
If you put left or right margins, count them too.
If you use font-dependent units (em, etc.), the same font-family and other font-related CSS entries have to be set - implicitly or not - for all the concerned elements.
Working fiddle with a little interactive test here.

Fallback for css-vars

I want to use CSS vars the first time and am doing that
#circle_1 {
width: 50px;
height: 50px;
width: var(--size_1);
height: var(--size_1);
}
and fill it with JS like so
var input_1 = document.querySelector("#groesse_1");
var circle_1 = document.querySelector("#circle_1");
input_1.addEventListener("change", function() {
circle_1.style.setProperty("--size_1", input_1.value);
});
This works nice, but as long as the user doesn't add a value to input_1, the circles have a not defined size (which I tried to prevent by giving a default height/width in the CSS before I added the width: var(--size_1); thing)
How would I correctly add a default value to that element?
See here: https://codepen.io/daiaiai/pen/OQYwVW
CSS func var() accepts two arguments: the --var custom property, and a fallback value.
So to properly fallback values you would do
selector {
prop: 20px; /* for browser without support for variables */
prop: var(--my_var, 20px); /* for browser with support for variables */
}
You can give a fallback default value
#circle_1 {
width: var(--size_1, 30px);
height: var(--size_1, 30px);
}
So this way the default value its 30px but if --size_1 its not empty it will override the 30px
If you want to know more here vars on MDN
Here is your updated codepen with a fallback
You can do that when defining the variable, and you only supply width and height once:
#circle_1 {
--size_1: 50px;
width: var(--size_1);
height: var(--size_1);
}
In your event handler, you'll also need to specify units unless you're expecting the user to enter them, e.g.:
circle_1.style.setProperty("--size_1", input_1.value + "px");
// -------------------------------------------------^^^^^^^
...or similar.
More on MDN.
Live Example:
var input_1 = document.querySelector("#groesse_1");
var circle_1 = document.querySelector("#circle_1");
input_1.addEventListener("change", function() {
circle_1.style.setProperty("--size_1", input_1.value + "px");
});
#circle_1 {
--size_1: 50px;
width: var(--size_1);
height: var(--size_1);
border: 1px solid black;
}
<input id="groesse_1" type="text">
<div id="circle_1"></div>

Changing Text Color On Click

I'm trying to change the text from black to blue when I click. I have it as an "if" statement and I know it doesn't need to be an "if" statement, but I'm just wondering why it doesn't work. I'm just asking, "If this color is black, change it to blue."
var myvar = document.getElementById('thisdiv');
myvar.onclick = function myfunction() {
if (myvar.style.color == "#000000") {
myvar.style.color = "#0000FF";
}
}
.mydiv {
height: 200px;
width: 200px;
background-color: red;
color: #000000;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
<div class="mydiv" id="thisdiv">Click Me</div>
JSFiddle
I'm not really looking for a solution to make it go from black to blue as I'm sure there's other ways I could figure out to do it, but more just wondering why the way I have it isn't working.
style only holds styles that were added using the style attribute in the HTML. It doesn't contain the computed style from applying <style> tags or stylesheets.
To get the computed style, use window.getComputedStyle(). Note this is read-only.
var myvar = document.getElementById('thisdiv');
myvar.onclick = function myfunction() {
if (window.getComputedStyle(myvar).color === "rgb(0, 0, 0)") {
myvar.style.color = "#0000FF";
}
}
.mydiv {
height: 200px;
width: 200px;
background-color: red;
color: #000000;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
<div class="mydiv" id="thisdiv">Click Me</div>
A better strategy though is to add or remove CSS classes to elements, so that you get separate presentation from functionality.
Okay, so the reason the code is not working is because myvar.style.color is undefined. When you use a stylesheet, it doesn't affect the JavaScript style properties, which should be the same as the styles defined in the style attribute of the element. What you want is something like the following.
// undefined!="#0000ff", success
if(myvar.style.color!="#0000ff") {
myvar.style.color = "#0000ff";
}
If you want to use JQuery, you can try something like the following.
// JQuery always returns opaque colors in rgb(r, g, b) form
// regardless of the original format.
if($(myvar).css("color")=="rgb(0, 0, 0)") {
myvar.style.color = "#0000ff";
}
I strongly suggest using an additional class for this, to account for its state.
var myvar = document.getElementById('thisdiv');
myvar.onclick = function myfunction() {
/* if (myvar.className === ""){
myval.className = "active";
} else {
myvar.className = "";
} */
// Same as below, toggle the class of #thisdiv from active to blank
myvar.className = myvar.className === "" ? "active" : "";
}
.mydiv {
height: 200px;
width: 200px;
background-color: red;
color: #000000;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.mydiv.active{
color: #0000ff;
}
You could also probably make use of the :visited pseudo selector and get rid of the click function entirely. You'd need to make your div one big link though. Something like this;
<a class="mydiv" id="thisdiv">Click Me</a>
.mydiv{
display:block; /* since it's a link and will be inline by default */
}
.mydiv:visited{
color: #0000ff;
}

Overflow hidden for text in css

I have an element with image and text,
Fiddle. Note: Resize preview enough to make grid big enough.
Here is my CSS:
.gridster .gs-w .item{
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
.gridster .gs-w .item .obj{
background-color: #00A9EC;
}
.gridster .gs-w .item .itemIcon {
height: 100%;
width: 100%;
float:left;
overflow: hidden;
z-index: 10;
}
.gridster .gs-w .item .itemIcon {
background-image: url(http://icons.iconarchive.com/icons/dakirby309/windows-8-metro/256/Apps-Calendar-Metro-icon.png);
background-repeat:no-repeat;
background-size:contain;
align-content: center;
}
.gridster .gs-w .item .itemText{
display: block;
width: 100%;
position: relative;
margin-right: 0px;
right: 0px;
text-align: right;
z-index: 9;
}
.gridster .gs-w .item .itemText a{
vertical-align: center;
text-align:right;
color:white;
padding-right: 10%;
font-size: 14px;
font-weight: 600;
text-decoration:none;
font-family: 'Segoe UI';
}
I want to show text when element is expanded, and hide when element is collapsed, I think I can achieve it by CSS, but it's not yet clear what is wrong.
and here it is collapsed
advise some CSS code, in case if possible to make in CSS.
You can hook into resize.resize.
By checking data attribute data-sizex you get how many columns the cell spans. By this you can expand the init function to the following:
Sample fiddle.
public.init = function (elem) {
container = elem;
// Initialize gridster and get API reference.
gridster = $(SELECTOR, elem).gridster({
shift_larger_widgets_down: true,
resize: {
enabled: true,
resize: function (e, ui, $widget) {
var cap = $widget.find('.itemText');
// Hide itemText if cell-span is 1
if ($widget.attr('data-sizex') == 1) {
cap.hide();
} else {
cap.show();
}
}
}
}).data('gridster');
hookWidgetResizer();
}
Or cleaner, and likely preferable. Split it out to own function and say something like:
resize: capHide
Sample fiddle.
If you rather go for the solution proposed by your updated images, one way is to tweak the CSS on resize, using your resize_widget_dimensions function. Sure this can be done better, but as a starter you can have this:
Sample fiddle.
this.$widgets.each($.proxy(function (i, widget) {
var $widget = $(widget);
var data = serializedGrid[i];
this.resize_widget($widget, data.size_x, data.size_y);
// Find itemText
var $it = $widget.find('.itemText');
// Set CSS values.
$it.css({width:this.min_widget_width, left:this.min_widget_width});
}, this));
Challenge is that the gridster is a very fluid cake where a lot of the dimensions and positioning is done by JavaScript rather then pure CSS. Anyhow, the above should give a direction on how to tweak it, and might even be good enough ;)
As a final treat you can resize the font according to cell size. I'm not sure how to best find the size you want as you divide the space between icon/image and text. But something like this:
Sample fiddle.
Where you have a hidden span to measure text:
<span id="font_sizer"></span>
With CSS:
#font_sizer {
position: absolute;
font-family:'Segoe UI';
visibility: hidden;
}
And font measure by:
function szFont(w, t) {
var s = 1, $fz = $('#font_sizer');
$fz.text(t);
$fz.css('fontSize', s + 'px');
while ($fz.width() < w - 2)
$fz.css('fontSize', ++s + 'px');
return s;
}
You can set font size as:
var fontSize = szFont(this.min_widget_width - 10, 'Objects');
Where this.min_widget_width - 10 is the part where you set size available for text. Then you can say:
var $it = $widget.find('.itemText');
$it.css({fontSize: fontSize + 'px', width:this.min_widget_width, left:this.min_widget_width});
Other notes:
You have a typo in:
var container,
grister, // <<-- Missing 'd' in gridster
resizeTimer;
In extensions you have
var data = serializedGrid[i];
this.resize_widget($widget, data.sizex, data.sizey);
however a console.log of data show:
data.size_x
data.size_y
not sure how this fits in. The data attribute uses sizex / y but data property from serialize, (on object), it uses size_x / y with underscore.
I think you are looking for media query:
#media all and (max-width: 760px) {
.gridster .gs-w .item .itemText {
display: none;
}
}
Example
You can hide text by using below type of CSS
.gridster .gs-w .item .itemText a.hide-text {
text-align: left;
text-indent: -99999px;
display: inline-block;
}
now whenever you want to hide text you need to add this class i.e. hide-text on anchor element Objects and vice versa to show text remove class
basically you need to try and figure out best possible solution to fit all requirements Good luck

Categories