I was looking for a multi component date picker like the one in the image under, but didn't find anything on Github, or elsewhere.
So I decided to make one. I'm having problems implementing the CSS where it fades out on top and bottom.
I thought about using :before and :after in the container, but no success. Can I apply gradients in :before and :after
For example:
ol {
overflow: hidden;
width: 8em;
height: 6em;
text-align: center;
border: 0.5em solid black;
border-radius: 0.5em;
padding: 0px;
}
li {
margin: 0px;
list-style: none;
padding: 0.5em 0;
line-height: 1em;
border: 1px solid #ccf;
}
<ol>
<li>2010</li>
<li>2011</li>
<li>2012</li>
<li>2013</li>
<li>2014</li>
<li>2015</li>
<li>2016</li>
<li>2017</li>
<li>2018</li>
<li>2019</li>
<li>2020</li>
</ol>
How to make the shadow on top and bottom?
Yes, you can apply gradients in :before and :after elements.
Example:
ol {
overflow: hidden;
width: 8em;
height: 6em;
position: relative;
text-align: center;
border: 0.5em solid black;
border-radius: 0.5em;
padding: 0px;
}
ol:before {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom : 80%;
content: "";
background-image: linear-gradient(to bottom, rgba(0,0,0.1) 0%, rgba(0,0,0) 100%);
z-index: -1;
pointer-events: none;
}
ol:after {
position: absolute;
left: 0;
right: 0;
top: 20%;
bottom : 0;
content: "";
background-image: linear-gradient(to bottom, rgba(0,0,0.1) 0%, rgba(0,0,0) 100%);
z-index: -1;
pointer-events: none;
}
li {
margin: 0px;
list-style: none;
padding: 0.5em 0;
line-height: 1em;
border: 1px solid #ccf;
}
Ok, got it by using gradients not on :before / :after but in a new div which floats with position: absolute; like:
.fader {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 9em;
background: linear-gradient(top, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, 0) 70%, rgba(0, 0, 0, 0.7) 100%);
background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, 0) 70%, rgba(0, 0, 0, 0.7) 100%);
background: -moz-linear-gradient(top, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, 0) 70%, rgba(0, 0, 0, 0.7) 100%);
pointer-events: none;
}
and the HTML:
<div class="date-picker">
<ol>
<li>2010</li>
<li>2011</li>
...
</ol>
<div class="fader"></div>
</div>
jsFiddle: https://jsfiddle.net/bo7dyx83/
Try something like this:
<div class="date-picker">
<ol>
<li>2010</li>
...
</ol>
<div class="shadow"></div>
</div>
With the date-picker styled however you like (setting width and height), and the following CSS:
.date-picker {
position: relative;
width: 8em;
height: 6em;
border: 0.5em solid black;
border-radius: 0.5em;
}
ol {
position: absolute;
overflow: hidden;
width: 100%;
height: 100%;
text-align: center;
margin: 0;
padding: 0;
}
li {
margin: 0px;
list-style: none;
padding: 0.5em 0;
line-height: 1em;
border: 1px solid #ccf;
}
.shadow {
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(rgba(0, 0, 0, 0.2), transparent, transparent, rgba(0, 0, 0, 0.2));
}
This creates a gradient image overlay positioned in front of the ol which is the image's sibling. Keep in mind that the z-index of .shadow needs to be larger than that of the ol.
EDIT: Looking more closely at the image you posted, the gradient seems closer to quadratic than linear. If you want the list to look more rounded, making a non-linear gradient in photoshop or something would make it look much more three dimensional.
Related
I want to make a card look like this, the border or the sides of the card are semi-circular, is it possible to make it with css? if yes, how? Thank you in advance
.wrapper {
}
.content-card {
width: 315px;
height: 131px;
left: 0px;
top: 0px;
background: #FFFFFF;
box-shadow: 4px 8px 12px rgba(0, 0, 0, 0.12);
border-radius: 8px;
}
<div class="wrapper">
<div class="content-card">
</div>
</div>
Multiple background can do it:
.content-card {
width: 300px;
height: 150px;
background:
radial-gradient(8px at left ,#0000 98%,#fff) left ,
radial-gradient(8px at right,#0000 98%,#fff) right;
background-size: 50.5% 25px;
background-repeat:repeat-y;
filter: drop-shadow(4px 8px 12px rgba(0, 0, 0, 0.12));
border-radius: 8px;
}
body {
background: pink;
}
<div class="content-card">
</div>
The old way - border-image
It permits you to use the willing image for borders, it was widely use for this kind of cases. You can have repeat option on it to allow different box's sizes with the same style.
The mozilla doc is quite explicit with good examples of it : https://developer.mozilla.org/en-US/docs/Web/CSS/border-image
The recent way - without image
You have the possibility to use pseudo-element :after and :before and stylize those elements with a repeated background using radial-gradient.
body {
background-color: #ffaaaa;
}
.ticket {
position: relative;
width: 300px;
height: 170px;
margin: 10px;
border-radius: 10px;
background: white;
box-shadow: 4px 8px 12px rgba(0, 0, 0, 0.12);
}
.ticket:before,
.ticket:after {
content: '';
position: absolute;
top: 5px;
width: 6px;
height: 160px;
}
.ticket:before {
left: -5px;
background: radial-gradient(circle, transparent, transparent 50%, #FBFBFB 50%, #FBFBFB 100%) -7px -8px/16px 16px repeat-y;
}
.ticket:after {
left: 300px;
background: radial-gradient(circle, transparent, transparent 50%, #FBFBFB 0%, #FBFBFB 100% ) -3px -7px / 16px 16px repeat-y;
}
<div class="ticket"></div>
I am trying to achieve this shape of div to hold profile information.
So far I've curved one of the corners. However, I am having problems parallel lines.
My HTML:
<div class="profile-card">
<h1>Sector Specialist</h1>
<p>Frank ocean</p>
</div>
My CSS:
.profile-card{
margin-top:150px;
float:right;
background-color: rgba(0,0,0,0.4);
height:500px;
text-align:center;
padding: 50px 40px;
border: 2px solid red;
border-top-left-radius: 39px;
}
The codepen is https://codepen.io/anon/pen/wjMQmw
Thank you in advance.
I would consider a solution with pseudo-element with some skew transformation:
.profile-card {
background: rgba(0, 0, 0, 0.4);
width: 200px;
text-align: center;
padding: 50px 0 0 40px;
border-top-left-radius: 39px;
border-left: 1px solid red;
border-top: 1px solid red;
position: relative;
}
.profile-card:before {
content: "";
position: absolute;
right: -40px;
width: 40px;
top: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.4);
transform: skewY(45deg);
transform-origin: top left;
border-top: 1px solid red;
border-right: 1px solid red;
box-sizing:border-box;
}
.profile-card:after {
content: "";
position: absolute;
bottom: -40px;
height: 40px;
right: 0;
left: 0;
background: rgba(0, 0, 0, 0.4);
transform: skewX(45deg);
border-left: 1px solid red;
border-bottom: 1px solid red;
transform-origin: top left;
box-sizing:border-box;
}
body {
background:linear-gradient(to right,lightblue,pink)
}
<div class="profile-card">
<h1>Sector Specialist</h1>
<p>Frank ocean</p>
</div>
Without the border I would consider multiple gradient to achieve the layout:
.profile-card {
background:
linear-gradient(to bottom left,rgba(0, 0, 0, 0.4) 50%,transparent 51%)0 100%/50px 50px no-repeat,
linear-gradient(to top right,rgba(0, 0, 0, 0.4) 50%,transparent 51%)100% 0/50px 50px no-repeat,
linear-gradient(rgba(0, 0, 0, 0.4),rgba(0, 0, 0, 0.4))100% 100%/calc(100% - 50px) 50px no-repeat,
linear-gradient(rgba(0, 0, 0, 0.4),rgba(0, 0, 0, 0.4))0 0/calc(100% - 50px) 50px no-repeat,
linear-gradient(rgba(0, 0, 0, 0.4),rgba(0, 0, 0, 0.4))0 50px/100% calc(100% - 100px) no-repeat;
width: 200px;
text-align: center;
padding: 50px 40px;
border-top-left-radius: 39px;
}
<div class="profile-card">
<h1>Sector Specialist</h1>
<p>Frank ocean</p>
</div>
Or the clip-path solution:
.profile-card {
background:rgba(0, 0, 0, 0.4);
width: 200px;
text-align: center;
padding: 50px 40px;
border-top-left-radius: 39px;
-webkit-clip-path: polygon(1% 0%, 75% 1%, 100% 30%, 100% 100%, 21% 100%, 0% 74%);
clip-path: polygon(1% 0%, 75% 1%, 100% 30%, 100% 100%, 21% 100%, 0% 74%)
}
<div class="profile-card">
<h1>Sector Specialist</h1>
<p>Frank ocean</p>
</div>
For super complex bordering, one option is to use SVG. Here is an example of basic usage of polygon. SVG embedded into HTML can be styled using CSS easily:
body{
margin:0;
height: 500px;
background: url('https://cdn3.tropicalsky.co.uk/images/1280x720/downtown-dubai-aerial-view.jpg');
}
.profile-card{
margin-top:5px;
background-color: transparent;
height:800px;
width: 200px;
text-align:center;
padding: 50px 40px;
position: relative;
}
.profile-card h1, .profile-card p {
position: relative;
}
.frame {
position: absolute;
top: 20px;
left: 20px;
opacity: 0.7;
}
<div class="profile-card">
<svg class="frame" height="300" width="300">
<polygon points="50 0,250 0,300 50,300 300, 50 300, 0 250, 0 50,7.5 25, 15 15, 25 7.5" style="fill:lightgrey;stroke:orange;stroke-width:1" />
</svg>
<h1>Sector Specialist</h1>
<p>Frank ocean</p>
</div>
I have a div wrapper and a div row and both have position properties set to relative. The wrapper div has a higher z-index than the inner div and both have background's set, however, the higher z-index background is still below the lower div's background. JS Fiddle Example
.wrapper {
position: relative;
z-index: 1000;
border: 1px solid black;
width: 131px;
height: 25px;
background: repeating-linear-gradient( to right, rgba(255, 0, 0, 0), rgba(255, 0, 0, 0) 10px, black 11px, black 1px);
}
.row {
position: relative;
z-index: -1;
margin-top: 2px;
margin-bottom: 1px;
width: 100%;
height: 20px;
background: linear-gradient( to right, rgba(255, 0, 0, 0) 50%, red 50%);
}
<div class="wrapper">
<div class="row"></div>
</div>
If you want the grid lines over the red bar, remove the z-index from the wrapper div:
.wrapper {
position: relative;
border: 1px solid black;
width: 131px;
height: 25px;
background: repeating-linear-gradient( to right, rgba(255, 0, 0, 0), rgba(255, 0, 0, 0) 10px, black 11px, black 1px);
}
.row {
position: relative;
z-index: -1;
margin-top: 2px;
margin-bottom: 1px;
width: 100%;
height: 20px;
background: linear-gradient( to right, rgba(255, 0, 0, 0) 50%, red 50%);
}
<div class="wrapper">
<div class="row"></div>
</div>
Remove z-index from wrapper div, and you should be good to go.
.wrapper {
position: relative;
border: 1px solid black;
width: 131px;
height: 25px;
background: repeating-linear-gradient( to right, rgba(255, 0, 0, 0), rgba(255, 0, 0, 0) 10px, black 11px, black 1px);
}
.row {
position: relative;
z-index: -1;
margin-top: 2px;
margin-bottom: 1px;
width: 100%;
height: 20px;
background: linear-gradient( to right, rgba(255, 0, 0, 0) 50%, red 50%);
}
<div class="wrapper">
<div class="row"></div>
</div>
I had to style block corners as in this first image.
I did it with help of extra inner block, using ::before and ::after pseudo-elements of both blocks:
<div class="header__text">
<p>
Lorem ipsum
</p>
</div>
.header__text {
display: inline-block;
vertical-align: top;
margin: 0 auto;
position: relative;
}
.header__text::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 12px;
height: 12px;
border-top: 1px solid rgba(0, 0, 0, 1);
border-left: 1px solid rgba(0, 0, 0, 1);
}
.header__text::after {
content: '';
position: absolute;
top: 0;
right: 0;
width: 12px;
height: 12px;
border-top: 1px solid rgba(0, 0, 0, 1);
border-right: 1px solid rgba(0, 0, 0, 1);
}
.header__text p {
margin: 0;
padding: 10px 20px;
font-family: Arial, sans-serif;
font-size: 21px;
line-height: 1.2em;
font-weight: 400;
color: #000;
text-transform: none;
text-decoration: none;
letter-spacing: .07em;
text-align: center;
position: relative;
}
.header__text p::before {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 12px;
height: 12px;
border-bottom: 1px solid rgba(0, 0, 0, 1);
border-left: 1px solid rgba(0, 0, 0, 1);
}
.header__text p::after {
content: '';
position: absolute;
bottom: 0;
right: 0;
width: 12px;
height: 12px;
border-bottom: 1px solid rgba(0, 0, 0, 1);
border-right: 1px solid rgba(0, 0, 0, 1);
}
jsbin link
Are there any better ways to style it using only css, without extra blocks, images, other auxiliary things? Just pure css.
Thanks.
You could use multiple gradient background-images:
div {
display: inline-block;
background-image:
linear-gradient(90deg, black 12px, transparent 12px, transparent calc(100% - 12px), black calc(100% - 12px)),
linear-gradient(90deg, black 12px, transparent 12px, transparent calc(100% - 12px), black calc(100% - 12px)),
linear-gradient(black 12px, transparent 12px, transparent calc(100% - 12px), black calc(100% - 12px)),
linear-gradient(black 12px, transparent 12px, transparent calc(100% - 12px), black calc(100% - 12px));
background-size: 100% 1px, 100% 1px, 1px 100%, 1px 100%;
background-repeat: no-repeat;
background-position: 0 0, 0 100%, 0 0, 100% 0;
}
p {
margin: 0;
padding: 10px 20px;
}
<div><p>Lorem Ipsum</p></div>
The below code works well on all browsers except Internet Explorer.
In IE the wording seems to be compressed to 1px height or covered by the hr gradient.
What's causing this problem?
.hr-how {
text-align: center;
border: 0;
height: 1px;
margin-bottom: 40px;
margin-top: 40px;
background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0));
}
.hr-how:after {
content: "HOW TO USE IT";
display: inline-block;
position: relative;
top: -0.7em;
font-size: 0.9em;
padding: 0 0.6em;
background: white;
}
<hr class="hr-how" id="hr-how">
http://jsfiddle.net/y8nx51rf/
This is happening because the default setting for overflow on hr tags is visible in Chrome and Firefox but hidden in IE. This causes any content outside the height of the hr to be cut off in IE.
To make this work in IE add overflow: visible; to .hr-how so the text can extend outside the boundaries of the hr.
.hr-how {
background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0));
border: 0;
height: 1px;
margin-bottom: 40px;
margin-top: 40px;
overflow: visible;
text-align: center;
}
.hr-how:after {
background: white;
content: "HOW TO USE IT";
display: inline-block;
font: "BodoniXT" !important;
font-size: 0.9em;
padding: 0 0.6em;
position: relative;
top: -0.7em;
}
<hr class="hr-how" id="hr-how" />