I have tried adding a shadow to my triangle but it just wont work, this is so annoying!
Heres my code:
function section_about() {
$(".about").css("display", "inline-block");
$(".about").animate({opacity:"1"}, {duration: 1000, queue: false});
window.location.hash = "/About Us/";
}
function triangle_sizer() {
$(".triangle-up").css("border-left-width", jQuery(window).width()/2);
$(".triangle-up").css("border-right-width", jQuery(window).width()/2);
$(".triangle-up").css("top", jQuery(window).height()-125);
$(".triangle-down").css("border-left-width", jQuery(window).width()/2);
$(".triangle-down").css("border-right-width", jQuery(window).width()/2);
$(".triangle-down").css("top", jQuery(window).height()-125);
}
triangle_sizer();
jQuery(window).resize(function() {
triangle_sizer();
});
##style.css##
.triangle-down {
width: 0;
height: 0;
border-style: solid;
border-width: 100px 200px 0 100px;
border-color: rgba(39, 39, 39, 1) transparent transparent transparent;
box-shadow: 0 16px 10px -17px rgba(0, 0, 0, 0.5);
}
.triangle-down:after {
content: "";
position: absolute;
width: 0;
height: 0;
background: rgba(39, 39, 39, 1);
-webkit-transform: rotate(45deg);
box-shadow: -1px -1px 10px -2px rgba(0, 0, 0, 0.5);
}
.par {
position: absolute;
top: 200%;
width: 100%;
height: 0%;
}
/* Arrows */
.arrows {
width: 220px;
height: 144px;
position: absolute;
left: 50%;
top: 70%;
margin-left: -76.5px;
}
.arrows path {
stroke: white;
fill: transparent;
stroke-width: 1px;
}
/* Arrows */
.arrows-down {
width: 220px;
height: 144px;
position: absolute;
left: 50%;
top: 70%;
margin-left: -78.5px;
}
.arrows-down path {
stroke: white;
fill: transparent;
stroke-width: 1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="par">
<div class="triangle-down">
<svg class="arrows-down" viewbox="0 0 102 102">
<path class="a1" d="M0 20 L30 52 L60 20"></path>
</svg>
</div>
</div>
I have been searching for a solution for a long time and cant find one. This is what happens when that code is ran:
https://gyazo.com/c890a79c547f5624c97abacc66104fc1
https://jsfiddle.net/Lec8862y/2/
HTML
<span class="triangle">▼</span>
CSS
span {
display: inline-block;
transform: scaleX(8.5);
color: lightgreen;
text-shadow:
0 2px 2px rgba(255,255,255,0.7),
0 10px 4px rgba(0,0,0,0.5);
font-size: 92px;
}
span:hover {
transition: all 0.2s ease;
transform: scaleX(9.5) translateY(4px);
text-shadow:
0 1px 1px rgba(0,0,0,0.5);
}
body {
padding: 20px;
margin-left: 260px;
margin-top: -40px
}
Working Fiddle: https://jsfiddle.net/rittamdebnath/drefg8r4/
You can try using box-shadow to build a triangle instead of border. Then on :before or :after elements you can set an overlapping box-shadow, example by Chris Coyier:
http://codepen.io/chriscoyier/pen/bNZWzK
You can cuplicate your element, align it directly behind the default triangle and use the css filter propertie in conjunction with absolute position and the back element size.
.triangle-down {
position: relative;
width: 220px;
height: 220px;
box-sizing: border-box;
}
.arrows-down {
display: block;
height: auto;
max-width: 200px;
box-sizing: border-box;
}
.arrows-down-back {
position: absolute;
left: 0;
top: 0;
max-width: 200px;
filter: blur(20px) opacity(.3);
-webkit-filter: blur(20px) opacity(.3);
}
<div class="par">
<div class="triangle-down">
<svg class="arrows-down img-responsive" viewbox="0 0 102 102">
<path class="a1" d="M0 20 L30 52 L60 20"></path>
</svg>
<svg class="arrows-down img-responsive arrows-down-back" viewbox="0 0 102 102">
<path class="a1" d="M0 20 L30 52 L60 20"></path>
</svg>
</div>
</div>
You could relay only on a gradient to draw and blur(shadow) the triangle.
If you use vertical margin/padding in percentage, it takes the width for reference, so arrow is resized from width, not height of content.
div {
position:relative;
color:white;
background:#333;
text-align:center;
margin:1em;
margin-bottom:5.5%;
box-shadow: 0 0 5px #333;
}
div:after {
content:'';
display:block;
position:absolute;
top:100%;
left:0;
right:0;
padding-top:5%;
background:linear-gradient(to bottom left, #333 49%, transparent 51%) no-repeat 0 0, linear-gradient(to bottom right, #333 49%, transparent 51%) no-repeat top right;
background-size:50% 99%
}
html {/* demo purpose to show arrow box is translucide */
background:linear-gradient(45deg, yellow,gray,purple,white,lime, yellow,gray,purple,white,lime);
min-height:100%;
}
<div>responsive box arrow, resize me or add content </div>
<div>i can be replicated <hr/> maybe you should use a <code>class</code> there </div>
Related
I want to design the above image using pure CSS.
Following is the HTML and CSS I have come up with so far:
<div>
<input
className="my_file"
type="file"
onChange={(event) => {
setImageSelected(event.target.files[0]);
}}
/>
<svg
width="20"
height="18"
viewBox="0 0 20 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="upload_image_icon"
>
<path
d="M7 0L5.17 2H2C0.9 2 0 2.9 0 4V16C0 17.1 0.9 18 2 18H18C19.1 18 20 17.1 20 16V4C20 2.9 19.1 2 18 2H14.83L13 0H7ZM10 15C7.24 15 5 12.76 5 10C5 7.24 7.24 5 10 5C12.76 5 15 7.24 15 10C15 12.76 12.76 15 10 15Z"
fill="white"
/>
</svg>
<Avatar
src={picture}
alt="Avatar"
id="hello"
className="avatar--profile_image"
/>
</div>
and here is my scss:
.profile--card_container {
width: 348px;
height: 448px;
// border: 1px solid rgb(211, 211, 211);
// border-radius: 5px;
.avatar--profile_image {
justify-content: center !important;
margin-bottom: 10px;
margin-top: 10px;
margin-left: 6.50rem;
height: 100px !important;
width: 100px !important;
box-shadow: rgba(0, 0, 0, 0.01) 0px 5px 16px 0px,
rgba(0, 0, 0, 0.10) 0px 0px 0px 0px;
position: relative;
overflow: hidden;
background-size: cover;
background-position: center;
background-blend-mode: multiply;
color: transparent;
transition: all .3s ease;
cursor: pointer;
border: 2px solid rgba(0, 0, 0, 0.54);
&:after {
content:'\A';
position:absolute;
width:100%; height:100%;
top:0; left:0;
background:rgba(0,0,0,0.6);
opacity:0;
transition: all 0.5s;
-webkit-transition: all 0.5s;
}
&:hover:after {
opacity:1;
}
}
input[type=file]::-webkit-file-upload-button {
cursor: pointer;
}
.my_file {
position: absolute;
outline: none;
color: transparent;
box-sizing: border-box;
transition: 0.5s;
margin: 45px 0 0 100px;
z-index: 1;
opacity: 0;
cursor: pointer;
}
.upload_image_icon {
margin: 44px 0 0 144px;
cursor: pointer;
position: absolute;
outline: none;
box-sizing: border-box;
z-index: 1;
}
}
here is how my result look like for now:
I am trying to achieve like when I hover profile picture the image will overlay black color and appear camera icon. How can I do that ?
Wrap the image within a div. and then use a pesudo-element with a z-index that onyl dispalys when you hover that div like in the snippet below:
.avatar {
width: 100px;
height: 100px;
position: relative;
}
.avatar img {
width: 100%;
object-fit: cover;
border-radius: 50%;
}
.avatar > div {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border-radius: 50%;
background-color: rgba(0, 0, 0, 0.6);
z-index: 2;
display: none;
}
.avatar:hover > div {
display: flex;
justify-content: center;
align-items: center;
}
<div class="avatar">
<img src="https://via.placeholder.com/500x500.jpg">
<div>Icon</div>
</div>
I'm looking to create the following setup for a navigation structure.
I'm able to get the white down triangle working without an issue but how do I place yet another triangle (green lines) over the top of the first one without a full border/background or using an image? I can only get a solid green arrow over the white one and that's not what I want to do.
This is what I currently have.
.custom-nav li a:after {
content: "";
z-index: 99;
width: 0;
height: 0;
border-style: solid;
border-width: 40px 150px 0 150px;
border-color: #ffffff transparent transparent transparent;
position: absolute;
top: 173%; left: -75px;
}
<div>
<ul class="custom-nav">
<li>Environment</li>
<li>Health</li>
</ul>
</div>
I think the best option to get something like that is to use an SVG:
body {
margin: 0;
background: #DEE;
}
.nav {
display: flex;
}
.button {
position: relative;
background: transparent;
border: 0;
width: 50%;
height: 100px;
padding: 0 0 50px;
background: content-box white;
font-family: monospace;
font-weight: bold;
outline: none;
cursor: pointer;
}
.button__text {
position: relative;
z-index: 1;
}
.button__triangle {
position: absolute;
top: 25px;
bottom: 0;
left: 50%;
width: 100%;
transition: transform ease-in 150ms;
transform: translate(-50%, -50%);
}
.button:hover > .button__triangle {
transform: translate(-50%, 0);
}
.button__triangle--big {
fill: white;
}
.button__triangle--small {
fill: white;
stroke: red;
stroke-width: 2px;
stroke-linecap: round;
opacity: 0;
transition: opacity ease-in 150ms;
}
.button:hover .button__triangle--small {
opacity: 1;
}
<nav class="nav">
<button class="button">
<span class="button__text">OPTION 1</span>
<svg viewBox="0 0 200 50" class="button__triangle">
<polygon points="0,0 100,50 200,0" class="button__triangle--big" />
<polyline points="50,5 100,30 150,5" class="button__triangle--small" />
</svg>
</button>
<button class="button">
<span class="button__text">OPTION 2</span>
<svg viewBox="0 0 200 50" class="button__triangle">
<polygon points="0,0 100,50 200,0" class="button__triangle--big" />
<polyline points="50,5 100,30 150,5" class="button__triangle--small" />
</svg>
</button>
</nav>
Multiple background can do this:
.box {
--w:160px; /* width of the arrow */
--h:40px; /* height of the arrow*/
--b:2px; /* thickness of the green arrow */
--o:20%; /* offset of the green arrow */
/* gadient coloration, white then the green border then white again then transparent */
--g:#fff var(--o),
green var(--o) calc(var(--o) + var(--b)),
#fff calc(var(--o) + var(--b) + 1px) 49.8%,
transparent 50%;
height:50px;
margin:5px;
border-bottom:var(--h) solid transparent; /* the arrow will take the border space */
background:
linear-gradient(to bottom right,var(--g)) calc(50% + calc(var(--w)/4)) 100% border-box,
linear-gradient(to bottom left ,var(--g)) calc(50% - calc(var(--w)/4)) 100% border-box,
#fff padding-box;
background-size:calc(var(--w)/2) var(--h);
background-repeat:no-repeat;
}
body {
background:#000;
}
<div class="box"></div>
<div class="box" style="--w:200px;--h:60px;--o:30%;--b:5px"></div>
<div class="box" style="--w:180px;--h:30px;--o:10%;--b:3px"></div>
I have a project where I need to insert speech bubbles / message boxes. The general shape I am trying to achieve is this one :
.bubble {
height: 100px;
width: 200px;
border: 3px solid gray;
background: lightgray;
position: relative;
cursor:pointer;
}
.triangle {
width: 0;
border-top: 20px solid black;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
cursor:pointer;
}
<div class="bubble">Speech bubble
</div>
<div class="triangle">
</div>
This currently does not pass a hit-test as the transparent border is also clickable.
Objectives
The hit box (clickable / hoverable areas) needs to stick to the shape's boundaries (the transparent borders here are also hoverable, invalidating this).
I need to display the shape over various content (images, gradents, text...),
Issues
The main issues I am having when manipulating this shape are:
Have the ability to move the triangle around the speech bubble according to the position of the element it refers to (top/left/right/bottom sides)
adding a border or box shadow around it when emphasis is needed
Is there anyway of addressing these issues?
In order to achieve this, you should consider altering your markup in order to make your html more efficient. This can be achieved using a pseudo element. I'll address each point individually, and put it all together at the end of my answer.
First of all,
Use pseudo elements to avoid extra elements
You could use a pseudo element to remove the extra .triangle div. This not only reduces your div numbers, but also helps with positioning as you can use the top: left: right: and bottom: css properties in order to position according to your main element. This can be seen below:
.oneAndOnlyDiv {
height: 100px;
width: 200px;
border: 3px solid gray;
background: lightgray;
position: relative;
}
.oneAndOnlyDiv:before {
content: "";
position: absolute;
top: 100%;
left: 20px;
width: 0;
border-top: 20px solid black;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
}
<div class="oneAndOnlyDiv">Main div</div>
Hit testing
In order to create your "hit test", you may wish to use a rotated element instead of a border hack.
Something like:
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
}
div:before {
content: "";
position: absolute;
top: 100%;
left: 20px;
height: 20px;
width: 20px;
background: black;
transform: rotate(45deg);
transform-origin:top right;
}
<div>Only element</div>
or use a skewed pseudo element:
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
}
div:before {
content: "";
position: absolute;
top: 90%;
left: 20px;
height: 30%;
width: 20px;
background: black;
transform: skewY(-45deg);
transform-origin:bottom left;
z-index:-1;
}
<div>Only element</div>
which will show the pointer only when the square or main element is hovered.
But hang on, that messes up the positioning? how can you deal with that?
There are a few solutions to that. One of which is to use the calc CSS property.
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
}
div:before {
content: "";
position: absolute;
top: -webkit-calc(100% - 10px); /*may require prefix for old browser support*/
top: calc(100% - 10px); /*i.e. half the height*/
left: 20px;
height: 20px;
width: 20px;
background: gray;
transform: rotate(45deg);
}
<div>Only element</div>
Adding a border
You can add a border quite easily now, simply by adding a border declaration to the main element, and setting the border-bottom and border-right of the pseudo element to inherit
Border
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
border:3px double black;
}
div:before {
content: "";
position: absolute;
top: -webkit-calc(100% - 10px); /*may require prefix for old browser support*/
top: calc(100% - 10px); /*i.e. half the height*/
left: 20px;
height: 20px;
width: 20px;
background: gray;
transform: rotate(45deg);
border-bottom:inherit;
border-right:inherit;
box-shadow:inherit;
}
<div>Only element</div>
Box Shadow:
In order to have a box shadow, I've used the :after pseudo element in order to hide the box shadow over the other pseudo, making the element seem as one single element.
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
box-shadow: 5px 5px 10px 2px black;
}
div:before,div:after {
content: "";
position: absolute;
top: -webkit-calc(100% - 10px); /*may require prefix for old browser support*/
top: calc(100% - 10px); /*i.e. half the height*/
left: 20px;
height: 20px;
width: 20px;
background: gray;
transform: rotate(45deg);
z-index:-1;
box-shadow:inherit;
}
div:after{
box-shadow:none;
z-index:8;
}
<div>Only element</div>
Putting it all together
You can also add a border radius to your message box or speech bubble by again, using the border-radius property:
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
border:3px double black;
border-radius:10px;
}
div:before {
content: "";
position: absolute;
top: -webkit-calc(100% - 10px); /*may require prefix for old browser support*/
top: calc(100% - 10px); /*i.e. half the height*/
left: 20px;
height: 20px;
width: 20px;
background: gray;
transform: rotate(45deg);
border-bottom:inherit;
border-right:inherit;
box-shadow:inherit;
}
<div>Only element</div>
This even allows you to create not only a triangle, but how about a circle instead?
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor:pointer;
border:3px double black;
border-radius:10px;
}
div:before {
content: "";
position: absolute;
top: -webkit-calc(100% - 13px); /*may require prefix for old browser support*/
top: calc(100% - 13px); /*i.e. half the height + border*/
left: 20px;
height: 20px;
width: 20px;
background: gray;
transform: rotate(45deg);
border:3px double transparent;
border-bottom:inherit;
border-right:inherit;
box-shadow:inherit;
border-radius:50%;
}
<div>Only element</div>
If you are having issues with content overflowing and being 'hidden' behind this pseudo element, and you aren't fussed about having a border, you could use a negative z-index which will solve this issue.
Don't like using 'magic numbers'?
If you don't like the idea of using a calc value, in which the positioning in my answer is currently using (whilst working), you may wish to use transform:translate(50%)
This would be a much better approach, since:
You do not need to know the size of the border, nor half the width
You will be making your message box/ bubble a lot more dynamic in its positioning, and would support further sizings.
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor: pointer;
border: 3px double black;
border-radius: 10px;
}
div:before {
content: "";
position: absolute;
top: 100%;
left: 30px;
height: 20px;
width: 20px;
background: gray;
box-sizing:border-box;
transform: rotate(45deg) translate(-50%);
border-bottom: inherit;
border-right: inherit;
box-shadow: inherit;
}
<div>Only element</div>
Want to move it? You can!
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor: pointer;
border: 3px double black;
border-radius: 10px;
}
div:before {
content: "";
position: absolute;
top: 100%;
left: 10%;
height: 20px;
width: 20px;
background: gray;
box-sizing: border-box;
transform: rotate(45deg) translate(-50%);
border-bottom: inherit;
border-right: inherit;
box-shadow: inherit;
transition: all 0.8s;
}
div:hover:before {
left: 90%;
}
<div>Only element</div>
Want it one the right?
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor: pointer;
border: 3px double black;
border-radius: 10px;
}
div:before {
content: "";
position: absolute;
top: 15%;
left: 100%;
height: 20px;
width: 20px;
background: gray;
box-sizing:border-box;
transform: rotate(45deg) translate(-50%);
border-top: inherit;
border-right: inherit;
box-shadow: inherit;
transition:all 0.8s;
}
div:hover:before{
top:80%;
}
<div>Only Element</div>
Want it to be a different shape of triangle?
div {
height: 100px;
width: 200px;
background: gray;
position: relative;
cursor: pointer;
border-radius: 10px;
}
div:before {
content: "";
position: absolute;
top: 70%;
left: 100%;
height: 20px;
width: 20px;
background: gray;
box-sizing:border-box;
transform: translate(-50%) skewX(45deg);
box-shadow: inherit;
transition:all 0.8s;
z-index:-1;
}
div:hover:before{
transform: translate(-50%);
border-radius:50%;
top:20%;
}
<div>Only Element</div>
We can rely on clip-path and drop-shadow filter to easily achieve this:
.box {
margin: 50px;
width: 200px;
height: 100px;
border-radius: 15px;
background: red;
position: relative;
filter: /* the more shadow you add the thicker the border will be */
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green);
}
.box::before {
content: "";
position: absolute;
top: 100%;
left: 20%;
height: 30px;
width: 50px;
background: inherit;
clip-path: polygon(0 0, 100% 0, 50% 100%);
}
.box:hover {
background:blue;
}
body {
background:linear-gradient(to right, pink,grey);
}
<div class="box"></div>
We can extend this basic example to consider any kind of position and triangle shape:
.box {
margin: 30px;
width: 150px;
height: 80px;
display:inline-block;
border-radius: 15px;
background: red;
position: relative;
filter: /* the more shadow you add the thicker the border will be */
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green);
}
.box::before {
content: "";
position: absolute;
height: var(--h,20px);
width: var(--w,30px);
background: inherit;
transform:scale(var(--x,1),var(--y,1));
}
.box.p-bottom::before{
top: 100%;
clip-path: polygon(0 0, 100% 0, 50% 100%);
}
.box.p-bottom.alt::before{
clip-path: polygon(0 0, 100% 0, 100% 100%);
}
.box.p-top::before{
bottom: 100%;
clip-path: polygon(0 100%, 100% 100%, 50% 0);
}
.box.p-top.alt::before{
clip-path: polygon(0 100%, 100% 100%, 100% 0);
}
.box.p-left::before{
right: 100%;
clip-path: polygon(100% 0, 100% 100%,0% 50%);
}
.box.p-left.alt::before{
clip-path: polygon(100% 0, 100% 100%,0% 100%);
}
.box.p-right::before{
left: 100%;
clip-path: polygon(0% 0, 0% 100%,100% 50%);
}
.box.p-right.alt::before{
clip-path: polygon(0% 0, 0% 100%,100% 100%);
}
.box.right::before{
right:var(--p,20px);
}
.box.left::before {
left:var(--p,20px);
}
.box.top::before{
top:var(--p,20px);
}
.box.bottom::before {
bottom:var(--p,20px);
}
.box:hover {
background:blue;
}
body {
background:linear-gradient(to right, pink,grey);
}
<div class="box p-bottom right"></div>
<div class="box p-bottom right alt"></div>
<div class="box p-bottom right alt" style="--x:-1"></div>
<div class="box p-top left"></div>
<div class="box p-top right" style="--p:40%"></div>
<div class="box p-top right alt" style="--p:40%"></div>
<div class="box p-left top"></div>
<div class="box p-left top alt"></div>
<div class="box p-right bottom" style="--w:20px;"></div>
<div class="box p-right bottom" style="--p:30px;--w:20px;--h:30px"></div>
<div class="box p-right bottom alt" style="--p:30px;--w:20px;--h:30px"></div>
<div class="box p-right bottom alt" style="--p:30px;--w:20px;--h:30px;--y:-1"></div>
We can also consider any kind of background for the whole shape. The trick work for a fixed width/height. The idea is to create a background having the same size for both the main and pseudo element then we simply adjust the position of the one inside the pseudo element to match the one of the parent (to have a perfect overlap)
.box {
--h:20px;
--w:30px;
--p:20px;
margin: 30px;
width: 150px;
height: 80px;
display:inline-block;
border-radius: 15px;
background:
var(--back,linear-gradient(45deg,red,purple))
center/
calc(150px + 2*var(--w)) calc(80px + 2*var(--h));
position: relative;
filter: /* the more shadow you add the thicker the border will be */
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green)
drop-shadow(0px 0px 1px green);
}
.box::before {
content: "";
position: absolute;
height: var(--h);
width: var(--w);
background: inherit;
transform:scale(var(--x,1),var(--y,1));
background-position:var(--b1) 0 var(--b2);
}
.box.p-bottom::before{
top: 100%;
clip-path: polygon(0 0, 100% 0, 50% 100%);
--b1:bottom;
}
.box.p-bottom.alt::before{
clip-path: polygon(0 0, 100% 0, 100% 100%);
}
.box.p-top::before{
bottom: 100%;
clip-path: polygon(0 100%, 100% 100%, 50% 0);
--b1:top;
}
.box.p-top.alt::before{
clip-path: polygon(0 100%, 100% 100%, 100% 0);
}
.box.p-left::before{
right: 100%;
clip-path: polygon(100% 0, 100% 100%,0% 50%);
--b1:left;
}
.box.p-left.alt::before{
clip-path: polygon(100% 0, 100% 100%,0% 100%);
}
.box.p-right::before{
left: 100%;
clip-path: polygon(0% 0, 0% 100%,100% 50%);
--b1:right;
}
.box.p-right.alt::before{
clip-path: polygon(0% 0, 0% 100%,100% 100%);
}
.box.right::before{
right:var(--p);
--b2:right calc(-1*var(--p) - var(--w));
}
.box.left::before {
left:var(--p);
--b2:left calc(-1*var(--p) - var(--w));
}
.box.top::before{
top:var(--p);
--b2:top calc(-1*var(--p) - var(--h));
}
.box.bottom::before {
bottom:var(--p);
--b2:bottom calc(-1*var(--p) - var(--h));
}
body {
background:linear-gradient(to right, pink,grey);
}
<div class="box p-bottom right"></div>
<div class="box p-bottom right alt" style="--back:url(https://picsum.photos/id/15/400/300)"></div>
<div class="box p-bottom right alt" style="--x:-1;--back:red"></div>
<div class="box p-top left" style="--back:url(https://picsum.photos/id/18/400/300)"></div>
<div class="box p-top right" style="--p:40px;--back:url(https://picsum.photos/id/1018/400/300)"></div>
<div class="box p-top right alt" style="--p:60px;--back:radial-gradient(red,pink,yellow)"></div>
<div class="box p-left top" style="--back:black"></div>
<div class="box p-left top alt" style="--back:repeating-linear-gradient(45deg,#fff 0 10px,orange 0 20px)"></div>
<div class="box p-right bottom" style="--w:20px;--back:linear-gradient(red,pink,yellow)"></div>
<div class="box p-right bottom" style="--p:30px;--w:20px;--h:30px;--back:repeating-radial-gradient(#fff 0 10px,orange 0 20px)"></div>
<div class="box p-right bottom alt" style="--p:30px;--w:20px;--h:30px;--back:conic-gradient(red,pink,yellow,red)"></div>
<div class="box p-right bottom alt" style="--p:30px;--w:20px;--h:30px;--y:-1;"></div>
SVG
This does not pass a hit-test as the transparent border is also clickable
This can be done using the pointer-events in svg.
pointer-events:visibleFill; Will only select the part where there is paint.
This example uses filter_box-shadow and is not supported by IE.
Also uses two shapes.
html,
body {
margin: 0;
padding: 0;
}
.bubble {
width: 150px;
height: 150px;
-webkit-filter: drop-shadow(5px 5px 0px #aaa);
filter: drop-shadow(5px 5px 0px #aaa);
}
.bubble-shape {
fill: #1e1;
}
.shape-text {
color: black;
}
<svg class="bubble" viewBox="0 0 110 110" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<g class="bubble-shape" style="cursor:pointer; pointer-events:visibleFill;">
<rect x="10" y="10" width="90" height="90" rx="15" ry="15" />
<polygon points="20,94 40,94 30,105" />
</g>
</svg>
This example uses one path
Should be fully supported by IE.
html,
body {
margin: 0;
padding: 0;
}
.bubble {
width: 150px;
height: 150px;
}
.bubble-shape {
stroke-width: 15;
stroke: #ddd;
fill: #1e1;
}
.shape-text {
color: black;
}
<svg class="bubble" viewBox="-70 -10 390 370" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<g style="cursor:pointer; pointer-events:visible;">
<path class="bubble-shape" d="m 0,0 250,0 c 25,0 50,20 50,50 l 0,225 c 0,25 -25,50 -50,50 l -175,0 -25,20 -20,-20 -40,0 c -25,0 -50,-25 -50,-50 l 0,-225 C -50,25 -50,0 0,0 Z" />
</g>
</svg>
So I am given one element that has glyph icons and am asked to code it using html, css and supplied font. Now each glyph icon has codes and ligatures. Can anyone help me with it? what should be my approach to start coding that element.
SVG
The given shape can be created with SVG.
You will have to learn a lot of SVG to create complex shapes.
I would start at the basics
.widget {
width: 300px;
height: 300px;
}
.pill {
stroke: #999;
stroke-width: 1;
}
.pill .top {
fill: Orange;
}
.pill .bottom {
fill: LightSeaGreen;
}
.pill .circ-outer {
fill: rgb(120, 50, 120);
}
.pill .circ-inner {
stroke: none;
fill: white;
}
.pill .cross {
stroke: rgb(120, 50, 120);
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
fill: none;
}
.handle {
stroke: #999;
fill: #555;
}
.ribble {
stroke: #777;
stroke-linecap: round;
stroke-linejoin: round;
}
<svg class="widget" viewBox="0 0 100 100">
<defs>
<filter id="drop">
<feOffset in="SourceAlpha" dx="0" dy="0.2" result="off" />
<feGaussianBlur result="blurOut" in="off" stdDeviation="0.5" />
<feBlend in="SourceGraphic" in2="blurOut" />
</filter>
</defs>
<path class="handle" d="m35,16
a 5 10 0 0 1 0,70"/>
<line class="ribble" x1="43" y1="43" x2="43" y2="57" filter="url(#drop)"/>
<line class="ribble" x1="45" y1="45" x2="45" y2="55" filter="url(#drop)"/>
<line class="ribble" x1="47" y1="47" x2="47" y2="53" filter="url(#drop)"/>
<g class="pill">
<path class="top" d="m10,50 0,-30
a 5 5 0 0 1 30 0 v 30" />
<path class="bottom" d="m10,50 0,30
a 5 5 0 0 0 30 0 v -30" />
<circle class="circ-outer" cx="25" cy="50%" r="15" />
<circle class="circ-inner" cx="25" cy="50%" r="10" filter="url(#drop)" />
<polyline class="cross" points="30,50 20,50 25,50 25,55 25,45" />
</g>
</svg>
For glyphicons you can refer this link
For example: we can write is like:
<p>Envelope icon: <span class="glyphicon glyphicon-envelope"></span></p>
Please see the below link for more details
http://www.w3schools.com/bootstrap/bootstrap_ref_comp_glyphs.asp
http://getbootstrap.com/components/
Without bootstrap:
<div class="inner-addon left-addon">
<i class="glyphicon glyphicon-user"></i>
<input type="text" class="form-control" />
</div>
In CSS
/* enable absolute positioning */
.inner-addon {
position: relative;
}
/* style icon */
.inner-addon .glyphicon {
position: absolute;
padding: 10px;
pointer-events: none;
}
/* align icon */
.left-addon .glyphicon { left: 0px;}
.right-addon .glyphicon { right: 0px;}
/* add padding */
.left-addon input { padding-left: 30px; }
.right-addon input { padding-right: 30px; }
Got this from this:
Add Bootstrap Glyphicon to Input Box
I have tried to make replica based on your image. Try to add Search, Home and Plus icons to head-glyph , middle-glyph , tail -glyph div's to look little bit similar to your image.
CSS
.glyph {
display:block;
border:3px solid #bbb;
height:120px;
width:50px;
position:absolute;
background:grey;
border-radius:24px;
z-index:100;
}
.head-glyph {
border-radius:20px;
background:orange;
height:70px;
width:50px;
position:absolute;
z-index:200;
display:block;
}
.middle-glyph{
border-radius:25px;
background:#660066;
height:50px;
width:50px;
border:2px solid #bbb;
position:absolute;
z-index:300;
top:35;
left:-3;
display:block;
}
.middle-glyph-tiny{
border-radius:25px;
background:white;
height:35px;
width:35px;
position:absolute;
z-index:300;
top:8;
left:8;
display:block;
box-shadow: 0 0 5px #888;
}
.tail-glyph {
border-radius:20px;
background:skyblue;
height:70px;
width:50px;
position:absolute;
z-index:200;
bottom:0;
}
.half-circle {
position:absolute;
z-index:10;
height:118px;
width:55px;
border-radius: 0px 60px 60px 0px;
background:grey;
left:15;
top:-2;
border:3px solid #bbb;
}
HTML
<div class="glyph">
<div class="head-glyph"></div>
<div class="middle-glyph">
<div class="middle-glyph-tiny"></div>
</div>
<div class="tail-glyph"> </div>
<div class="half-circle"> </div>
</div>
http://jsbin.com/vumurafuwa/2/edit
since you're going to probably to need to register click events, I've used a couple of elements to allow for this:
Please note this is only for semantic purposes only
.wrap {
position: relative;
width: 75px;
height: 200px;
border-radius: 100px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
border: 3px solid darkgray;
margin: 50px;
background: lightgray;
z-index: 8;
box-shadow: 0 0 20px 10px black;
cursor: pointer;
}
.wrap:before {
content: "";
position: absolute;
left: 0;
width: 140%;
top: 8%;
height: 84%;
border-radius: 50%;
background: gray;
border: 3px solid darkgray;
}
.wrap:after {
content: "";
position: absolute;
width: 0;
border: 3px ridge darkgray;
border-radius: 3px;
height: 10%;
top: 45%;
left: 110%;
}
.middle:hover:before {
background: lightgray;
}
.top {
content: "";
position: absolute;
top: 0;
left: 0;
height: 50%;
width: 100%;
border-radius: 75px 75px 0 0;
background: orange;
transition: all 0.4s;
}
.top:before,
.bottom:before {
content: "";
position: absolute;
background: url(http://bahriadirectory.com/wp-content/uploads/2014/07/Very-Basic-Search-icon.png) no-repeat;
background-size: 40px 40px;
height: 50px;
width: 50px;
left: 10px;
}
.top:before {
top: 10px;
}
.bottom:before {
bottom: 5px;
}
.bottom:before {
background: url(http://www.wheatonbible.org/Content/10713/Icons/home-icon.png) no-repeat;
left: 8px;
background-size: 50px 50px;
}
.bottom {
content: "";
position: absolute;
top: 50%;
left: 0;
height: 50%;
width: 100%;
border-radius: 0 0 75px 75px;
background: cornflowerblue;
transition: all 0.4s;
}
.top:hover,
.bottom:hover {
background: lightgray;
}
.middle {
position: absolute;
height: 67px;
width: 100%;
border-radius: 50%;
border: 3px solid lightgray;
top: 50%;
left: -3px;
transform: translateY(-50%);
background: purple;
}
.middle:before {
content: "";
position: absolute;
top: 10%;
left: 10%;
background: white;
border-radius: 50%;
height: 80%;
width: 80%;
box-shadow: 5px 5px 5px 0 #222;
transition: all 0.4s;
}
.middle:after {
content: "+";
position: absolute;
top: 50%;
lefT: 50%;
transform: translate(-50%, -50%);
color: purple;
font-family: arial;
font-size: 80px;
}
html,
body {
margin: 0;
padding: 0;
background: #222;
}
<div class="wrap">
<div class="top"></div>
<div class="bottom"></div>
<div class="middle"></div>
</div>
Please note
I have used images for the search and home icons. These can be altered by using font icons/etc.
I am trying to make the below shape using only CSS. I know that achieving this shape using an image or SVG would be a lot easier but I am trying to achieve it with CSS for a proof of concept.
The below is the code that I have tried so far. It creates a diamond shape by using transform: rotate(45deg) but the diagonals are of the same length whereas the shape that I need has one very long diagonal and another very short.
.separator{
background: #555;
top: 40px;
padding-top: 0px;
margin: 0px 40px;
height: 100px;
width: 100px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
transform: rotate(45deg);
}
Fiddle Demo
Is it possible to create the shape that I need using CSS?
Note: A similar question was asked earlier and was closed/deleted as "too broad" as it did not show any coding attempt. Posting a new question and self answering it based on this meta discussion. Please feel free to chip in with alternate solutions (or) edit the question to make it more useful for future readers.
For a needle resting on its tip
Yes, it is possible to create that shape using only CSS. You have to rotate the shape along both the Y-axis and the Z-axis to achieve it.
Rotating it along the Z-axis by 45 degrees will produce a diamond shape (as indicated in the question) and rotating it along the Y-axis by close to (but less than) 90 degrees will make only a part of the shape visible from the front and thereby would give it the appearance of having shorter diagonal lines (resembling a compass pointer).
Additionally adding a linear-gradient for the background and a inset box-shadow will help to achieve a shape that is a lot closer to the shape shown in question.
body {
background: #333;
font-family: Calibri;
font-size: 18px;
}
div {
height: 200px;
width: 150px;
display: inline-block;
vertical-align: middle;
color: white;
padding-top: 40px;
}
.separator {
background: #555;
top: 40px;
padding-top: 0px;
height: 160px;
width: 160px;
background-image: linear-gradient(-45deg, #555 0%, #555 40%, #444 50%, #333 97%);
box-shadow: inset 6px 6px 22px 8px #272727;
transform: rotateY(87deg) rotate(45deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div>
Some lengthy paragraph content which wraps around when it exceeds the width
</div>
<div class='separator'></div>
<div>
Some lengthy paragraph content which wraps around when it exceeds the width
</div>
For a needle resting on its base
For a needle that is resting on its base, the rotation should be along the X-axis and Z-axis instead of along Y-axis and Z-axis for the needle resting on its tip. Below is a sample snippet.
body {
background: #AAA;
font-family: Calibri;
font-size: 18px;
}
div {
height: 200px;
width: 150px;
display: inline-block;
vertical-align: middle;
color: white;
padding-top: 40px;
margin: 40px;
}
.separator {
background: #555;
top: 40px;
padding-top: 0px;
height: 160px;
width: 160px;
background-image: linear-gradient(-45deg, #555 0%, #555 40%, #444 50%, #333 97%);
box-shadow: inset 6px 6px 22px 8px #272727;
transform: rotateX(87deg) rotate(45deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='separator'></div>
Compass Pointer created using above method:
Here is a sample compass pointer (inspired in part by the Safari logo) created purely using CSS. The pointer or the needle inside is created using the method explained above.
.container {
position: relative;
height: 152px;
width: 152px;
padding: 10px;
border-radius: 50%;
background: radial-gradient(circle at 50% 50%, white 58%, #999 70%, #EEE 80%);
border: 1px solid #AAA;
}
.dial {
height: 150px;
width: 150px;
border-radius: 50%;
background: linear-gradient(#1ad4fd, #1d65f0 100%);
border: 1px solid #999;
position: relative;
animation: rotatedial 2s 6 alternate forwards;
}
.dial:after {
content: '';
position: absolute;
top: 25px;
left: 25px;
height: 100px;
width: 100px;
background-image: linear-gradient(-45deg, white 0%, white 47%, red 50%);
box-shadow: inset 0px 6px 22px 0px #CCC, inset -6px -6px 22px 0px #AAA;
transform: rotateY(85deg) rotate(45deg);
}
.dial:before {
content: '';
position: absolute;
top: 72px;
left: 70px;
height: 8px;
width: 8px;
background: radial-gradient(circle at 50% 50%, white 30%, grey 100%);
border: 1px solid #999;
border-radius: 50%;
z-index: 2;
}
.hands,
.hands-small {
position: absolute;
height: 150px;
width: 150px;
top: 11.25px;
left: 11px;
z-index: 0;
}
.hands:before,
.hands:after,
.hands .hand:before,
.hands .hand:after {
content: '';
position: absolute;
top: 0;
left: 74.5px;
width: 1px;
height: 12px;
background: #EEE;
border-radius: 4px;
box-shadow: 0px 138px #EEE;
transform-origin: 50% 75px;
}
.hands-small:before,
.hands-small:after,
.hands-small .hand-small:before,
.hands-small .hand-small:after {
content: '';
position: absolute;
top: 0;
left: 74.5px;
width: 1px;
height: 7px;
background: #EEE;
border-radius: 4px;
box-shadow: 0px 143px #EEE;
transform-origin: 50% 75px;
}
.hands:before {
transform: rotate(-45deg);
}
.hands:after {
transform: rotate(0deg);
}
.hand:before {
transform: rotate(45deg);
}
.hand:after {
transform: rotate(90deg);
}
.hands-small:before {
transform: rotate(-22.5deg);
}
.hands-small:after {
transform: rotate(22.5deg);
}
.hand-small:before {
transform: rotate(67.5deg);
}
.hand-small:after {
transform: rotate(112.5deg);
}
#keyframes rotatedial {
0% {
transform: rotate(35deg);
}
100% {
transform: rotate(15deg);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="container">
<div class="dial"></div>
<div class="hands">
<div class="hand"></div>
</div>
<div class="hands-small">
<div class="hand-small"></div>
</div>
</div>
If you stumbled on this page looking for a SVG implementation, have a look at the below snippet:
.separator {
position: relative;
width: 12px;
}
svg {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
path {
fill: url(#MyGradient);
}
path#shade {
stroke: #2E2E2E;
stroke-width: 3;
}
/* Just for the demo to style the divs and position */
body {
background: #333;
font-family: Calibri;
font-size: 18px;
}
.container {
display: flex;
}
.container > .content {
flex: 1;
flex-grow: 1;
color: white;
margin: 20px;
}
<div class='container'>
<div class='content'>Some lengthy paragraph content which wraps around when it exceeds the width.Some lengthy paragraph content which wraps around when it exceeds the width.Some lengthy paragraph content which wraps around when it exceeds the width.</div>
<div class='separator'>
<svg viewBox='0 0 10 200' preserveAspectRatio='none'>
<defs>
<linearGradient id="MyGradient" x1=' 50% ' y1='0% ' x2='50% ' y2='100% '>
<stop offset="0%" stop-color="#333" />
<stop offset="100%" stop-color="#555" />
</linearGradient>
</defs>
<path d='M0,100 5,0 10,100 z' id='shade' />
<path d='M0,100 5,0 10,100 5,200 z ' />
</svg>
</div>
<div class='content '>Some lengthy paragraph content which wraps around when it exceeds the width.Some lengthy paragraph content which wraps around when it exceeds the width.Some lengthy paragraph content which wraps around when it exceeds the width.</div>
</div>