CSS-Add round status button on top of another - html

I am new to css. How can I add a status button which changes color depending on chat availability on top of another button?

You can use the position property.
See an example code here.
Some resources:
https://www.w3schools.com/css/css_positioning.asp
https://developer.mozilla.org/en-US/docs/Web/CSS/position

From the picture i can tell you don't have to use 2 html elements on top of each other, but you can use css properties like border and background-color to achieve exactly as the button in your picture.
I posted how in the code below with even a little bit of javascript to toogle the button status (not needed for styling, so if you don't know any javascript yet, you can skip that part).
let isOpen = false;
const btn = document.querySelector("#btn");
const dot = document.querySelector(".dot");
const txt = document.querySelector("#text");
btn.addEventListener("click", () => {
if (isOpen) {
dot.style.backgroundColor = "red";
txt.innerHTML = "The chat is now closed";
} else {
dot.style.backgroundColor = "green";
txt.innerHTML = "The chat is now open";
}
isOpen = !isOpen;
});
.dot {
height: 25px;
width: 25px;
background-color: red;
border-radius: 50%;
display: inline-block;
border: 5px solid gray;
}
#wrapper {
border: 1px solid black;
text-align: center;
padding: 10px;
}
#btn {
margin-top: 10px;
}
<div id="wrapper">
<span class="dot"></span>
<p id="text">The chat is now closed</p>
</div>
<button id="btn">Toogle</button>

Related

how to change the background-Color on click of a button in javascript

I was able to change the color of the text but i am not able to understand how to change the background color of the p tag. If someone can please let me know hoe to do it. Below is my HTML and JS code.
function button(){
var btn = document.getElementById('btn');
btn.addEventListener('click', function onClick(event) {
// Change text color globally
document.body.style.color = 'red';
});
}
button();
<style>
p{
box-sizing: border-box;
border: 1px solid black;
height: 20px;
width: 300px;
text-align: center;
}
</style>
<p>Welcome To My Domain</p>
<button id="btn">Button</button>
You could add a class to the p tag and then query that within your event listener and set its style attribute, document.querySelector('.classname').style.backgroundColor = 'somecolor'
function button() {
var btn = document.getElementById('btn');
btn.addEventListener('click', function onClick(event) {
// Change text color globally
document.body.style.color = 'red';
document.querySelector('.welcome').style.backgroundColor = 'black';
});
}
button();
<style>
p {
box-sizing: border-box;
border: 1px solid black;
height: 20px;
width: 300px;
text-align: center;
}
</style>
<p class="welcome">Welcome To My Domain</p>
<button id="btn">Button</button>
Another way would be to toggle a class that styles your element for you. With this example add the class and style it in your css and then use the classList in javascript to toggle the class.
document.querySelector('.className').classList.toggle('someclass')
function button() {
var btn = document.getElementById('btn');
btn.addEventListener('click', function onClick(event) {
// Change text color globally
document.querySelector('.welcome').classList.toggle('instance-change')
});
}
button();
.instance-change {
color: red;
background-color: black;
}
p {
box-sizing: border-box;
border: 1px solid black;
height: 20px;
width: 300px;
text-align: center;
}
<p class="welcome">Welcome To My Domain</p>
<button id="btn">Button</button>

RTL - Why the border-right is not changing

