Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make an Upvote/Downvote button?

This is just for the styling, 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. Thanks in advance.

like image 770
user519753 Avatar asked Nov 25 '10 07:11

user519753


People also ask

How do I make upvote and Downvote buttons Reddit?

For the upvote and downvote button, you can click Mod Tools >> Community Appearance >> Posts. From there, you can find Up + Down Vote Icons. select custom and you can change the upvote and downvote button looks.

What is upvote Downvote?

Some formal definitions of downvote refer to “voting against a cumulative tally of popular support.” Downvote is the opposite of upvote, which represents support for something. On Reddit, upvote and downvote user events are tabulated, and have an effect on how content is represented on the Reddit website.

How do you Downvote a tweet?

When looking at a reply, you'll know if you are part of Twitter's downvote test if you see a down arrow between the heart icon and the share icon under the reply. If you see a down arrow, this means you are part of the test and you have the ability to downvote replies on tweets.

How do Upvotes and Downvotes work on Reddit?

Upvotes show that redditors think content is positively contributing to a community or the site as a whole. Downvotes mean redditors think that content should never see the light of day. If you like something, be it a post or a comment, and you think it contributes to a conversation, upvote it!


2 Answers

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:

The up/down sprite image

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>
like image 179
Jan Avatar answered Oct 09 '22 20:10

Jan


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> 
like image 28
KillerFish Avatar answered Oct 09 '22 18:10

KillerFish