I am trying to draw a line with a small arrow pointing down as in the image attached.
I have not been able to get the downward arrow. Is there a way I can do it using html and css?
HTML
<hr class="line">
CSS
.line{
width:70%;
color:red;
}
http://jsfiddle.net/4eL39sm1/
Thanks.
You can use pseudo-elements :after and :before:
.line {
width:70%;
}
.line:after {
content:'';
position: absolute;
border-style: solid;
border-width: 7px 7px 0;
border-color: #FFFFFF transparent;
display: block;
width: 0;
z-index: 1;
top: 8px;
left: 45%;
}
.line:before {
content:'';
position: absolute;
border-style: solid;
border-width: 7px 7px 0;
border-color: #7F7F7F transparent;
display: block;
width: 0;
z-index: 1;
top: 9px;
left: 45%;
}
<hr class="line">
You can play with border-width to adjust the size to your needs.
Related
I am building a testimonial component in react and I have to make a shape direction towards pic, I have done the shape exactly how I want but the testimonial div has border color when I apply the div gets a border but the shape is left outside I have tried several ways but couldn't find a solution, I have attached the picture of what I want and how it is right now.
How I want it
What I have achieved till now
Below is my CSS
#page {
background-color: lightgray;
padding: 40px;
}
.container {
position: relative;
background-color: #FFFFFF;
max-width: 600px;
height: auto;
border: 1px solid #E7E7E7;
padding: 30px;
box-sizing: border-box;
}
.container:after {
position: absolute;
width: 0;
height: 0;
border-top: 50px solid white;
border-right: 40px solid transparent;
top:101%;
left: 40%;
content: '';
transform: rotate(14deg);
margin-top: -10px;
}
<div id="page">
<div class="container">This is a test</div>
</div>
You may use a filter , choice: drop-shadow.
support ? , don't be afraid : https://caniuse.com/?search=drop-shadow All but IE 6-11 and Opera mini
here is an exemple to run:
#page {
background-color: lightgray;
padding: 40px;
}
.container {
position: relative;
background-color: #FFFFFF;
max-width: 600px;
height: auto;
filter:
/* draw borders without blur*/
drop-shadow(0 1px )
drop-shadow(1px 0px )
drop-shadow(0 -1px )
drop-shadow(-1px 0px )
/* add eventually a shadow */
drop-shadow(0 0 3px )
/*and another for demo purpose */
drop-shadow(30px 30px 3px gray );
padding: 30px;
box-sizing: border-box;
}
.container:after {
position: absolute;
width: 0;
height: 0;
border-top: 50px solid white;
border-right: 40px solid transparent;
top:101%;
left: 40%;
content: '';
transform: rotate(14deg);
margin-top: -10px;
}
<div id="page">
<div class="container">This is a test</div>
</div>
You can use a :before that's 1px bigger than your :after which uses the border colour instead and then it will be mostly covered by the :after, giving you your "fake" border. Just makes sure your z-indexing is correct so it doesn't show inside your bubble.
EDIT: Adding in example css.
I modified some colours and spacing for illustrative purposes:
#page {
background: #ffc;
padding: 40px 40px 60px;
position: relative;
z-index: 0;
}
.container {
position: relative;
background: #fff;
max-width: 600px;
height: auto;
border: 1px solid #000;
padding: 30px;
box-sizing: border-box;
}
.container:after,
.container:before {
position: absolute;
width: 0;
height: 0;
top: 101%;
left: 40%;
content: "";
transform: rotate(14deg);
margin-top: -10px;
}
.container:after {
border-top: 50px solid #fff;
border-right: 40px solid transparent;
}
.container:before {
border-top: 52px solid #000;
border-right: 42px solid transparent;
margin-left: -1px;
z-index: -1;
}
<div id="page">
<div class="container">This is a test</div>
</div>
Adding both a :before and :after is a good idea to get the effect you want. Using a CSS box-shadow or outline won't work because it actually renders a complete square around your arrow/triangle shape. A z-index is added to the before to push it to the background. In that way it's not overlapping the other objects.
Here's an example of what you might want. You can adjust the border sizes to finetune it.
.container {
position: relative;
background-color: #FFFFFF;
max-width: 600px;
height: auto;
border: 1px solid #E7E7E7;
padding: 30px;
box-sizing: border-box;
}
.container:before {
position: absolute;
width: 0;
height: 0;
border-top: 53px solid #e7e7e7;
border-right: 43px solid transparent;
top: 100%;
left: 40%;
content: '';
transform: rotate(14deg);
margin-top: -10px;
z-index: -1;
}
.container:after {
position: absolute;
width: 0;
height: 0;
border-top: 50px solid white;
border-right: 40px solid transparent;
top:101%;
left: 40%;
content: '';
transform: rotate(14deg);
margin-top: -10px;
}
<div class="container"></div>
I am trying to build a parallelogram background that only appears on hover in a menu item. For the shape, I am using :before and :after pseudo-elements, however I cannot apply the same transition effect on them. Does anyone knows what could I do to solve this problem?
Here is the code until the moment:
div {
float:left;
background-color:#fff;
margin: 20px;
transition:.5s;
}
.testClass {
margin-top: 0px;
margin-left: 0px;
padding: 5px 10px;
display: block;
background-repeat: no-repeat;
background: #fff;
position: relative;
transition:.5s;
}
.testClass:hover {
background: gold;
transition:.5s;
}
.testClass:hover:before {
content: '';
position: absolute;
top:0;
left:-15px;
width: 0px;
height: 0px;
border-style: solid;
border-width: 0 0 29px 15px;
border-color: transparent transparent gold transparent;
}
.testClass:hover:after {
content: '';
position: absolute;
top:0;
right:-15px;
width: 0px;
height: 0px;
border-style: solid;
border-width: 30px 15px 0 0;
border-color: gold transparent transparent transparent;
}
<div >
<div class="testClass">HOME</div>
<div class="testClass">ABOUT US</div>
<div class="testClass">CONTACT</div>
<div class="testClass">LOGIN</div>
<div class="testClass">SERVICES</div>
</div>
What about an easier way with only one element to create the shape:
div {
float: left;
margin: 20px;
transition: .5s;
}
.testClass {
margin-top: 0px;
margin-left: 0px;
padding: 5px 10px;
display: block;
background: #fff;
position: relative;
transition: .5s;
z-index: 0;
}
.testClass:before {
content: '';
position: absolute;
z-index: -1;
top: 0;
left: -10px;
right: -10px;
bottom: 0;
opacity: 0;
background: gold;
transform: skew(-20deg);
transition: .5s;
}
.testClass:hover::before {
opacity: 1;
}
<div>
<div class="testClass">HOME</div>
<div class="testClass">ABOUT US</div>
<div class="testClass">CONTACT</div>
<div class="testClass">LOGIN</div>
<div class="testClass">SERVICES</div>
</div>
I am trying to create a div with arrow on left and right. No background, only border. Something like this:
I am able to create similar div with filled background color using ::before and ::after tags. However, only borders is something i am not able to achieve. Can it be done with css only?
https://jsfiddle.net/1g16x8p7/1/
html:
<div class="wizard">
<a class="item">
</a>
</div>
css:
.item {
display: inline-block;
padding: 15px;
padding-left: 25px;
/*default styles*/
background-color: green;
position: relative;
}
.item:before,
.item:after {
content: "";
height: 0;
width: 0;
border-width: 15px 0 15px 10px;
border-style: solid;
position: absolute;
left: 100%;
top: 0;
}
.item:before {
border-color: transparent transparent transparent white;
left: 0;
}
.item:after {
border-color: transparent transparent transparent green;
}
You can use ::before and ::after with borders on two adjacent sides (e.g. top and right) and then transform: rotate and position: absolute them to create the left and right parts, e.g.
<div class="arrow"></div>
.arrow {
height: 75px;
width: 200px;
border-top: 4px solid black;
border-bottom: 4px solid black;
position: relative;
}
.arrow::before, .arrow::after {
content: "";
border-top: 4px solid black;
border-right: 4px solid black;
height: 55px;
width: 55px;
position: absolute;
transform: rotate(45deg);
}
.arrow::before {
top: 8px;
left: -30px;
}
.arrow::after {
top: 8px;
right: -30px;
}
Here's an example.
I am trying to create a ribbon at the beginning of a rectangle. However, I cannot figure out how to make it appear BEHIND the rectangle.
Please see this codepen: http://codepen.io/gosusheep/pen/aOqOBy
The part for creating the ribbon and putting it behind the rectangle is here:
.rectangle::before{
content: "";
width: 0;
height: 0;
display: block;
position: absolute;
z-index: -1;
border-left: 25px solid transparent;
border-right: 25px solid $blue;
border-top: 25px solid $blue;
border-bottom: 25px solid $blue;
left: -30px;
top: 10%;
}
Even with position: absolute, and z-index: -1, it appears ON TOP of the div.
Can anyone help with this?
What is happening here is that apparently, the property transform: translateX(-50%); it's "overriding" in some way the z-index. My solution is just center rectangle otherwise, for example:
.rectangle{
margin: 0 auto;
}
DEMO
The reason for your problem is not because children cannot be positioned behind their parent but because you are using a transform on the parent. Using transforms affect the stacking context like mentioned in this answer by BoltClock.
One solution would be to avoid the transform totally and use left: calc(50% - 100px) instead to position the ribbon at the center (like in the below snippet). (50% - 100px) is used as the value because 100px is half of the box width (50% is the center point of the parent).
.rectangle {
width: 200px;
height: 50px;
background-color: #8080ff;
position: relative;
left: calc(50% - 100px); /* newly added */
border: 1px #6666ff solid;
}
ul {
list-style: none;
}
li {
display: inline;
}
li + li::before {
content: " | ";
}
.container {
width: 100%;
position: relative;
}
.rectangle {
width: 200px;
height: 50px;
background-color: #8080ff;
position: relative;
left: calc(50% - 100px); /* newly added */
border: 1px #6666ff solid;
}
.rectangle::before {
content: "";
width: 0;
height: 0;
display: block;
position: absolute;
z-index: -1;
border-left: 25px solid transparent;
border-right: 25px solid #8080ff;
border-top: 25px solid #8080ff;
border-bottom: 25px solid #8080ff;
left: -30px;
top: 10%;
}
<p>put a pipe between nav elements</p>
<nav>
<ul>
<li>banana</li>
<li>woof</li>
<li>quack</li>
</ul>
</nav>
<p>Ribbon on the end of a rectangle</p>
<div class='container'>
<div class='rectangle'></div>
</div>
If in case you can't use the above solution, then you could follow the approach described below.
Assuming you don't have any other use for the ::after pseudo-element, you could use that to create the rectangle and give it a z-index higher than the ::before pseudo-element to make it appear behind the rectangle.
/* Modified */
.rectangle {
width: 200px;
height: 50px;
position: relative;
left: 50%;
transform: translateX(-50%);
}
/* Added */
.rectangle::after {
content: "";
width: 100%;
height: 100%;
top: 0px;
left: 0px;
display: block;
position: absolute;
background-color: #8080ff;
border: 1px #6666ff solid;
z-index: -1;
}
.rectangle{
padding: 4px;
box-sizing: border-box;
}
Below is a sample snippet:
ul {
list-style: none;
}
li {
display: inline;
}
li + li::before {
content: " | ";
}
.container {
width: 100%;
position: relative;
}
.rectangle::before {
content: "";
width: 0;
height: 0;
display: block;
position: absolute;
z-index: -2;
border-left: 25px solid transparent;
border-right: 25px solid #8080ff;
border-top: 25px solid #8080ff;
border-bottom: 25px solid #8080ff;
left: -30px;
top: 10%;
}
/* Modified */
.rectangle {
width: 200px;
height: 50px;
position: relative;
left: 50%;
transform: translateX(-50%);
}
/* Added */
.rectangle::after {
content: "";
width: 100%;
height: 100%;
top: 0px;
left: 0px;
display: block;
position: absolute;
background-color: #8080ff;
border: 1px #6666ff solid;
z-index: -1;
}
.rectangle{
padding: 4px;
box-sizing: border-box;
}
<p>put a pipe between nav elements</p>
<nav>
<ul>
<li>banana</li>
<li>woof</li>
<li>quack</li>
</ul>
</nav>
<p>Ribbon on the end of a rectangle</p>
<div class='container'>
<div class='rectangle'>
Some content
</div>
</div>
Solution here, look closely at z-indexes and positions
.container{
position: relative;
width: 100%;
z-index: 1;
}
.rectangle{
width: 200px;
height: 50px;
background-color: $blue;
position: absolute;
left: 50%;
border: 1px darken($blue,5%) solid;
}
.rectangle::after{
content: "";
width: 0;
height: 0;
border-left: 25px solid transparent;
border-right: 25px solid $blue;
border-top: 25px solid $blue;
border-bottom: 25px solid $blue;
left: -30px;
top: 10px;
position: absolute;
z-index: -1;
}
And your codepen edited http://codepen.io/anon/pen/mJXeed working now
I generated a bubble chat thingy from http://www.ilikepixels.co.uk/drop/bubbler/
In my page I put a number inside of it
.bubble {
position: relative;
width: 20px;
height: 15px;
padding: 0;
background: #FFF;
border: 1px solid #000;
border-radius: 5px;
}
.bubble:after {
content: "";
position: absolute;
top: 4px;
left: -4px;
border-style: solid;
border-width: 3px 4px 3px 0;
border-color: transparent #FFF;
display: block;
width: 0;
z-index: 1;
}
.bubble:before {
content: "";
position: absolute;
top: 4px;
left: -5px;
border-style: solid;
border-width: 3px 4px 3px 0;
border-color: transparent #000;
display: block;
width: 0;
z-index: 0;
}
I want the background-color of the bubble to change according to the number inside of it via rgb
so if my div is
<div class="bubble" style="background-color: rgb(100,255,255);"> 100 </div>
I want the color to be rgb(100,255,255)
The thing is this doesn't affect the triangle.
How do I write the inline css so it will include the :before and :after?
You can, using CSS variables (more precisely called CSS custom properties).
Set your variable in your style attribute: style="--my-color-var: orange;"
Use the variable in your stylesheet: background-color: var(--my-color-var);
Browser compatibility
Minimal example:
div {
width: 100px;
height: 100px;
position: relative;
border: 1px solid black;
}
div:after {
background-color: var(--my-color-var);
content: '';
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
<div style="--my-color-var: orange;"></div>
Your example:
.bubble {
position: relative;
width: 30px;
height: 15px;
padding: 0;
background: #FFF;
border: 1px solid #000;
border-radius: 5px;
text-align: center;
background-color: var(--bubble-color);
}
.bubble:after {
content: "";
position: absolute;
top: 4px;
left: -4px;
border-style: solid;
border-width: 3px 4px 3px 0;
border-color: transparent var(--bubble-color);
display: block;
width: 0;
z-index: 1;
}
.bubble:before {
content: "";
position: absolute;
top: 4px;
left: -5px;
border-style: solid;
border-width: 3px 4px 3px 0;
border-color: transparent #000;
display: block;
width: 0;
z-index: 0;
}
<div class='bubble' style="--bubble-color: rgb(100,255,255);"> 100 </div>
You can't. With inline styles you are targeting the element directly. You can't use other selectors there.
What you can do however is define different classes in your stylesheet that define different colours and then add the class to the element.
The key is to use background-color: inherit; on the pseudo element. See: http://jsfiddle.net/EdUmc/
If you really need it inline, for example because you are loading some user-defined colors dynamically, you can always add a <style> element right before your content.
<style>#project-slide-1:before { color: #ff0000; }</style>
<div id="project-slide-1" class="project-slide"> ... </div>
Example use case with PHP and some (wordpress inspired) dummy functions:
<style>#project-slide-<?php the_ID() ?>:before { color: <?php the_field('color') ?>; }</style>
<div id="project-slide-<?php the_ID() ?>" class="project-slide"> ... </div>
Since HTML 5.2 it is valid to place style elements inside the body, although it is still recommend to place style elements in the head.
Reference: https://www.w3.org/TR/html52/document-metadata.html#the-style-element
I resolved a similar problem by border-color: inherit
, see:
<li style="border-color: <?php echo $hex ?>;">...</li>
li {
border-width: 0;
}
li:before {
content: '';
display: inline-block;
float: none;
margin-right: 10px;
border-width: 4px;
border-style: solid;
border-color: inherit;
}