I want to achieve the following shapes using pure CSS, no images.
I've come to the following point.
Here is the HTML structure:
<div class="sixteen columns">
<div id="applicationStatus">
<ul>
<li class="applicationStatus">Application Received</li>
<li class="applicationStatusGood">Language Exam</li>
<li class="applicationStatusNoGood">Oral Exam</li>
<li class="applicationStatus">Grant</li>
</ul>
</div>
</div>
And here is the CSS:
#applicationStatus {
position: relative;
width: auto;
height: 140px;
left: 40px; }
ul.applicationStatus {
list-style: none; }
li.applicationStatus, li.applicationStatusGood, li.applicationStatusNoGood {
height: 140px;
background-color: #767676;
display: inline-block;
/* Dirty IE Hack */
zoom: 1;
*display: inline;
margin-right: 30px;
margin-left: 30px;
padding: 10px;
color: white;
font-size: 18px;
text-align: center;
line-height: 150px;
/* vertical-align: middle; */ }
li.applicationStatus:after, li.applicationStatusGood:after, li.applicationStatusNoGood:after {
content: "";
position: absolute;
width: 0;
height: 0;
border-top: 80px solid transparent;
border-left: 30px solid #767676;
border-bottom: 80px solid transparent;
margin: -10px 90px 0 10px; }
li.applicationStatus:before, li.applicationStatusGood:before, li.applicationStatusNoGood:before {
content: "";
position: absolute;
width: 0;
height: 0;
left: 0px;
border-top: 80px solid transparent;
border-left: 30px solid white;
border-bottom: 80px solid transparent;
margin: -10px 0px 0 0px; }
li.applicationStatus:first-child, li.applicationStatusGood:first-child, li.applicationStatusNoGood:first-child {
margin-left: 0px;
text-indent: 30px; }
li.applicationStatus:last-child, li.applicationStatusGood:last-child, li.applicationStatusNoGood:last-child {
border-top: 0px solid transparent;
border-left: 0px solid transparent;
border-bottom: 0px solid transparent; }
li.applicationStatusGood {
background-color: #77a942; }
li.applicationStatusGood:after {
border-left: 30px solid #77a942; }
li.applicationStatusNoGood {
background-color: #c42c00; }
li.applicationStatusNoGood:after {
border-left: 30px solid #c42c00; }
Why doesn't the :before selector apply to all of the shapes or all in all how can I achieve what I want?
Modification of Your Code
The main issue you faced was not having position: relative on your li elements. But there were other things that needed tweaking too.
Here is a fiddle example to see.
I added the class you failed to reference in your HTML above to the ul element, so here is the HTML:
<div class="sixteen columns">
<div id="applicationStatus">
<ul class="applicationStatus">
<li class="applicationStatus">Application Received</li>
<li class="applicationStatusGood">Language Exam</li>
<li class="applicationStatusNoGood">Oral Exam</li>
<li class="applicationStatus">Grant</li>
</ul>
</div>
</div>
Then I modified your CSS a bit to condense it (could be more condensed if CSS3 only was being supported):
#applicationStatus {
position: relative;
width: auto;
height: 140px;
left: 40px; }
.applicationStatus li { /* Added this and moved much code to here */
position: relative; /* this was a key property missing from your code */
text-indent: 30px;
height: 140px;
background-color: #767676;
display: inline-block;
/* Dirty IE Hack */
zoom: 1;
*display: inline;
/* margin-right: 30px; Eliminated this */
margin-left: 30px;
padding: 10px 10px 10px 30px; /* tweaked this */
color: white;
font-size: 18px;
text-align: center;
line-height: 150px;
}
ul.applicationStatus { /* this was irrelevant with the HTML you gave, but I added the class to the ul */
list-style: none; }
/* tweaked various things below here */
li.applicationStatus:first-child:after, li.applicationStatusGood:after, li.applicationStatusNoGood:after {
content: "";
position: absolute;
width: 0;
height: 0;
border-top: 80px solid transparent;
border-left: 30px solid #767676;
border-bottom: 80px solid transparent;
margin: -10px 90px 0 10px;
}
li.applicationStatus:last-child:before, li.applicationStatusGood:before, li.applicationStatusNoGood:before {
content: "";
position: absolute;
width: 0;
height: 0;
left: 0;
border-top: 80px solid transparent;
border-left: 30px solid white;
border-bottom: 80px solid transparent;
margin: -10px 0px 0 0px;
}
li.applicationStatus:first-child {
padding-left: 10px;
margin-left: 0;
}
li.applicationStatus:last-child {
padding-right: 30px;
}
li.applicationStatusGood {
background-color: #77a942; }
li.applicationStatusGood:after {
border-left: 30px solid #77a942; }
li.applicationStatusNoGood {
background-color: #c42c00; }
li.applicationStatusNoGood:after {
border-left: 30px solid #c42c00; }
U can try this website.
http://cssarrowplease.com/
.arrow_box {
position: relative;
background: #88b7d5;
border: 8px solid #c2e1f5;
}
.arrow_box:after, .arrow_box:before {
left: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.arrow_box:after {
border-color: rgba(136, 183, 213, 0);
border-left-color: #88b7d5;
border-width: 30px;
top: 50%;
margin-top: -30px;
}
.arrow_box:before {
border-color: rgba(194, 225, 245, 0);
border-left-color: #c2e1f5;
border-width: 41px;
top: 50%;
margin-top: -41px;
}
Related
So I want to create a button that looks like this when it's active (you can see that it has a little arrow pointing to the right)
Currently I have something like that, it stays blue after clicked, text turns white and all that. I used .addClass for that, but I have no idea if I should use it again to glue on a triangle onto my button, there has to be a better way right?
While I'm at it, how can I make the shadow/sidebar?
Please, experienced people, give this beginner some enlightenment
add below css for
.active {
height: 50px;
width: 100px;
background: blue;
height: 50px;
width: 100px;
background: blue;
position: relative;
}
.active:after {
content: "";
border-right: 10px solid transparent;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 10px solid black;
height: 0;
width: 0;
position: absolute;
right: -20px;
top: 50%;
transform: translateY(-50%);
}
<div class="active"></div>
try
.active {
height: 50px;
width: 200px;
background: #0092ff;
}
.active:after {
content: "";
border-style: solid;
border-width: 10px 0 10px 10px;
border-color: transparent transparent transparent #0092ff;
display: block;
margin-left: 200px;
transform: translateY(75%);
}
.active:hover:after {
content: "";
border-left: 0px solid #0092ff;
transition: border-left 0.2s ease-in;
}
<div class="active"></div>
Please Check following working example.
$(function() {
$('.btn').click(function() {
$(this).closest('ul').find('.active').removeClass('active');
$(this).addClass('active');
});
});
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
li a {
padding: 10px;
background: teal;
position: relative;
display: block;
width: 60px;
cursor: pointer;
}
.active::after {
content: " ";
border-right: 10px solid transparent;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-left: 10px solid teal;
height: 0;
width: 0;
position: absolute;
right: -20px;
top: 50%;
transform: translateY(-50%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li><a class="btn active">Home</a></li>
<li><a class="btn">News</a></li>
<li><a class="btn">Contact</a></li>
<li><a class="btn">About</a></li>
</ul>
you need to add position:relative to the selector ul li.
after that, you can use the following code below to add content through the pseudo element after of the active link.
change the size of the borders, as well as positions for top and right to suit your needs.
ul li.active:after {
content: "";
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-left: 20px solid #0092ff;
position:absolute;
top: 15px;
right:-15px;
}
I have a web page using the following HTML code:
<ol class="progress-bar">
<li class="progress-bar__steps not-current">
<span class="progress-bar__steps--numbers"></span>
<span class="progress-bar__steps--text">option 1</span>
</li>
<li class="progress-bar__steps not-current">
<span class="progress-bar__steps--numbers"></span>
<span class="progress-bar__steps--text">option 2</span>
</li>
<li class="progress-bar__steps current">
<span class="progress-bar__steps--numbers"></span>
<span class="progress-bar__steps--text">option 3</span>
</li>
<li class="progress-bar__steps not-current">
<span class="progress-bar__steps--numbers"></span>
<span class="progress-bar__steps--text">option 4</span>
</li>
</ol>
and using this CSS code:
.progress-bar {
list-style: none;
overflow: hidden;
font: 14px Helvetica;
font-weight: 600;
display: flex;
counter-reset: li;
padding: 0px;
}
.progress-bar__steps:hover{
border: 2px solid #1779ba;
background:yellow;
}
.progress-bar__steps {
background: #ddd;
color: #666;
width: 25%;
position: relative;
cursor: default;
list-style-image: none;
list-style-type: none;
padding: 20px 5px;
text-align: center;
border: 2px solid transparent;
}
#media screen and (min-width: 800px) {
.progress-bar__steps {
padding: 20px 0 20px 65px;
text-align: left;
}
}
#media screen and (min-width: 800px) {
.progress-bar__steps:first-child {
padding: 20px 0 20px 30px;
}
}
#media screen and (min-width: 800px) {
.progress-bar__steps:after {
border-bottom: 50px solid transparent;
border-top: 50px solid transparent;
content: " ";
display: block;
height: 0;
left: 100%;
margin-top: -50px;
position: absolute;
top: 50%;
width: 0;
border-left: 30px solid #ddd;
z-index: 2;
}
}
#media screen and (min-width: 800px) {
.progress-bar__steps:before {
border-bottom: 50px solid transparent;
border-top: 50px solid transparent;
content: " ";
display: block;
height: 0;
left: 100%;
margin-top: -50px;
position: absolute;
top: 50%;
width: 0;
border-left: 30px solid #fff;
z-index: 1;
margin-left: 5px;
}
}
.progress-bar .current {
background: #1779ba;
color: #fff;
}
.progress-bar .not-current {
cursor:pointer;
}
.progress-bar .current:after {
border-left: 30px solid #1779ba;
}
#media screen and (min-width: 800px) {
.progress-bar__steps--numbers:before {
content: counter(li) " ";
counter-increment: li;
margin-right: 15px;
background: white;
border: 1px solid transparent;
border-radius: 50%;
display: inline-block;
height: 20px;
line-height: 20px;
text-align: center;
width: 20px;
}
}
.current .progress-bar__steps--numbers:before {
background: white;
color: #1779ba;
}
The code is working properly in all major browsers, Safari, Chrome, Firefox, Internet Explorer except in one thing, the border hover effect is not working in full.
In order to better understand the issue I have setup a working demo. You can find the working demo at this location:
https://codepen.io/anon/pen/OZRYPV
I tweaked a bit your code to show what can be possibly be done there: https://codepen.io/anon/pen/GdjaGZ.
#media screen and (min-width: 800px) {
.progress-bar__steps:after {
border-bottom: 31px solid transparent;
border-top: 31px solid transparent;
content: " ";
display: block;
height: 0;
right: -19px;
margin-top: -31px;
position: absolute;
top: 50%;
width: 0;
border-left: 19px solid #ddd;
z-index: 2;
}
}
#media screen and (min-width: 800px) {
.progress-bar__steps:before {
border-bottom: 33px solid transparent;
border-top: 33px solid transparent;
content: " ";
display: block;
height: 0;
right: -22px;
margin-top: -33px;
position: absolute;
top: 50%;
width: 0;
border-left: 20px solid #fff;
z-index: 1;
margin-left: 0;
}
.progress-bar__steps:hover:after {
border-left-color: yellow;
}
.progress-bar__steps:hover:before {
border-left-color: #1779ba;
}
}
The problem with the shape is that you can't easily create border there. the easies solution in my opinion is to use SVG of the shape you need with stroke as it will make it look good and it'll be easier to position it. You can create the path using any vector editor. There should be even online ones.
Hi I'm trying to make a Pomodoro clock. I've made a play button by removing border-right and increasing border-left width to create a triangle.
My questions is - how do I apply border-radius to it?
https://codepen.io/jenlky/pen/ypQjPa?editors=1100
<div id="all-buttons" class="buttons">
<!-- play button -->
<div id="play" class="play-button"></div>
<!-- pause button -->
<div id="pause">
<div class="line-1"></div>
<div class="line-2"></div>
</div>
<!-- end of play and pause button-->
</div>
.play-button {
z-index: 2;
width: 48px;
height: 48px;
border-style: solid;
border-width: 24px 0px 24px 48px;
border-color: white white white #FF8F83;
}
HTML play button:
.circle_inner{
position: relative;
height: 100%;
}
.circle_inner:before{
content: "";
display: block;
width: 0;
height: 0;
border-style: solid;
border-width: 10px 0 10px 20px;
border-color: transparent transparent transparent #000;
position: absolute;
top: 50px;
left: 50%;
margin: -10px 0 0 -7px;
}
<div class="circle_inner">
</div>
Try this (Less)
<div class="control play">
<span class="left"></span><span class="right"></span>
</div>
.control {
#color: #ffb160;
#highlight: darken(#color, 10%);
#duration: 0.4s;
#sin: 0.866;
#size: 112px;
border-radius: 50%;
margin: 20px;
padding: #size*0.25;
width: #size;
height: #size;
font-size: 0;
white-space: nowrap;
text-align: center;
cursor: pointer;
&, .left, .right, &:before {
display: inline-block;
vertical-align: middle;
transition: border #duration, width #duration, height #duration, margin #duration;
transition-tiomig-function: cubic-bezier(1, 0, 0, 1);
}
&:before {
content: "";
height: #size;
}
&.pause {
.left, .right {
margin: 0;
border-left: #size*0.33 solid #color;
border-top: 0 solid transparent;
border-bottom: 0 solid transparent;
height: #size*#sin;
}
.left {
border-right: #size*0.2 solid transparent;
}
}
&.play {
#border: #size/4;
.left {
margin-left: #size/6;
border-left: #size*#sin/2 solid #color;
border-top: #border solid transparent;
border-bottom: #border solid transparent;
border-right: 0px solid transparent;
height: #size - 2*#border;
}
.right {
margin: 0;
border-left: #size*#sin/2 solid #color;
border-top: #border solid transparent;
border-bottom: #border solid transparent;
height: 0px;
}
}
&:hover {
border-color: #highlight;
.left, .right {
border-left-color: #highlight;
}
}
}
How can draw an up-down arrow with pure CSS?
This is what I get using HTML :
.up-down-arrow {
font-size: 50px;
color: #666;
padding: 0;
margin: 0;
display: inline-block;
}
<div class="up-down-arrow">↕</div>
But the line between the arrows is too short. Can I make it longer?
Ideally, this is what I am after:
Single element solution
You can achieve that with pseudo elements, CSS triangles and some positioning:
.arrow {
width: 2px;
height: 200px; /* <- adjust your height as you need it */
background: black;
margin: 10px;
position: relative;
}
.arrow::before,
.arrow::after {
content: '';
position: absolute;
left: -9px;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
}
.arrow::before {
top: 0;
border-bottom: 15px solid black;
}
.arrow::after {
bottom: 0;
border-top: 15px solid black;
}
<div class="arrow"></div>
Multiple elements solution
To achieve the actual arrow shape, you will need multiple elements. Here the pseudo elements are used to create white triangles, that cut out the black arrow heads:
.arrow {
width: 2px;
height: 200px; /* <- adjust your height as you need it */
background: black;
margin: 10px;
position: relative;
}
.up, .down, .arrow::before, .arrow::after {
position: absolute;
left: -9px;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
}
.up {
top: 0;
border-bottom: 15px solid black;
}
.down {
bottom: 0;
border-top: 15px solid black;
}
.arrow::before, .arrow::after {
content: '';
z-index: 2;
}
.arrow::before {
top: 11px;
border-bottom: 4px solid white;
}
.arrow::after {
bottom: 11px;
border-top: 4px solid white;
}
<div class="arrow">
<div class="up"></div>
<div class="line"></div>
<div class="down"></div>
</div>
Or another variant with a continuous line:
.line {
position: relative;
margin: -15px 0 -15px 9px;
width: 2px;
height: 180px;
background-color: black;
z-index: 5;
}
.up,
.down {
position: relative;
z-index: 3;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
}
.up {
border-bottom: 15px solid black;
}
.down {
border-top: 15px solid black;
}
.down::before, .up::after {
position: absolute;
left: -10px;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
content: '';
z-index: 4;
}
.down::before {
bottom: 11px;
border-top: 4px solid white;
}
.up::after {
top: 11px;
border-bottom: 4px solid white;
}
<div class="arrow">
<div class="up"></div>
<div class="line"></div>
<div class="down"></div>
</div>
To make the up-down arrows with the line in between the same as your example, I would suggest using SVG. You can use it inline as shown in the following example :
.wrap{
position:relative;
height:70vh;
border-left:1px solid #000;
margin:10vh 50px;
padding:5vh 20px;
}
.arrow {
position:absolute;
left:-5px;
width: 9px;
height: auto;
}
.up{top:-9px;}
.down{bottom:-9px;}
<div class="wrap">
<svg class="arrow up" viewbox="0 0 7 10">
<path d="M3.5 0 L7 10 Q3.5 7 0 10z"/>
</svg>
<svg class="arrow down" viewbox="0 0 7 10">
<path d="M3.5 10 L7 0 Q3.5 3 0 0z"/>
</svg>
Whatever content you need here
</div>
The inline SVG arrows are made with a path element and using one quadratic curve (made with Q3.5 7 0 10 in the up arrow).
The line between the arrows is made with a border left on a container div it expands with the height of this container.
Both arrows are positioned absolutely.
Here is one more solution using arrow char code \027A4 for ::before and ::after content.
Size of these chars has bound to root font size rem and their modification rotate, top and left based on the content font-size.
.arrow {
position: relative;
width: 3px;
height: 150px;
margin: 20px;
background: tomato;
}
.arrow::before,
.arrow::after {
content: '\027A4';
position: absolute;
font-size: 1.5rem;
color: tomato;
}
.arrow::before {
top: -.9em;
left: -.5em;
transform: rotate(-90deg);
}
.arrow::after {
bottom: -.9em;
left: -.32em;
transform: rotate(90deg);
}
<div class="arrow"></div>
To keep it simple, change the height style in mid class to increase the length of line!
.up {
width: 0px;
height: 0px;
border-bottom: 10px solid black;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: none;
}
.mid {
margin-left:7px;
width: 2px;
height: 180px;
background-color:black;
}
.down{
width: 0px;
height: 0px;
border-top: 10px solid black;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-bottom: none;
}
<div class='up'></div>
<div class='mid'></div>
<div class='down'></div>
Hope it helps!
So I am working on a progress wizard with steps, and I am having a hard time with trying to get a certain look with the progress bar running into the rounded progress steps. Here is my HTML/CSS on Copepen:
http://codepen.io/heysharybobbins/pen/yymXbK
Ultimately, the goal is to have the gray and/or green progress line merge directly into the solid-circle progress step (dark gray or green). Right now, the gray or green progress line stops at the border which is set on the progress step circle:
The end goal is for it to look like this PSD example:
http://codepen.io/heysharybobbins/pen/yymXbK
.container {
width: 960px;
margin: 50px auto;
font-family: Arial, sans-serif;
}
.progress-wrap {
height: 16px;
background: #e4e4e4;
border-radius: 3px;
border-top: 1px solid #ccc;
}
.progress-wizard {
padding: 0 0 10px 0;
position: relative;
bottom: 10px;
list-style-type: none;
}
.progress-wizard li {
display: inline-block;
width: 16%;
height: 36px;
font-size: 12px;
text-align: center;
text-indent: -19px;
line-height: 75px;
border-top: 4px solid #ccc;
box-shadow: inset 0 1px 0 #fff;
position: relative;
z-index: 1 !important;
}
.progress-wizard li:before {
position: relative;
float: left;
text-indent: 0;
left: -webkit-calc(50% - 9.5px);
left: -moz-calc(50% - 9.5px);
left: -ms-calc(50% - 9.5px);
left: -o-calc(50% - 9.5px);
left: calc(50% - 9.5px);
}
.progress-wizard li.done {
font-size: 12px;
}
.progress-wizard li.done:before {
content: "✔" !important;
color: white !important;
text-shadow: none !important;
font-size: 14px;
height: 30px;
width: 30px;
line-height: 30px;
top: -19px;
border: none;
border-radius: 19px;
box-shadow: 0 -1px 0 0 #ccc;
}
.progress-wizard li.todo {
font-size: 12px;
border-top-color: #ccc;
position: relative;
color: #999;
}
.progress-wizard li.todo:before {
content: "\2B24";
font-size: 17.1px;
top: -22px;
line-height: 18.05px;
}
.progress-wizard li.done {
color: #8c9c58;
border-top-color: #8c9c58;
}
.progress-wizard li.done:before {
color: white;
background-color: #8c9c58;
border: 5px solid #e4e4e4;
position: relative;
top: -22px;
}
.progress-wizard li.todo:before {
background: #ccc;
width: 30px;
height: 30px;
border: 5px solid #e4e4e4;
box-shadow: 0 -1px 0 0 #ccc;
border-radius: 60px;
line-height: 30px;
}
.progress-wizard li.stepone:before {
color: #999;
text-shadow: 1px 1px 0 white;
content: "1";
}
.progress-wizard li.steptwo:before {
color: #999;
text-shadow: 1px 1px 0 white;
content: "2";
}
.progress-wizard li.stepthree:before {
color: #999;
text-shadow: 1px 1px 0 white;
content: "3";
}
.progress-wizard li.stepfour:before {
color: #999;
text-shadow: 1px 1px 0 white;
content: "4";
}
.progress-wizard li.stepfive:before {
color: #999;
text-shadow: 1px 1px 0 white;
content: "5";
}
.progress-wizard li.stepsix:before {
color: #999;
text-shadow: 1px 1px 0 white;
content: "6";
}
.progress-wizard li.current {
color: #93b5d3;
}
.progress-wizard li.current:before {
background: #93b5d3;
color: #fff;
text-shadow: none;
}
<div class="container">
<div class="progress-wrap">
<ol class="progress-wizard">
<li class="progress-point done stepone">Information</li><li class="progress-point current todo steptwo">Related Items</li><li class="progress-point todo stepthree">Access</li><li class="progress-point todo stepfour">Uploads</li><li class="progress-point todo stepfive">Availability</li><li class="progress-point todo stepsix">Review</li>
</ol>
</div>
</div>
I was thinking in order to solve this it would have something to do with the z-index of the pseudo elements and parent of the pseudo elements, but I have tried a couple things and have had no luck. Any input would be greatly appreciated.
Thanks!
Could this be it?
.progress-wizard li.done:after {
content: " ";
background-color: #ccc;
position: absolute;
top: -4px;
padding-right: 47px;
left: 107px;
height: 4px;
}
http://codepen.io/anon/pen/wBVxje
EDIT:
Just saw a small problem. You have to add this :after element only to the last done element. Otherwise it overlays the progress bar. Is it fine? It can be removed using JS.
In Bootstrap
.progress-wizard li:before {
position: relative;
float: left;
text-indent: 0;
left: -webkit-calc(50% - 9.5px);
left: -moz-calc(50% - 9.5px);
left: -ms-calc(50% - 9.5px);
left: -o-calc(50% - 9.5px);
left: calc(50% - 9.5px);
box-sizing: content-box;
}