Is there any way to create navigation bar with transparent background color like below image?
I tried using CSS3 pseudo selectors but the curves are not as per the design:
div::before{
width: 200px;
height: 90px;
background: rgba(255, 255, 255, 0.2);
background: radial-gradient(circle 0 at -20% 50%,transparent,transparent 100px,rgba(255, 255, 255, 0.2) 100px),
radial-gradient(circle 20px at 180px 50%,transparent,transparent 100px,rgba(255, 255, 255, 0.2) 100px);
background-size:100px 90px, 100px 90px;
background-position:0 0,100% 0;
background-repeat:no-repeat
}
You can do this in multiple ways with CSS and I've shown few of them in the below answer. I've used ul and li tags because I feel they are more suited for a navigation bar but you can easily convert it to work with div tags also.
One drawback that both CSS approaches have is that the parent element is still basically a rectangle and so mouse interactions would happen outside the curve (but inside the element's boundaries). The only solution I have for this problem is to use clip-path.
Using Radial Gradient:
This is just like what you had started to do. I have just set the gradient at the correct position and have used it to produce the right hand side black border also. The curve on element's left side is done using the border-radius property.
The radial gradient is transparent for 20px (half the height of the element) and is black color for 1px (to produce the border), has the required background color for the rest of it.
Drawback of using gradients is that they would not work in IE9 and lower because they do not support gradients.
li {
position: relative;
float: left;
width: 33%;
height: 40px;
line-height: 36px; /* height - 2 * border width */
text-indent: 10px;
border: 2px solid rgba(0, 0, 0, .5);
border-right: none;
border-radius: 20px 0px 0px 20px;
background: radial-gradient(20px 20px at calc(100% + 4px) 50%, transparent 18px, rgba(0, 0, 0, .5) 19px, rgba(0, 0, 0, .5) 20px, rgba(255, 255, 255, .25) 21px); /* the first color after transparent is border color, the last color is background color */
background-clip: content-box;
box-shadow: -1px 2px 1px rgba(0, 0, 0, .25);
overflow: hidden;
}
ul {
list-style-type: none;
}
* {
box-sizing: border-box;
}
body {
background: radial-gradient(circle, chocolate 0%, sandybrown 100%);
min-height: 100vh;
}
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
Using Box Shadow:
This has better browser support because box-shadow works even in IE9. For this approach, we need a pseudo-element which is placed just inside the right border of the parent element. Both the elements (that is, the pseudo and the parent) have a border-radius assigned to create the curve. Background color is achieved using a wide box-shadow on the pseudo-element because assigning a background color to the parent or the pseudo-element will bleed outside the shape also.
li {
position: relative;
float: left;
width: 33%;
height: 40px;
line-height: 36px; /* height - 2 * border width */
text-indent: 10px;
border: 2px solid rgba(0, 0, 0, .5);
border-right: none;
border-radius: 20px 0px 0px 20px;
box-shadow: -1px 2px 1px rgba(0, 0, 0, .25);
overflow: hidden;
}
ul {
list-style-type: none;
}
li:after {
position: absolute;
content: '';
height: 100%;
width: 100%;
left: calc(100% - 18px); /* 100% - (half of height - border width) */
top: -2px; /* inverse of border width */
border-radius: 20px;
border: 2px solid rgba(0, 0, 0, .5);
box-shadow: 0px 0px 0px 999px rgba(255, 255, 255, .25); /* the color here is the background color */
z-index: -1;
}
*{
box-sizing: border-box;
}
body {
background: radial-gradient(circle, chocolate 0%, sandybrown 100%);
min-height: 100vh;
}
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
Using SVG:
You can do this using SVG also by creating the required shape with a path element and positioning it absolutely with respect to the parent.
li {
position: relative;
float: left;
width: 33%;
height: 40px;
line-height: 40px;
text-indent: 10px;
}
ul {
list-style-type: none;
}
svg {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
}
path {
stroke: rgba(0, 0, 0, .5); /* border color */
stroke-width: 2; /* border width */
fill: rgba(255, 255, 255, .25); /* background color */
}
path:hover{
stroke: red;
}
body {
background: radial-gradient(circle, chocolate 0%, sandybrown 100%);
min-height: 100vh;
}
<ul>
<li>
<svg viewBox='0 0 200 40' preserveAspectRatio='none'>
<path d='M20,1 A19,19 0 1,0 20,39 L200,39 A19,19 0 0,1 200,1z' />
</svg>One</li>
<li>
<svg viewBox='0 0 200 40' preserveAspectRatio='none'>
<path d='M20,1 A19,19 0 1,0 20,39 L200,39 A19,19 0 0,1 200,1z' />
</svg>Two</li>
<li>
<svg viewBox='0 0 200 40' preserveAspectRatio='none'>
<path d='M20,1 A19,19 0 1,0 20,39 L200,39 A19,19 0 0,1 200,1z' />
</svg>Three</li>
</ul>
Related
Hi I am trying to make a speedometer with gradient colours. My current code gets gradient colours, but its left to right.
Standing gradient - Wrong
I don't want the gradient that is in the vertical order. I want it to curve and fade.
Code:
.gauge {
font-family: Arial, Helvetica, sans-serif;
background-color: red;
background-image: linear-gradient(to right , red , orange , yellow , green);
box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.09), 0 0 35px 5px rgba(255, 255, 255, 0.29);
width: 200px;
height: 100px;
border-radius: 100px 100px 0 0;
position: relative;
overflow: hidden;
/* safari fix */
-webkit-transform-style: flat;
-webkit-transform: translateZ(0px);
}
<div class="gauge"></div>
What i am trying to achieve is a gradient of pizza pieces.
This can be achieved using conic-gradient: https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/conic-gradient
.conic-gradient {
width: 150px;
height: 150px;
background: conic-gradient(from 180deg, blue, green, yellow, orange, red);
border-radius: 100%;
}
<div class="conic-gradient">
<div>
You need to tweak it to your needs.
A mix of radial and conic gradients might also do, here a possible example:
.gauge {
font-family: Arial, Helvetica, sans-serif;
background:
/*black part */radial-gradient( circle at bottom center, black 59px, #5555 , transparent 65px),
/*pizza's pieces*/conic-gradient( from 4.7rad at 50% 100%, #39ab5e 0deg 36deg, #9ca92e 36deg 72deg, #eec22a 72deg 108deg, #e07b27 108deg 144deg, #e2443c 144deg);
box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.09), 0 0 35px 5px rgba(255, 255, 255, 0.29);
width: 200px;
height: 100px;
border-radius: 100px 100px 0 0;
position: relative;
overflow: hidden;
/* safari fix */
-webkit-transform-style: flat;
-webkit-transform: translateZ(0px);
}
/* demo purpose*/
html {
min-height: 100vh;
display: grid;
}
body {
background: #3D1873;
margin: auto;
}
.gauge {
color: white;
display: grid;
align-items: end;
justify-content: center;
font-size: 1.7em;
line-height:2.75
}
<div class="gauge">BIM</div>
colors blending
.gauge {
font-family: Arial, Helvetica, sans-serif;
background:
/*black part */radial-gradient( circle at bottom center, black 59px, #5555 , transparent 65px),
/*pizza's pieces*/conic-gradient( from 4.7rad at 50% 100%, #39ab5e 0deg 36deg, #9ca92e 36deg 72deg, #eec22a 72deg 108deg, #e07b27 108deg 144deg, #e2443c 144deg);
box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.09), 0 0 35px 5px rgba(255, 255, 255, 0.29);
width: 200px;
height: 100px;
border-radius: 100px 100px 0 0;
position: relative;
overflow: hidden;
/* safari fix */
-webkit-transform-style: flat;
-webkit-transform: translateZ(0px);
}
/* colors blending to next */
.gauge ~ .gauge {
background:
/*black part */radial-gradient( circle at bottom center, black 59px, #5555 , transparent 65px),
/*pizza's pieces*/conic-gradient( from 4.7rad at 50% 100%, #39ab5e , #9ca92e 36deg, #eec22a 72deg, #e07b27 108deg, #e2443c 144deg );
box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.09), 0 0 35px 5px rgba(255, 255, 255, 0.29);
}
/* demo purpose*/
html {
min-height: 100vh;
display: grid;
text-align:center;
color:white;
}
body {
background: #3D1873;
display:flex;
margin: auto;
}
.gauge {
margin:1em;
color: white;
display: grid;
align-items: end;
justify-content: center;
font-size: 1.7em;
line-height:2.75;
flex-shrink:0;
}
.gauge:before {
content:'';
position:absolute;
bottom:-3px;
left:20px;
width:80px;
height: 6px;
background:linear-gradient(to left , transparent 55px, black 55px);
border-radius:50%;
box-shadow:3px 2px 2px #555;
clip-path: polygon(-10px -10px, 20px -10px, 20px 10px, -10px 10px);
transform-origin:center right;
transform:rotate(90deg);
animation: 4s rot infinite alternate;
}
#keyframes rot{
15%, from {transform:rotate(0deg)}
90%, to {transform:rotate(180deg)}
}
.gauge ~.gauge:before {
animation-play-state:paused;
}
.gauge ~ .gauge:hover:before {
animation: 4s rot infinite alternate;
}
<div class="gauge">BIM</div>
Next: animation paused<br>
hover to play animation
<div class="gauge">BIM</div>
I am trying to use CSS linear-gradient and box-shadow to make an image have a box-shadow on 3 sides (top, right, and left) while also having a "fade-to-white" on the bottom edge of the image.
I don't want the image url in the CSS, I want to use the img tag in the html.
This is what I have so far: https://codepen.io/adelelanders/pen/rNVMxZw however the bottom edge is still showing the box-shadow (dark line). I want the bottom edge to fade to white.
img {
max-width: 100%;
}
.image-container {
max-width: 100%;
width: 600px;
}
.white-fade::after {
display: block;
position: relative;
background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0, #fff 100%);
margin-top: -150px;
height: 150px;
width: 100%;
content: '';
}
.box-shadow {
border-radius: 5px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
}
<div class="image-container white-fade">
<img class="box-shadow" src="https://cdn.pixabay.com/photo/2019/03/18/06/46/cyber-4062449__340.jpg" />
</div>
consider mask instead of gradient
img {
max-width: 100%;
}
.image-container {
max-width: 100%;
width: 600px;
padding:20px; /* Some padding for the shadow */
-webkit-mask:
linear-gradient(#fff,#fff) top/100% calc(100% - 149px) no-repeat,
linear-gradient(#fff,transparent) bottom/100% 150px no-repeat;
mask:
linear-gradient(#fff,#fff) top/100% calc(100% - 149px) no-repeat,
linear-gradient(#fff,transparent) bottom/100% 150px no-repeat;
}
.box-shadow {
border-radius: 5px;
display:block;
box-shadow: 0 10px 20px rgba(0, 0, 0, 1), 0 6px 6px rgba(0, 0, 0, 1);
}
<div class="image-container white-fade">
<img class="box-shadow" src="https://cdn.pixabay.com/photo/2019/03/18/06/46/cyber-4062449__340.jpg" />
</div>
I have a progress bar that show from left to right. I need to make another which is same style progress but will show from right to left.
Here is my style definition:
progress, progress[role] {
-webkit-appearance: none;
appearance: none;
border: none;
background-size: auto;
height: 50px;
width: 100%;
padding-top: 10px;
}
progress[value]::-webkit-progress-bar {
background-color: grey;
border-radius: 2px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset;
}
progress[value]::-webkit-progress-value {
background-image:
-webkit-linear-gradient(-45deg,
transparent 33%, rgba(0, 0, 0, .1) 33%,
rgba(0,0, 0, .1) 66%, transparent 66%),
-webkit-linear-gradient(top,
rgba(255, 255, 255, .25),
rgba(0, 0, 0, .25)),
-webkit-linear-gradient(left, #09c, #f44);
border-radius: 2px;
background-size: 35px 20px, 100% 100%, 100% 100%;
}
.valuebar {
position: relative;
}
.valuebar h3 {
color: #fff;
left: 1em;
line-height: 1;
position: absolute;
}
I used sample from the web which uses ::-webkit-progress-value.
How can I make it render from right to left?
Generally, many elements flip their horizontal rendering when their direction attribute is changed from ltr (which is the default) to rtl, which stands for right-to-left (to be compatible with right-to-left languages, such as Arabic or Hebrew).
The <progress> element is not different. Just give CSS something to cling to (such as a special class) and set its direction: rtl;.
Here is a small snippet based on the code you posted.
/* this is the important bit */
progress.rtl {
direction: rtl;
}
progress,
progress[role] {
-webkit-appearance: none;
appearance: none;
border: none;
background-size: auto;
height: 50px;
width: 100%;
padding-top: 10px;
}
progress[value]::-webkit-progress-bar {
background-color: grey;
border-radius: 2px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset;
}
progress[value]::-webkit-progress-value {
background-image: -webkit-linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, .1) 33%, rgba(0, 0, 0, .1) 66%, transparent 66%), -webkit-linear-gradient(top, rgba(255, 255, 255, .25), rgba(0, 0, 0, .25)), -webkit-linear-gradient(left, #09c, #f44);
border-radius: 2px;
background-size: 35px 20px, 100% 100%, 100% 100%;
}
.valuebar {
position: relative;
}
.valuebar h3 {
color: #fff;
left: 1em;
line-height: 1;
position: absolute;
}
<progress value="59" max="100">59%</progress>
<br />
<progress class="rtl" value="59" max="100">59%</progress>
I don't know what is your markup, as you did not post it, but you may need to adjust the .valuebar positioning.
Here is a code pen you can toy with.
I have created a shape which represents a page with a shadow that gets bigger towards the bottom.
body {
background: #dddddd;
}
div {
background: white;
margin: 40px auto;
height: 300px;
width: 300px;
position: relative;
padding: 10px;
}
div:before,
div:after {
height: 96%;
z-index: -10;
position: absolute;
content: "";
left: 8px;
top: 2%;
width: 30%;
max-width: 300px;
background: transparent;
box-shadow: -10px 0px 10px rgba(0, 0, 0, 0.5);
transform: rotate(1.5deg);
}
div:after {
transform: rotate(-1.5deg);
right: 8px;
left: auto;
box-shadow: 10px 0px 10px rgba(0, 0, 0, 0.5);
}
<div></div>
I need this to be rotated but when i try to add transform: rotate(10deg), the box-shadow illusion gets ruined and goes on top of the parent layer.
body {
background: #dddddd;
}
div {
background: white;
margin: 40px auto;
height: 300px;
width: 300px;
position: relative;
padding: 10px;
transform: rotate(10deg);
}
div:before,
div:after {
height: 96%;
z-index: -10;
position: absolute;
content: "";
left: 8px;
top: 2%;
width: 30%;
max-width: 300px;
background: transparent;
box-shadow: -10px 0px 10px rgba(0, 0, 0, 0.5);
transform: rotate(1.5deg);
}
div:after {
transform: rotate(-1.5deg);
right: 8px;
left: auto;
box-shadow: 10px 0px 10px rgba(0, 0, 0, 0.5);
}
<div></div>
I have found this question: Which CSS properties create a stacking context? but there doesn't seem to be a proposed solution for my requirement.
Would there be any good solutions which would work in my case. I do not mind if they are SVG, filter, canvas or any thing else as long as it is supported reasonably well.
If you use another div it fixes the problem that you are experiencing, so that the background colour is on the inner div and the rotate is on the outer div.
Else you might need to use another method to get the same result.
body {
background: #dddddd;
}
.two{
background: white;
height: 300px;
width: 300px;
padding: 10px;
}
div.one {
margin: 40px auto;
height: 300px;
width: 300px;
position: relative;
transform: rotate(10deg);
}
div.one:before,
div.one:after {
height: 96%;
z-index: -10;
position: absolute;
content: "";
left: 8px;
top: 2%;
width: 30%;
max-width: 300px;
background: transparent;
box-shadow: -10px 0px 10px rgba(0, 0, 0, 0.5);
transform: rotate(1.5deg);
}
div.one:after {
transform: rotate(-1.5deg);
right: 8px;
left: auto;
box-shadow: 10px 0px 10px rgba(0, 0, 0, 0.5);
}
<div class="one">
<div class="two">
</div>
</div>
Note: This answer does not describe how to fix the stacking context problem that is seen in your approach. This just provides a couple of alternate approaches that could be used to achieve a similar effect. Advantage of these approaches is that they should work in IE10+ and does not require any extra elements.
I would still recommend vals' answer if IE support is not mandatory.
Method 1: Perspective Transform
This is almost similar to the one that you had used except that it uses a single pseudo-element rotated with perspective to produce the shadows. Since only one pseudo-element is utilized, the other pseudo can be used to add a white foreground above the shadows.
body {
background: #dddddd;
}
div {
position: relative;
height: 300px;
width: 300px;
padding: 10px;
margin: 40px auto;
transform: rotate(10deg);
}
div:before,
div:after {
position: absolute;
content: '';
top: 0px;
}
div:before {
height: 100%;
width: 100%;
left: 0px;
background: white;
}
div:after {
height: 98%;
width: 97%;
left: 1.5%;
transform-origin: bottom;
transform: perspective(125px) rotateX(1deg);
box-shadow: 10px 0px 10px rgba(0, 0, 0, .5), -10px 0px 10px rgba(0, 0, 0, .5);
z-index: -1;
}
<div></div>
Method 2: Linear Gradients
We can use linear-gradient background images and position them appropriately to produce an effect similar to the one produced by the box-shadows. But as you can see in the output, it doesn't quite match up to a shadow because the blurred areas are not the same.
Here, we make use of the following:
One small angled linear gradient image (to top left) to produce the shadow on the left side of the box.
Another small angled linear gradient image (to top right) to produce the shadow on the right side of the box.
A large linear-gradient image for the white colored area (which is almost a solid color). A gradient is used here instead of a solid color because the size of a gradient image can be controlled.
body {
background: #dddddd;
}
div {
margin: 40px auto;
height: 300px;
width: 300px;
transform: rotate(10deg);
backface-visibility: hidden;
background: linear-gradient(to right, transparent 0.1%, white 0.1%), linear-gradient(to top left, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .3) 5%, transparent 50%), linear-gradient(to top right, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .3) 5%, transparent 50%);
background-size: 280px 100%, 10px 97%, 10px 97%;
background-position: 10px 0px, left top, right top;
background-repeat: no-repeat;
background-origin: border-box;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div></div>
The bottom of the gradient still doesn't get the blur that is seen in the box-shadow output. If needed, this can be achieved to some extent by adding even more gradients like in the below snippet.
body {
background: #dddddd;
}
div {
margin: 40px auto;
height: 300px;
width: 300px;
transform: rotate(10deg);
backface-visibility: hidden;
background: linear-gradient(to right, transparent 0.1%, white 0.1%), linear-gradient(to top left, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .3) 5%, transparent 50%), linear-gradient(to top right, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .3) 5%, transparent 50%), linear-gradient(to bottom left, rgba(0, 0, 0, 0), rgba(0, 0, 0, .3) 5%, transparent 60%), linear-gradient(to bottom right, rgba(0, 0, 0, 0), rgba(0, 0, 0, .3) 5%, transparent 70%);
background-size: 280px 100%, 10px 97%, 10px 97%, 10px 2.5%, 10px 2.5%;
background-position: 10px 0px, left top, right top, left 99.25%, right 99.25%;
background-repeat: no-repeat;
background-origin: border-box;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div></div>
When you go into the transforms world, the transforms themselves will solve some of the problems that they create.
You can solve this with the 3d equivalent of z-index, the Z coordinate
Unfortunately, this won't work in IE (I believe until they support preserve 3d)
body {
background: #dddddd;
}
div {
background: white;
margin: 40px auto;
height: 300px;
width: 300px;
position: relative;
padding: 10px;
transform: translateZ(1px) rotate(10deg);
transform-style: preserve-3d;
}
div:before,
div:after {
height: 96%;
z-index: -10;
position: absolute;
content: "";
left: 8px;
top: 2%;
width: 30%;
max-width: 300px;
background: transparent;
box-shadow: -10px 0px 10px rgba(0, 0, 0, 0.5);
transform: translateZ(-1px) rotate(1.5deg);
}
div:after {
transform: translateZ(-1px) rotate(-1.5deg);
right: 8px;
left: auto;
box-shadow: 10px 0px 10px rgba(0, 0, 0, 0.5);
}
<div></div>
My Css is as below i try to move the "+" icon to the right a bit but failed to move it, can anyone help?
.button-sec-icon {
background-color: #fdfdfd;
cursor:pointer;
background: transparent url("images/basicsetup/plus.png") no-repeat left!important;
margin-right: 5px;
border: 2px solid #EEEEEE;
border-radius: 5px 5px 5px 5px;
box-shadow: 0 3px 1px rgba(0, 0, 0, 0.2);
color: #ca2b2b;
display: block;
height: 28px;
margin: 10px 0 0 60px;
transition: all 0.5s ease 0s;
min-width: 150px;
width: 121px;
}
.button-sec-icon:hover {
border :1px solid #888;
box-shadow: 0 4px 1px rgba(0, 0, 0, 0.2);
}
You need to use background-position
background: transparent url("images/basicsetup/plus.png") no-repeat left!important;
So instead of using left, use
background-position: 10px 0; /* Parameters are X and Y respectively */
Can you just set the background-position to top right?
background: transparent url("images/basicsetup/plus.png") top right no-repeat !important;
Or even if you need it across a bit, use percentages or fixed widths:
background: transparent url("images/basicsetup/plus.png") 0 5% no-repeat !important;
background: transparent url("images/basicsetup/plus.png") 0 5px no-repeat !important;
You used the margin tag twice. "margin-right" and "margin". Delete the first "margin-right" and see what happens.
background-position: 10px 0px;
This should do the trick, background-position can be used in many ways.
Take a read here:
http://www.css3.com/css-background-position/