How to use negative padding in css - html

I want to add negative padding in css, I have written a small code of battery charging cell. What I want is if I enter value in negative like -1px than the cell color should move to the left side and div should stay in center.
.cell {
width: 100px;
height: 30px;
border: 1px solid black;
}
.padding {
background-color: #3D9970;
width: 10px;
float: left;
height: 30px;
position: absolute;
left: 55px;
padding-right: 1px;
}
<div class="cell">
<div class="cell1"></div>
<div class="padding"></div><span style="display: inline;">
</div>
Please help me.

You can't.
See the specification:
Unlike margin properties, values for padding values cannot be negative.

I think you can achieve the same effect with pseudo elements:
.cell{
display:block;
width: 100px;
height: 30px;
position:relative;
}
.cell:before{
content:'';
background-color: #3D9970;
width: 10px;
top:0;
left:calc(50% - 5px);
height: 100%;
position: absolute;
}
.cell:after{
content:'';
border: 1px solid black;
width:100%;
height:100%;
display:block;
top:0;
left: 0px;
position: absolute;
}
<div class="cell">
</div>
"Left" property could be negative, so if you change it you can move the position of the green rectangle in the middle (.cell:before) of the block and border itself (.after)

The easiest way is to use an absolute positioning relatively to a parent node. Here the parent node would be the battery "housing".
So you can set the position CSS value of the rot div to relative, and then the charge one to absolute. Indeed, according to MDN Webdocs:
absolute: [...] It is positioned relative to its closest positioned ancestor, if any.
Then, you just have to play with the left and width CSS properties. For the "middle" case, I chose to display one border.
Below a working snippet. Just click the "Begin the charge variation" button to start the show.
var chargeElement = document.getElementById("charge");
// To set a charge to the battery, simply call: setCharge(percentage)
function setCharge(percentage) {
var left;
var width;
if (percentage > 100) percentage = 100;
if (percentage < 0) percentage = 0;
chargeElement.setAttribute("data-value", percentage);
// If the charge is 50%, simply draw a line
if (percentage == 50) {
chargeElement.className = "middle";
} else {
chargeElement.className = "";
}
// Otherwise, adjust left and width values
if (percentage >= 50) {
left = 50;
width = percentage - left;
} else {
left = percentage;
width = 50 - left;
}
// Then update the charge style.
chargeElement.style.left = left + "%";
chargeElement.style.width = width + "%";
}
// A simple function to add / remove some charge
function addCharge(percentage) {
var value = parseInt(chargeElement.getAttribute("data-value"));
value += percentage;
setCharge(value);
}
// Here just some stuff for illustration.
// You don't need those functions to set the charge.
function letsBeginTheShow(buttonElement) {
buttonElement.disabled = true;
setNextCharge(10);
}
function setNextCharge(increment) {
var percentage = parseInt(chargeElement.getAttribute("data-value"))
percentage += increment;
if (percentage > 100) {
percentage = 100;
increment = -5;
}
if (percentage < 0) {
percentage = 0;
increment = 5;
}
setCharge(percentage);
setTimeout(function() {
setNextCharge(increment);
}, 50);
}
setCharge(50);
.battery {
position: relative;
width: 100px;
height: 30px;
border: 1px solid black;
/* Below : only for aestethic reasons */
float: left;
margin-right: 30px;
/* End of aesthethic stuff */
}
#charge {
height: 100%;
position: absolute;
background-color: #3D9970;
border-color: #3D9970;
}
.middle {
border-left: 1px solid;
}
<div class="battery">
<div id="charge" data-value="50" class="middle"></div>
</div>
<button onclick="letsBeginTheShow(this)">Begin the charge variation</button>

Related

Header position offset not following top margin of container