I'm trying right to left direction in my HTML as it will be useful for languages like arabic,hebrew
The problem which i face is border-right is not changing it's retained in the same place when shifted to RTL. According to my understanding i thought border-right will be changed as border-left when i switch to RTL mode.
What does RTL property really does?. It just shifts only the content.
If so i can do the workaround by changing the border-right to left in case of RTL. But before doing that i just to want understand what the RTL really does. Please throw some light on it
var rtl = document.getElementById('RTL');
var content = document.getElementById('content');
var currentState;
rtl.onclick = implementRTL;
function implementRTL() {
currentState = content.getAttribute('dir');
if (currentState == 'ltr') {
content.setAttribute('dir', 'rtl');
} else {
content.setAttribute('dir', 'ltr');
}
}
div {
border: 10px solid #000;
border-right: 10px solid red
}
<div id="content" dir="ltr">
Hi Here is the content
</div>
<button id="RTL">
RTL SWITCH
</button>
Check the code below which i tried
border-inline-end
This property sets the right border when the text is LTR and the left border in case of RTL. Similarly, there is border-inline-start for the border on the other side, and border-block-start and border-block-end for the top and bottom borders. They apply correctly to vertical text as well.
var rtl = document.getElementById('RTL');
var content = document.getElementById('content');
var currentState;
rtl.onclick = implementRTL;
function implementRTL() {
currentState = content.getAttribute('dir');
if (currentState == 'ltr') {
content.setAttribute('dir', 'rtl');
} else {
content.setAttribute('dir', 'ltr');
}
}
div {
border: 10px solid #000;
/* border-right: 10px solid red; */ /* old */
border-inline-end: 10px solid red; /* new */
}
<div id="content" dir="ltr">
Hi Here is the content
</div>
<button id="RTL">
RTL SWITCH
</button>
dir="ltr" sets the direction of content flow within a block-level element. This applies to text, inline, and inline-block elements. It also sets the default alignment of text and the direction that table cells flow within a table row.
You can use direction: rtl; in CSS and do something like that :
.rtl {
direction: rtl;
}
.element {
border-right: 1px solid red;
}
.rtl .element {
border-right: none;
border-left: 1px solid red;
}
or
.element {
border-right: 1px solid red;
}
#content:dir(rtl) .element {
border-right: none;
border-left: 1px solid red;
}
When the "dir" attribute of content reflects a value of either ltr or rtl, what gets effected is the direction in which text displays. Altering the border-color of an element generally requires a manual solution. Here is one way to accomplish this feat:
HTML:
<div id="content" dir="ltr">
Hi! Here is the content
</div>
<button id="RL">
RL SWITCH
</button>
CSS:
div,.divltr {
border: 10px solid #000;
border-right: 10px solid red;
}
.divrtl {
border: 10px solid #000;
border-left: 10px solid red;
}
JAVASCRIPT:
var d = document;
d.g = d.getElementById;
var rl = d.g('RL');
var c = d.g('content');
rl.addEventListener('click',function(){
toggleWhichWay();
});
function setTextBorder(whichway) {
c.setAttribute('dir', whichway);
c.className = "div" + whichway;
}
function getCurrState() {
return c.getAttribute('dir');
}
function toggleWhichWay() {
(getCurrState() == 'ltr')? setTextBorder('rtl') :setTextBorder('ltr');
}
see demo.
var toggleButton = document.querySelector('#rtl');
var targetEle = document.querySelector('#content');
function toggleTextDir(ele) {
var dir = ele.attributes.dir.value;
ele.attributes.dir.value = dir === 'rtl' ? 'ltr' : 'rtl';
}
toggleButton.addEventListener('click', function() {
toggleTextDir(targetEle);
});

CSS - Have Image Move With Centered Text-Align Input Text

