Change background position div when input is focus - css

I'm building form with images like a label...
I have:
DIV.icon-phone {
width: 22px
height: 22px
background: url('icon-set.png') no-repeat 22px 66px;
}
INPUT.pool-phone {
border:1px solid #666;
}
I would something like this:
if INPUT.pool-phone:focus change DIV.icon-phone background-position to: 44px 66px
Please help.

In order to alter some css property of an element when another element is modified, you need to have specific structures..
For your example, the input element must share the same immediate parent as the div and also be before it in the hierarchy.
In this case you can use the ~ General sibling combinator to target it
.pool-phone:focus ~ .icon-phone{
background-position:...
}
Demo at http://jsfiddle.net/gaby/fx5Uy/
otherwise you can use javascript and bind to the onfocus event..

you could write a javascript function to take care of that for you.
[the input button].onfocus = function changeBg () { [thediv].style.background="[whatever you want]" };
[the input button].onblur = function resetBg () { [thediv].style.background="[whatever you want]" };
Gaby posted a pure css version which is preferable (at least to me).

Related

Set background color to trasparent CSS

I am trying to set the background color to transparent for this page:
.page-id-714 .container-fluid {
background-color: transparent;
}
But I do not seem to be able to address the correct class or item. Can anyone point me in the right direction?
You are setting it on the wrong class. You need to set it on
.top-stripe {
/* Current, it's set to background-color: #fbfbfb; */
background-color: transparent;
}
Make sure you declare the above after the selector which I've shared below, else you need to make your selector more specific, or you need to use !important which I would not recommend, or better, you remove top-stripe from that declaration altogether.
Here's the declaration on your webpage..
Try this:
.top-stripe {
background-color: transparent!important;
}

CSS calc() behaviour in CSS variables

I'm curious to the behaviour of using calc() in setting a CSS variable.
Example:
#test {
--halfWidth: calc(100% / 2);
}
Now, if the #test element, say a div, was 500px wide, I would like the --halfWidth variable to be set to 250px.
But, as far as I can tell the var(--halfWidth) code used elsewhere simply drops in the calc(100% / 2) string instead of 250px. Which means that I can't use the calculation of say element A and use it in element B later on, since it would simply set for example width: var(--halfWidth); as half the width of element B instead of half the width of element A, where the variable was defined.
I've scoured the web trying to find any documentation on the behaviour of this, but I have so far drawn a blank.
Ideally, setting a CSS variable using calc should be available in two variants:
One variant working just like this example, simply dropping in the string as-is, bar any in-string variable replacements.
A second variant where calc() would yield the result of the calculation instead of simply replacing the string.
How to achieve this? I'd rather leave the actual implementation to people suited to it, but one possibility would be an eval() kind of thing; like eval(calc(100% / 2)) would give the result 250px.
Anyway, if anyone have any real documentation on this behaviour or a solution to how to get the example above to yield the result instead, I'm all ears!
Edit: Just FYI, I have read the specs at https://drafts.csswg.org/css-variables/
This is kind of a tough question to answer cause the answer will not be:
Do it like this...then it will work
The problem you are facing is the normal behavior of CSS. It cascades the styles. If what you are trying to achieve would work it would get real messy after a short amount of time.
I mean how cool is it that you can define a variable like this
#test {
--halfWidth: calc(100% / 2);
}
where var(--halfWidth) should always be calc(100% / 2). Did you note that it will always be half the width of the parent element?
Imagine how strange it would be if a programmer in a few months reads your code and has box with a width of 1000px set with --halfWidth and now it is 250px wide ... I would think the internet is broken :) It should just be 500px wide.
To achieve what you want, you could/should define different vars defining the widths of the parent elements. And split it down to the children.
One approach to this is to dynamically add a line to the CSS Object Model (CSSOM) which explicitly declares the width of the .halfwidth class.
This width will then apply to all divs with the .halfwidth class.
In the example below, I have, additionally, made .element-a horizontally resizable, so that you can see more clearly that as you change the width of .element-a, the width of both .halfwidth divs changes proportionately, including the .halfwidth div which is a child of .element-b.
Working Example:
let myStylesheet = document.styleSheets[0];
const elementA = document.getElementsByClassName('element-a')[0];
let elementAWidth = window.getComputedStyle(elementA).getPropertyValue('width');
const calculateHalfWidth = (elementAWidth) => {
myStylesheet.insertRule('.halfWidth { width: ' + (parseInt(elementAWidth) / 2) + 'px; }', myStylesheet.cssRules.length);
}
calculateHalfWidth(elementAWidth);
// ================================================================================
// THE SCRIPT BELOW USES A ResizeObserver TO WATCH THE RESIZABLE .element-a DIV
// ================================================================================
const elementAObserver = new ResizeObserver(entries => {
for (let entry of entries) {
if (entry.contentRect.width !== elementAWidth) {
calculateHalfWidth(entry.contentRect.width);
}
}
});
elementAObserver.observe(elementA);
body {
font-family: sans-serif;
}
div.element {
float: left;
width: 200px;
height: 100px;
margin: 12px 3px;
text-align: center;
border: 1px solid rgb(0, 0, 0);
}
div.element h2 {
font-size: 18px;
}
div.element-a {
resize: horizontal;
overflow: auto;
}
div.element-b {
width: 300px;
}
div.halfWidth {
height: 40px;
margin: 0 auto;
border: 1px dashed rgb(255, 0, 0);
}
div.halfWidth h2 {
font-size: 14px;
}
<div class="element element-a">
<h2>Element A</h2>
<div class="halfWidth">
<h2>halfWidth</h2>
</div>
</div>
<div class="element element-b">
<h2>Element B</h2>
<div class="halfWidth">
<h2>halfWidth</h2>
</div>
</div>