Here I have a header with position: fixed. As it does not go with the normal flow of the window, a margin for the body is set to the height of the header (here 100px). Now, the body starts right after the bottom of the header.
The main div in the body has a margin-top of 50px. But, the header grasps that margin, and it's not shown. If I set a border on the body, then the margin is shown. I don't know what is the relation of that top margin with the border of the body.
This can be solved if I add 50px more to the margin-top of the main div. But I want to know what's happening here.
body {
background-color: white;
margin-top: 100px;
/* border: 1px solid black; */
}
header {
background-color: black;
height: 100px;
position: fixed;
z-index: 1;
top: 0;
left: 0;
right: 0;
}
main {
background-color: gray;
margin-top: 50px;
width: 100%;
height: 100vh;
}
<header></header>
<main></main>
Adding a border adjusts the display of the layout because the <body> and the <main> margins overlap without the border (since it's just whitespace), but with the border rendered, the two margins must be separate. Thus, without the border, the total margin is 100px, and with the border, the total margin is 150px.
See demo below. (I've also added a button to hide the <header> since it's position is fixed, so it isn't relevant to the situation.
const body = document.querySelector("body");
const header = document.querySelector("header");
const a = document.createElement("div");
const b1 = document.createElement("button");
b1.textContent = "Toggle body border";
b1.addEventListener("click", () => {
if (body.style.border !== "1px solid red") {
body.style.border = "1px solid red";
} else {
body.style.border = "none";
}
});
const b2 = document.createElement("button");
b2.textContent = "Toggle body margin";
b2.addEventListener("click", () => {
if (body.style.marginTop !== "0px") {
body.style.marginTop = "0px";
} else {
body.style.marginTop = "100px";
}
});
const b3 = document.createElement("button");
b3.textContent = "Toggle header visibility";
b3.addEventListener("click", () => {
if (header.style.display !== "none") {
header.style.display = "none";
} else {
header.style.display = "block";
}
});
a.appendChild(b1);
a.appendChild(b2);
a.appendChild(b3);
a.style.position = "fixed";
a.style.top = "0";
a.style.zIndex = "2";
document.body.appendChild(a);
body {
background-color: white;
margin-top: 100px;
}
header {
background-color: black;
height: 100px;
position: fixed;
z-index: 1;
top: 0;
left: 0;
right: 0;
}
main {
background-color: gray;
margin-top: 50px;
width: 100%;
height: 100vh;
}
<header></header>
<main></main>

How can I position the element at very precise pixel on image using Top and Left CSS property

I want to display a dot at specific pixel on image click. I'm displaying it by giving top and left values in %. What happening is the dot isn't moving when clicked another pixel present inside the dot.
When click outside then it is moving. I don't understand why this is happening.
May be it is because there is very small change in top and left values for each pixel.
I've updated CSS for displaying dot within the circle
.hObiiS{
border: solid 1px #303030 !important;
background: rgba(0, 0, 0, 0.3);
border-radius: 50%;
box-sizing: border-box;
box-shadow: none !important;
height: 9px !important;
position: absolute;
transform: translate3d(-50%, -50%, 0);
width: 9px !important;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.hObiiS::before{
position: absolute;
content: '';
width: 1px;
height: 1px;
background-color: rgb(224, 1, 1);
border-radius: 50%;
}
<div class="hObiiS" style="top: 25.4601%; left: 58.6382%;"></div>
Can someone please provide solution to move dot per pixel ?
Here is your problem solution.
let container = document.querySelector('img');
let dot = document.getElementById('dot');
document. addEventListener('click', function( e ) {
if (container === event.target && container.contains(e. target)) {
var parentPosition = getPosition(container);
var xPosition = e.clientX - parentPosition.x - (dot.clientWidth / 2);
var yPosition = e.clientY - parentPosition.y - (dot.clientHeight / 2);
dot.style.left = xPosition + "px";
dot.style.top = yPosition + "px";
}
});
// Helper function to get an element's exact position
function getPosition(el) {
var xPos = 0;
var yPos = 0;
while (el) {
if (el.tagName == "BODY") {
// deal with browser quirks with body/window/document and page scroll
var xScroll = el.scrollLeft || document.documentElement.scrollLeft;
var yScroll = el.scrollTop || document.documentElement.scrollTop;
xPos += (el.offsetLeft - xScroll + el.clientLeft);
yPos += (el.offsetTop - yScroll + el.clientTop);
} else {
// for all other non-BODY elements
xPos += (el.offsetLeft - el.scrollLeft + el.clientLeft);
yPos += (el.offsetTop - el.scrollTop + el.clientTop);
}
el = el.offsetParent;
}
return {
x: xPos,
y: yPos
};
}
.container {
position: relative;
cursor: "crosshair";
}
#dot {
position: absolute;
top: 0;
left: 0;
width: 10px;
height: 10px;
display: inline-block;
background-color: red;
transform: translate(100, 0);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="container">
<img width="200px" alt="" src="https://img.rawpixel.com/s3fs-private/rawpixel_images/website_content/upwk62143495-wikimedia-image.jpg?w=800&dpr=1&fit=default&crop=default&q=65&vib=3&con=3&usm=15&bg=F4F4F3&ixlib=js-2.2.1&s=218f80fbd029cd0fa69b8597ef4928c0" />
<span id="dot" />
</div>
</body>
</html>
Codepen
Your mouse click position (e.clientX and e.clientY) is relative to your browser's top-left corner that's why your click position is not accurate. You can study the details explanation in this article.
Move Element to Click Position
You need to stop the dot from stopping the click going through to the image.
You can use pointer-events for that.
Here's a simple example:
.container {
position relative;
display: inline-block;
width: 30vmin;
height: 30vmin;
}
img {
position: relative;
width: 100%;
height: 100%;
object-fit: cover;
}
.dot {
background: red;
width: 30px;
height: 30px;
border-radius: 50%;
position: absolute;
top: 10%;
left: 10%;
pointer-events: none;
}
<div class="container"><img onclick="alert('I saw the click');" src="https://picsum.photos/id/1015/300/300">
<div class="dot"></div>
</div>

Why is my paragraph popup coming outside my div with the "mousedown" event?

I need to show my paragraph inside my <div> when click on the <div>. This is my code:
const area = document.getElementById("area");
const popup = document.getElementById("popup");
function showPopup(event) {
let x = event.clientX;
let y = event.clientY;
popup.style.left = `${x}px`;
popup.style.top = `${y}px`;
popup.style.visibility = "visible";
}
area.addEventListener("mousedown", showPopup);
.area {
border: 1px solid;
position: absolute;
height: 200px;
width: 200px;
}
.popup {
visibility: hidden;
position: absolute;
display: inline-block;
}
<div id="area" class="area">
<p class="popup" id="popup">popup</p>
</div>
Note that this is inside another main body <div> (also with position: absolute).
Try this
<div id="area">
<div class="area""
<p class="popup" id="popup">popup</p>
</div>
</div>
I tested your code and observed you are changing style.top property based on your ClientX value which is causing popup element to appear over random position. Use following updated code and it's should be good.
function showPopup(event) {
console.log(event.clientX, event.clientY)
let x = event.clientX;
let y = event.clientY;
popup.style.left = `${x - 8}px`;
popup.style.top = `${y - 8}px`;
popup.style.visibility = "visible";
}
and few CSS changes as -
.area {
border: 1px solid;
position: relative;
height: 200px;
width: 200px;
}
.popup {
visibility: hidden;
position: absolute;
display: inline-block;
margin: 0;
}
For more close positioning of popup element.

Can animation only be applied to 'absolute' positioned elements?

I am trying to animate an object using DOM and struggling to animate the element when its CSS property position is not set to "absolute". Here is my code below:
I create a circle HTML element and try to move it in 45 degrees. Is there any way to animate an HTML element object that is not positioned absolute?
x = 10;
function on_click() {
var myCurvyMovement = document.getElementById("circle");
myCurvyMovement.style.left = 0.5 * x;
myCurvyMovement.style.top = 1 + x
x += 10;
}
#circle {
position: absolute;
width: 100px;
height: 100px;
background: red;
-moz-border-radius: 50px;
-webkit-border-radius: 50px;
border-radius: 50px;
}
/* Cleaner, but slightly less support: use "50%" as value */
#divBox {
position: static
}
<body>
<button style="display:block" onclick="on_click()">Move the box</button>
<div id="circle">
</div>
</body>
I wouldn't consider left/right in order to do animation. As you have noticed, it won't work in all the cases as it need positionned elements. Even when using positionned element you won't have the same behavior between relative, absolute and fixed because each one will have its own reference for top/left.
For such case better consider transform that you can apply to any element (shouldn't be an inline element) and the reference of the movement will be the same for all. You will also have better performance.
x = 10;
function on_click() {
var myCurvyMovement = document.getElementById("circle");
myCurvyMovement.style.transform = "translate(" + (0.5 * x)+"px,"+(1 + x)+"px)";
x += 10;
}
#circle {
width: 100px;
height: 100px;
background: red;
border-radius: 50px;
transition:0.5s all; /*to have a smooth movement*/
}
<body>
<button style="display:block" onclick="on_click()">Move the box</button>
<div id="circle">
</div>
</body>
You forgot to concatenate the "px" to set the x and y positions
x = 10;
function on_click() {
var myCurvyMovement = document.getElementById("circle");
myCurvyMovement.style.left = 0.5 * x + 'px';
myCurvyMovement.style.top = 1 + x + 'px';
x += 10;
}
#circle {
position: absolute;
width: 100px;
height: 100px;
background: red;
-moz-border-radius: 50px;
-webkit-border-radius: 50px;
border-radius: 50px;
}
/* Cleaner, but slightly less support: use "50%" as value */
#divBox {
position: static
}
<body>
<button style="display:block" onclick="on_click()">Move the box</button>
<div id="circle">
</div>
</body>
when not's absolute you need change the margin-left and margin-top property, in javascript is like this
myCurvyMovement.style.marginLeft = 1 + x + 'px'
myCurvyMovement.style.marginTop = 1 + x + 'px'
(top/bottom and left/rigth)