I have an text input with the following HTML:
<span>
✍
</span>
<input type="text">
and the corresponding CSS:
input{
text-align: center;
border: none;
outline: none;
background-color: transparent;
}
The input element should blend seamlessly into its background with only the HTML icon indicating that it is indeed an input. The HTML icon will remain in a static position with the current mark-up as new text is added into the input.
Is there anyway to have my HTML icon start right to the left of the first letter and have it gradually move toward the left as the left boundary of the text string pushes in the same direction?
Fiddle Example
If you're ok with contenteditable you could try this:
span{
display: inline-block;
position: relative;
left: 50%;
transform: translateX(-50%);
}
span::before {
content: '\270D';
}
<span contenteditable='true'></span>
A possible but imperfect (needs lots of work) idea using jquery.
fiddle
$('input').bind('keypress', function(e) {
var tester = $(this).val().length;
var code = e.keyCode || e.which;
var currentWidth = $('input').css('width').slice(0, -2);
var currentWidthParsed = parseInt(currentWidth, 10);
if(code == 8) {
var newWidth = (currentWidthParsed - 8) + 'px'
$('input').css('width', newWidth);
} else {
var newWidth = (currentWidthParsed + 8) + 'px'
$('input').css('width', newWidth);
}
});
body {
text-align: center;
}
input{
text-align: left;
border: none;
outline: none;
background-color: transparent;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<span>
✍
</span>
<input type="text">
As far as I know you can't have dynamic width of inputs with something like width: auto. In that case you could have a wrapper with fixed with and a text-align right.
So I would say the only possibility is to have that icon inside the value of the input (if it may exist as UTF-8 icon) and then strip it out when processing the value. But of course this would seem dirty.

Start Content from bottom of container and push up

So what I'm trying to accomplish seems like easy CSS etc. Im changing a messaging system and what the conversations to start at the bottom sorta like Facebook or text message where it has one person on the left and the other on the right.
How do I get the divs to go up as new content is added via ajax? I saw this similar question but didn't quite understand what he mean focus on the LI. An example would be great.
Something like this perhaps?
<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
function prependChild(parent, element)
{
if (parent.childNodes)
parent.insertBefore(element, parent.childNodes[0]);
else
parent.appendChild(element)
}
window.addEventListener('load', mInit, false);
function mInit()
{
byId('btnAddNew').addEventListener('click', onAddBtnClicked, false);
}
function onAddBtnClicked()
{
var txtInputElem = byId('newMsgTxtInput');
var msgTxt = txtInputElem.value;
var li = newEl('li');
li.appendChild( newTxt( msgTxt ) );
var ulTgt = byId('msgTarget');
var existingLiItems = ulTgt.querySelectorAll('li');
var numItemsExisting = existingLiItems.length;
if (numItemsExisting%2 != 0)
li.className = 'even';
else
li.className = 'odd';
prependChild(ulTgt, li);
}
</script>
<style>
.controls
{
display: inline-block;
padding: 8px;
margin: 8px;
border: solid 1px #555;
border-radius: 4px;
color: #777;
background-color: #ddd;
}
#msgTarget
{
width: 275px;
border: solid 1px #555;
margin: 8px;
border-radius: 4px;
}
/*
Doesn't work 'properly' - since we add items at the top, rather than the bottom
The first item added will be 'even', then the second item gets added and now it's the first child 'even'
so, the item added first is now an 'odd' child. A better way may be to count the number of existing li
items the ul contains, before assigning the new li elements a class of even or odd that will enable css
styling.
#msgTarget li:nth-child(odd)
{
background-color: #CCC;
}
#msgTarget li:nth-child(even)
{
background-color: #5C5;
}
*/
.odd
{
background-color: #CCC;
}
.even
{
background-color: #5C5;
}
</style>
</head>
<body>
<div class='dlg'>
<div class='controls'>
<input id='newMsgTxtInput'/><button id='btnAddNew'>Add message</button>
</div>
<ul id='msgTarget'></ul>
</div>
</body>
</html>

How can I make an Upvote/Downvote button?

I'm trying to make an upvote/downvote the same way that it's done on SO and Reddit, from what I can see they use arrow images as backgrounds and then position it, but I'm a CSS newbie and I need someone to walk me through it.
You could do it by adding a different picture to the background, one for every state of the button. There is however a cleaner, easier, more modern way of achieving this result: Sprites.
A sprite is an image that is saved as a part of a larger image. One of the biggest advantages of using sprites is the reduction of round-trips to the server for all the images to just one request for the Sprites. The element to display a picture has the image as background. The background is moved relative to the element so the element displays only part of the image. Like when you move a photo-frame over a poster (or in this case: moving the poster under the frame)
At SO they make an image that contains all the states for the button. They give the element for the button (a span in this case) a fixed width and height and add the background to it with CSS. Then toggle a class for the state (on or off) with javascript on the click event. Now the only thing you have to do in CSS is change the position of the background with CSS classes:
for (const btn of document.querySelectorAll('.vote')) {
btn.addEventListener('click', event => {
event.currentTarget.classList.toggle('on');
});
}
.vote {
display: inline-block;
overflow: hidden;
width: 40px;
height: 25px;
cursor: pointer;
background: url('http://i.stack.imgur.com/iqN2k.png');
background-position: 0 -25px;
}
.vote.on {
background-position: 0 2px;
}
Click to vote (using sprites): <span class="sprite vote"> </span>
You can easily add more states to the sprites like 'hover' and 'active' just the same way. SO even puts all the images for the whole page in a single image. You can verify this with firebug or the Chrome developer tools. Look for 'sprites.png'.
Update (2020)
It's been 10 years since I answered this question and in this time,
the landscape has changed. Now you can use inline svg as well to achieve this effect. I've updated the code snippet to use svg. This is how stackoverflow currently does this.
It works by toggling the color property of a surrounding span element on button click. The span element contains an inline svg image of an arrow. The fill property of the path that makes up the arrow is initialized with currentColor, which instructs it to take whatever is the current text color.
for (const btn of document.querySelectorAll('.vote')) {
btn.addEventListener('click', event => {
event.currentTarget.classList.toggle('on');
});
}
.vote {
display: inline-block;
cursor: pointer;
color: #687074
}
.vote.on {
color: #f48024
}
Click to vote (using svg):
<span class="vote">
<svg width="36" height="36">
<path d="M2 10h32L18 26 2 10z" fill="currentColor"></path>
</svg>
</span>
You can do it by using two simple images ... design two images in some image editors like Photoshop, if u don't have MSPaint...
CSS code is
#voting{
width:30px;
height:40px;
}
.upvote{
width:30px;
height: 20px;
cursor: pointer;
}
.downvote{
width:30px;
height: 20px;
background: url('downvote.jpg') 0 0 no-repeat;
cursor: pointer;
}
HTML code :
<div id="voting">
<div class="upvote"></div>
<div class="downvote"></div>
</div>
I'm doing project on django, and I'm trying to implement up-vote and down-vote on many posts, I've taken #Jan's code partly and finished it.
vote.html
<span onclick="like_function({{user_answer.pk}})" id="like-{{user_answer.pk}}" class="vote_up_off"></span>
<div id="counter-{{user_answer.pk}}">0</div>
<span onclick="dislike_function({{user_answer.pk}})" id="dislike-{{user_answer.pk}}" class="vote_down_off"></span>
vote.css
/* like dislike button */
.vote_up_off {
display: inline-block;
overflow: hidden;
width: 40px;
height: 25px;
cursor: pointer;
background: url(' https://i.stack.imgur.com/nxBdX.png');
background-position: 0 -25px;
margin-left: 5px;
}
.vote_up_on {
background-position: 0 2px;
display: inline-block;
overflow: hidden;
width: 40px;
height: 25px;
cursor: pointer;
background: url('https://i.stack.imgur.com/nxBdX.png');
margin-left: 5px;
}
.vote_down_off {
display: inline-block;
overflow: hidden;
width: 40px;
height: 25px;
cursor: pointer;
background: url('https://i.stack.imgur.com/vWw7n.png');
background-position: 0 -1px;
margin-top: 3px;
}
.vote_down_on {
display: inline-block;
overflow: hidden;
width: 40px;
height: 25px;
cursor: pointer;
background: url('https://i.stack.imgur.com/vWw7n.png');
background-position: 0 -28px;
margin-top: 3px;
}
vote.js
function like_function(answer_id) {
var like_button = document.getElementById('like-'+answer_id);
var dislike_button = document.getElementById('dislike-'+answer_id);
var counter_element = document.getElementById('counter-'+answer_id);
let current_counter = parseInt(counter_element.innerText);
//check if dislike is on(true) or off(false)
let dislike_state = false
if (dislike_button.className == "vote_down_on") {
dislike_state = true
}
else {
dislike_state = false
}
//if dislike is checked
if (dislike_state) {
current_counter += 2;
dislike_button.className = 'vote_down_off'
counter_element.innerText = current_counter
like_button.className = 'vote_up_on'
}
// if dislike is not checked
else {
if (like_button.className == 'vote_up_off') {
like_button.className = "vote_up_on"
current_counter += 1;
counter_element.innerText = current_counter
}
else {
like_button.className = "vote_up_off"
current_counter += -1;
counter_element.innerText = current_counter
}
}
}
function dislike_function(answer_id) {
var like_button = document.getElementById('like-'+answer_id);
var dislike_button = document.getElementById('dislike-'+answer_id);
var counter_element = document.getElementById('counter-'+answer_id);
let current_counter = parseInt(counter_element.innerText);
//check if like is on(true) or off(false)
let like_state = false
if (like_button.className == "vote_up_on") {
like_state = true
}
else {
like_state = false
}
//if like is checked
if (like_state) {
console.log('это тру лайк (лайк нажат)')
current_counter += -2;
like_button.className = 'vote_up_off'
counter_element.innerText = current_counter
dislike_button.className = "vote_down_on"
}
//if like is not checked
else {
if (dislike_button.className == 'vote_down_off') {
dislike_button.className = "vote_down_on"
current_counter += -1;
counter_element.innerText = current_counter
}
else {
dislike_button.className = "vote_down_off"
current_counter += 1;
counter_element.innerText = current_counter
}
}
}