How can I change CSS pseudo-element property dynamically?

I understood:
You can't modify pseudo elements through JavaScript since they are not part of the DOM
I also knew we could add properties in pseudo-element by appending style -- more.
However, the appending solution could only add value. adding doesn't mean the ability of changing dynamically. I also need to the ability of replacing the property value.
Therefore, I tried to use attr() to change background image dynamically. However, currently attr only supports content property - more.
So what else I can try here?
In order to adding more context of the question, basically, I want to dynamically update avatar image in chat. The avatar image is setted in pseudo-element(before and after). Here is the code-pen of Chat UI -- http://codepen.io/clintioo/pen/HAkjq
Thank you very much!
As said in other answers, there is a way to inject styles that will afect your pseudo element.
A somewhat simpler workaround for your specific case could be to just inherit the background from the base element (since you are not using it)
function changebkg () {
target1 = document.getElementById('test');
target1.style.backgroundImage = "url(http://placekitten.com/1000/750)";
}
#test {
font-size: 40px;
position: relative;
display: inline-block;
color: black;
background-size: 0px;
background-color: lightblue;
}
#test:after {
content: "";
position: absolute;
left: 200px;
top: 20px;
width: 200px;
height: 200px;
background-image: inherit;
border: solid 1px;
background-size: contain;
}
<div id="test" onclick="changebkg();">click me</div>
Here is the part in the "duplicate" that shows how to get, add and change CSS pseudo-element property dynamically using Javascript.
Stack snippet
/* on page load */
window.addEventListener('load', function() {
/* get button and add click event to it */
var btn = document.querySelector('button');
btn.addEventListener("click", function(){
/* get first <p> element */
var el1 = document.querySelector('p.first');
/* get second <p> element */
var el2 = document.querySelector('p.second');
/* get first <p> pseudo's "content" property value */
var str = window.getComputedStyle(el1,':before').getPropertyValue('content');
/* get first <p> pseudo's "color" property value */
var col = window.getComputedStyle(el1,':before').getPropertyValue('color');
/* dynamically add a rule to the stylesheet so the second <p>
will get the same "content"/"color" value as the first */
document.styleSheets[0].addRule('p.second:before', 'content: ' + str + ' ; color: ' + col + ';');
/* dynamically add a rule to the stylesheet that override the
first <p> "color" to green */
document.styleSheets[0].addRule('p.first:before', 'color: green;');
});
});
p.first:before {
content:"foo";
color: red;
}
button {
display: block;
width: 220px;
margin-top: 50px;
}
<p class="first">This is a paragraph</p>
<p class="second">This is another paragraph</p>
<button>Change/Add pseudo properties</button>
As you have just learned, attr() isn't supported anywhere else but the content property at the moment. If your requirement is to set other CSS properties dynamically, then I'm afraid you can't do much of that within CSS alone. The closest you can get is to generate static CSS dynamically through a script, as shown in a number of answers to the first question you link to.
In the specific case of user avatars, I don't see why you aren't just marking those up using img elements instead, which would obviate this issue entirely.
You can create a css file and then inject it into the DOM.
var avatar_css_for_avatar = document.createElement('style');
avatar_css_for_avatar.type = 'text/css';
avatar_css_for_avatar.innerHTML = '.user-avatar-id:before { background-image: url(url_of_image); }';
document.getElementsByTagName('head')[0].appendChild(avatar_css_for_avatar);
document.getElementById('someElementId').className = 'user-avatar-id';