HTML element wont stay positioned at bottom

So I have a chat UI that is a box where messages go, and at the bottom of the box of messages is a text input element. It works fine at the beginning, but once enough messages appear then the text input element scrolls up, along with the messages, and will not stay positioned at the bottom. How can I do this? Any useful thoughts would be appreciated.
<html>
<body>
<div id="chatui">
<div id="chatmsgs"></div>
<input type="text" id="chatbox">
</div>
</body>
</html>
Here is my CSS:
#chatui {
z-index:3;
position:absolute;
bottom:5px;
width: 380px;
height: 150px;
border: 3px solid #8AC007;
margin-left:5px;
overflow:auto;
}
#chatbox {bottom:3px;position:absolute;width:378px;}
#chatmsgs {position:absolute;}
Here is my Javascript:
This just says when you press "Enter" on your keyboard to display the text you typed into the "chatmsgs" div.
$(window).keydown(function(e){
if (e.keyCode == 13) {
if (document.activeElement.id == 'chatbox') {
var msg = document.getElementById('chatbox').value;
document.getElementById('chatbox').value = '';
var ms = '<p>'+msg+'</p>';
$('#chatmsgs').append(ms);
}
}
});
Check out this fiddle to see what I am talking about:
https://jsfiddle.net/ev3uymw6/
You have to add overflow:auto and appropriate height to the chatmsgs div, so that it doesn't grow beyond the size of chatui and make it scroll alltogether.
$(window).keydown(function(e) {
if (e.keyCode == 13) {
if (document.activeElement.id == 'chatbox') {
var msg = document.getElementById('chatbox').value;
document.getElementById('chatbox').value = '';
var ms = '<p>' + msg + '</p>';
$('#chatmsgs').append(ms);
}
}
});
#chatui {
z-index: 3;
position: absolute;
bottom: 5px;
width: 380px;
height: 150px;
border: 3px solid #8AC007;
margin-left: 5px;
}
#chatbox {
bottom: 3px;
position: absolute;
width: 378px;
}
#chatmsgs {
position: absolute;
height: 130px;
overflow: auto;
width: 378px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="chatui">
<div id="chatmsgs">
</div>
<input type="text" id="chatbox">
</div>
</body>