CSS/LESS if more then one element

Is there any way, of having a if like syntax, where I can check (for an example) there are more than input[type="text"]
Something like:
.my-element >= 1 {
border: 1px solid red; // Each .my-element will have a red border
}
.my-lement == 1 {
border: 1px solid green; // The only .my-element will have a green border
}
In javascript I would do something like:
if ($('input[type="text"]').length >= 1)
I mentioned LESS in the title, because I'm writing my css code in a LESS syntax
You can, in some cases, approximate this (albeit it requires an up-to-date browser, compliant with CSS3):
input {
border-color: #f00;
}
input:only-of-type {
border-color: #0f0;
}
JS Fiddle demo.
The above works on the assumption that you're trying to style an input element which is the only input element (or 'element of that type') as a child of its parent (it has no siblings of the same input element-type).
If, however, you're trying to style an element differently according to whether it has any sibling elements, you can use:
input {
border-color: #f00;
}
input:only-child {
border-color: #0f0;
}
JS Fiddle demo.
References:
:only-of-type (Mozilla Developer Network).
:only-of-type (W3C.org).
NO, in CSS there is no if else . Use JavaScript for changing your css dynamically.
the if statement is not present in LESS as well. But this language supports guard expression which may help in mimicking some if statements.
Check this tutorial

Chaining CSS rules

I have defined some background colors that I'll be using on my site. So I can easily set the background color of different elements like:
.background_highlite{
background-color: rgb(231, 222, 207); /*Cream in my Coffee*/
}
.background_shadow{
background-color: rgb(201, 179, 156); /*Moose Mousse*/
}
Now, if I want all textarea elements on my page to have Moose Mousse color as their background I want to write another CSS rule that references back to .background_shadow, so I only have to change the rgb values in one place.
Something like:
textarea{
height:50px;
background-color: background_highlite /* want to feed forward to keep the rgb in one place */
}
Is this possible with CSS?
People have been frustrated by CSS's simplistic structure, and have created pre-processors to write CSS more conveniently. Look at Less, for example, or CleverCSS.
You can assign all the elements the same class, and then set the background color in the class's CSS:
<textarea class="background_shadow">blah</textarea>
Keep in mind that you can assign a number of classes to any element, so you can use one class just to control the background color, and then use other classes for your other needs:
<textarea class="background_shadow another_class something_else">...</textarea>
Not really. http://dorward.me.uk/www/css/inheritance/ lists your main options.
Sorry, no. CSS does not support variables, or chaining.
however, there is a javascript library that allows that. http://lesscss.org/
The best you can do would be
.hilight textbox {
background: black;
}
textbox {
color: pink;
}
.background_shadow {
background: grey;
}
Or, of course, you could add the .hilite class to your div.
You have two options to work with:
Native CSS, which is possible, but not good to maintain.
Preprocessor, like xCSS, which can create more cleaner code and provide variables.
For simple projects I assume, native CSS will be good. But in more complicated it`s best to use some sort of processors, like pals talked earlier.
In this method you can always use some human readable rule like:
.blabla {min-height: 20px}, which pre-processor by your own logic transform to CSS, that all of our target browsers can understand, like .blabla {min-height: 20px; height: auto !important; height: 20px;} etc.
Also what I realy like in preprocessors is that you can right code, as here:
.specialClass extends .basicClass {} // see more at extends
.selector {
a {
display: block;
}
strong {
color: blue;
}
} // see more at children
or what you needed is vars {
$path = ../img/tmpl1/png;
$color1 = #FF00FF;
$border = border-top: 1px solid $color1;
} // see more at vars

Resources