I have a fixed, 100% height menu on the left and I need to create a shadow effect on its right side that would disappear after while.
See the figure that illustrates this.
How to create this effect?
Here is a fiddle: http://jsfiddle.net/52VtD/7787/
HTML:
<nav id="main-menu">
<h1>Hello</h1>
A
B
C
D
</nav>
CSS:
#main-menu {
width: 320px;
height: 100%;
top: 0;
z-index: 1000;
position: fixed;
background-color: #b4bac1;
}
You can achieve this with CSS3: box-shadow and transform.
In the example below the box-shadow is applied to a pseudo element of .menuContainer which sits underneath the .menu element and is rotated by 1° using CSS3s rotate() transform property.
html,body { /* This is only here to allow the menu to stretch to 100% */
height: 100%;
margin: 0;
}
.menuContainer {
position: relative;
height: 100%;
width: 100px;
}
.menuContainer::after {
content: "";
position: absolute;
z-index: 1;
top: -10px;
bottom: 0;
left: -7px;
background: rgba(0,0,0,0.3);
box-shadow: 10px 0 10px 0 rgba(0,0,0,0.3);
width: 100px;
transform: rotate(1deg);
}
.menu {
background: #f00;
height: 100%;
width: 100px;
position: relative;
z-index: 2;
}
<div class="menuContainer">
<div class="menu"></div>
</div>
JSFiddle
You could fake it with a pseudo-element rather than using a box-shadow as follows
JSfiddle Demo
CSS
#main-menu {
width: 50px;
height: 100%;
top: 0;
z-index: 1000;
position: fixed;
background-color: pink;
}
#main-menu:after {
content:"";
position: absolute;
top:0;
left:100%;
height:100%;
width:5%;
background: linear-gradient(to bottom, rgba(0,0,0,0.15) 0%,rgba(0,0,0,0) 100%);
}
Related
I want to do this:
So far I got this:
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: #red;
z-index: 10000;
height: 10px;
overflow: visible;
}
.header:after {
content: '';
position: relative;
top: 100%;
display: block;
margin: 0 auto;
background: red;
width: 50px;
height: 25px;
border-radius: 10px 10px 50px 50px;
}
<div class="header"></div>
Codepen.
I can't get the top radius to go outwards the half circle like in the image.
How to do this with CSS?
You cannot make a negative radius on a border.
There is the possibility to make an SVG path or radial gradient... I made a new div as circle and radial gradient on pseudo-elements. It's not perfect, but it will possibly show you the direction to solution :)
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: red;
z-index: 10000;
height: 10px;
overflow: visible;
}
.header-circ {
position: relative;
top: 100%;
display: block;
margin: 0 auto;
background: red;
width: 500px;
height: 250px;
border-radius: 10px 10px 250px 250px;
}
.header-circ::before, .header-circ::after {
content: "";
position: absolute;
width: 100px;
height: 100px;
z-index: -1;
}
.header-circ::before {
left:-94px;
background: radial-gradient(circle at bottom left, white 0%,white 75%,red 75%);
}
.header-circ::after {
right:-94px;
background: radial-gradient(circle at bottom right, white 0%,white 75%,red 75%);
}
<div class="header"></div>
<div class="header-circ"></div>
Here's a quote from W3C on how transform establishes a new containing block:
For elements whose layout is governed by the CSS box model, any value
other than none for the transform property also causes the element to
establish a containing block for all descendants. Its padding box will
be used to layout for all of its absolute-position descendants,
fixed-position descendants, and descendant fixed background
attachments.
And here's their example code:
<style>
#container {
width: 300px;
height: 200px;
border: 5px dashed black;
padding: 5px;
overflow: scroll;
}
#bloat {
height: 1000px;
}
#child {
right: 0;
bottom: 0;
width: 10%;
height: 10%;
background: green;
}
</style>
<div id="container" style="transform:translateX(5px);">
<div id="bloat"></div>
<div id="child" style="position:fixed;"></div>
</div>
My problem is that the W3C example doesn't work as expected in Firefox. The green div doesn't stay fixed when I scroll — try running the snippet yourself.
My own example has exactly the same problem (the red divs don't stay fixed when I scroll):
.inner-container {
width: 72vw;
height: 72vh;
transform: translateZ(0);
overflow-y: scroll;
box-sizing: border-box;
border: 2px dashed black;
}
.fixed-top {
position: fixed;
height: 20%;
width: 100%;
left: 0;
top: 0;
background: red;
opacity: 0.5;
}
.fixed-bottom {
position: fixed;
height: 20%;
width: 100%;
left: 0;
bottom: 0;
background: red;
opacity: 0.5;
}
.content {
height: 88rem;
background: repeating-linear-gradient(0deg, #fff, #fff 1%, #e2e2e2 1%, #e2e2e2 3%);
}
<div class="inner-container">
<div class="fixed-top"></div>
<div class="content"></div>
<div class="fixed-bottom"></div>
</div>
I don't get it. According to the spec, descendants with position: fixed should not move if their parent has a transform applied, but they do! What gives?
The weird thing is that I can make it work by adding a second container and applying the transform to that instead (now my red divs don't move when I scroll, which is what I want):
.outer-container {
width: 72vw;
height: 72vh;
transform: translateZ(0);
}
.inner-container {
width: 100%;
height: 100%;
overflow-y: scroll;
box-sizing: border-box;
border: 2px dashed black;
}
.fixed-top {
position: fixed;
height: 20%;
width: 100%;
left: 0;
top: 0;
background: red;
opacity: 0.5;
}
.fixed-bottom {
position: fixed;
height: 20%;
width: 100%;
left: 0;
bottom: 0;
background: red;
opacity: 0.5;
}
.content {
height: 88rem;
background: repeating-linear-gradient(0deg, #fff, #fff 1%, #e2e2e2 1%, #e2e2e2 3%);
}
<div class="outer-container">
<div class="inner-container">
<div class="fixed-top"></div>
<div class="content"></div>
<div class="fixed-bottom"></div>
</div>
</div>
But I have no idea why I need to use two containers to make this work. According to the spec I should just be able to apply a transform to the first container, which is so much cleaner. Is this actually possible with one container? I don't have time to learn Kubernetes at the moment.
Here's a CodePen if you want to play with it.
Use position: sticky
There is a fantastic demo at https://developer.mozilla.org/en-US/docs/Web/CSS/position
.inner-container {
width: 72vw;
height: 72vh;
overflow-y: scroll;
box-sizing: border-box;
border: 2px dashed black;
position: relative;
}
.fixed-top {
position: sticky;
height: 20%;
width: 100%;
left: 0;
top: 0;
background: red;
opacity: 0.5;
}
.fixed-bottom {
position: sticky;
height: 20%;
width: 100%;
left: 0;
bottom: 0;
background: red;
opacity: 0.5;
}
.content {
height: 88rem;
background: repeating-linear-gradient( 0deg, #fff, #fff 1%, #e2e2e2 1%, #e2e2e2 3%);
}
<div class="inner-container">
<div class="fixed-top"></div>
<div class="content"></div>
<div class="fixed-bottom"></div>
</div>
I am trying to do the following:
- add a left background, 50% width (color red).
- add a right background, 50% width (color green).
- add a centered layer for content (had to wrap it with another layer).
(wrapper blue, content white).
I'll change the backgrounds later, but I need a 50-50 split background with a different background image on each side and with a centered layer covering on top of that.
Any improvments or suggestions? :)
Code below:
/* By forcing `height: 100%` in the html
and body tag will make sure there are no white areas
in vicinity (this is optional though, use it only if you need it */
html, body {height: 100%;}
/* -------------------------------------------- */
div
{
border: 1px solid black;
}
div#wd_bg_left
{
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 50%;
background-color: red;
z-index: 1;
}
div#wd_bg_right
{
position: absolute;
top: 0;
bottom: 0;
right: 0;
width: 50%;
background-color: green;
z-index: 1;
}
div#wd_wrapper_1
{
position: absolute;
top: 0;
bottom: 0;
left: 5%;
right: 5%;
background-color: blue;
z-index: 2;
}
div#wd_wrapper_2
{
margin: 5px auto 5px auto;
min-height: 99%;
background-color: white;
width: 1000px;
}
<div id="wd_bg_left"></div>
<div id="wd_bg_right"></div>
<div id="wd_wrapper_1">
<div id="wd_wrapper_2"></div>
</div>
A simple linear gradient would suffice if color is all you need.
html, body {
height:100%;
margin:0;
}
body {
min-height:100%;
background:linear-gradient(to right, red, red 50%, blue 50%);
}
.container {
height:100%;
width:50%; /* your width here */
margin:auto;
border:1px solid green;
}
<div class="container"></div>
Or a couple of pseudo-elements if you want background images
html,
body {
height: 100%;
margin: 0;
}
body {
min-height: 100%;
overflow: hidden;
}
.container {
height: 100%;
width: 50%;
/* your width here */
margin: auto;
border: 1px solid green;
position: relative;
}
.container::before,
.container::after {
content: '';
position: absolute;
top: 0;
height: 100%;
width: 50vw;
z-index: -1;
}
.container::before {
/* rightside */
background: #f00; /* use bg image here */
left: 50%;
}
.container::after {
/* leftside */
background: #0f0; /* use bg image here */
right: 50%;
}
<div class="container"></div>
Try this:
#wd-bg-right {
width:50vw;
Height: 100vh; /* just for demonstrating*/
Background-color: red;
Right: 0;
}
wd
-bg-right {
width:50vw;
Height: 100vh; /* just for demonstrating*/
Background-color: red;
Right: 0;
}
Hope it helps you, cheers!
The code below will create an arrow right below an <a> element:
JSFiddle
.btn {
position: relative;
display: inline-block;
width: 100px;
height: 50px;
text-align: center;
color: white;
background: gray;
line-height: 50px;
text-decoration: none;
}
.btn:after {
content: "";
position: absolute;
bottom: -10px;
left: 0;
width: 0;
height: 0;
border-width: 10px 50px 0 50px;
border-style: solid;
border-color: gray transparent transparent transparent;
}
Hello!
The problem is that we have to indicate the link width to get an arrow of a proper size because we cannot indicate the border width in pixels.
How to make a responsive triangle percent based?
You could use a skewed and rotated pseudo element to create a responsive triangle under the link :
DEMO (resize the result window to see how it reacts)
The triangle maintains it's aspect ratio with the padding-bottom property.
If you want the shape to adapt it's size according to it's content, you can remove the width on the .btn class
.btn {
position: relative;
display: inline-block;
height: 50px; width: 50%;
text-align: center;
color: white;
background: gray;
line-height: 50px;
text-decoration: none;
padding-bottom: 15%;
background-clip: content-box;
overflow: hidden;
}
.btn:after {
content: "";
position: absolute;
top:50px; left: 0;
background-color: inherit;
padding-bottom: 50%;
width: 57.7%;
z-index: -1;
transform-origin: 0 0;
transform: rotate(-30deg) skewX(30deg);
}
/** FOR THE DEMO **/
body {
background: url('http://i.imgur.com/qi5FGET.jpg');
background-size: cover;
}
Hello!
For more info on responsive triangles and how to make them, you can have a look at
Triangles with transform rotate (simple and fancy responsive triangles)
Another solution to this would be to use a CSS clip-path to clip a triangle out of a coloured block. No IE support however, but could be used for internal tools etc.
DEMO
Written with SCSS for ease.
.outer {
background: orange;
width: 25%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 1em;
p {
margin: 0;
text-align: center;
color: #fff;
}
&:after {
content: '';
position: absolute;
top: 100%;
left: 0;
right: 0;
padding-bottom: 10%;
background: orange;
-webkit-clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
}
}
I found solution that works with any width/height. You can use two pseudo-elements with linear-gradient background, like this, (fiddle):
.btn {
position: relative;
display: inline-block;
width: 100px;
height: 50px;
text-align: center;
color: white;
background: gray;
line-height: 50px;
text-decoration: none;
}
.btn:before {
content: "";
position: absolute;
top: 100%;
right: 0;
width: 50%;
height: 10px;
background: linear-gradient(to right bottom, gray 50%, transparent 50%)
}
.btn:after {
content: "";
position: absolute;
top: 100%;
left: 0;
width: 50%;
height: 10px;
background: linear-gradient(to left bottom, gray 50%, transparent 50%)
}
A modified version of the below code can help you to achieve this
HTML
<div class="triangle-down"></div>
CSS
.triangle-down {
width: 10%;
height: 0;
padding-left:10%;
padding-top: 10%;
overflow: hidden;
}
.triangle-down:after {
content: "";
display: block;
width: 0;
height: 0;
margin-left:-500px;
margin-top:-500px;
border-left: 500px solid transparent;
border-right: 500px solid transparent;
border-top: 500px solid #4679BD;
}
For further reading on responsive triangles: CSS triangles made responsive
(archived link)
I tried the other answers and found them to be either too complex and/or unwieldy to manipulate the shape of the triangle. I decided instead to create a simple triangle shape as an svg.
The triangle height can be set to an absolute value, or as a percentage of the rectangle so it can be responsive in both directions if necessary.
html, body{
height:100%;
width:100%;
}
.outer{
width:20%;
height:25%;
background:red;
position:relative;
}
.inner{
height:100%;
width:100%;
background-color:red;
}
.triangle-down{
height:25%;
width:100%;
position:relative;
}
.triangle-down svg{
height:100%;
width:100%;
position:absolute;
top:0;
}
svg .triangle-path{
fill:red;
}
<div class="outer">
<div class="inner"></div>
<div class="triangle-down">
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" viewBox="0 0 2 1">
<g>
<path class="triangle-path" d="M0,0 l2,0 l-1,1 z" />
</g>
</svg>
</div>
Tested FF, Chrome, IE, Edge, mob Safari and mob Chrome
Another option would be to use background liner gradients, and flex positioning to make sure that the triangle always scales to its parent container. No matter how wide or narrow you make that container, the triangle always scales with it. Here is the fiddle:
https://jsfiddle.net/29k4ngzr/
<div class="triangle-wrapper-100">
<div class="triangle-left"></div>
<div class="triangle-right"></div>
</div>
.triangle-wrapper-100 {
width: 100%;
height: 100px;
display:flex;
flex-direction: column;
flex-wrap: wrap;
}
.triangle-right {
right: 0px;
background: linear-gradient(to right bottom, #6940B5 50%, transparent 50%);
width: 50%;
height: 100px;
}
.triangle-left {
left: 0px;
background: linear-gradient(to right bottom, #6940B5 50%, transparent 50%);
width: 50%;
height: 100px;
transform: scaleX(-1);
}
I took #Probocop's answer and come up with the following:
<style>
.btn {
background-color: orange;
color: white;
margin-bottom: 50px;
padding: 15px;
position: relative;
text-align: center;
text-decoration: none;
}
.btn:after {
background-color: inherit;
clip-path: url('data:image/svg+xml;utf8,%3Csvg xmlns="http://www.w3.org/2000/svg"%3E%3Cdefs%3E%3CclipPath id="p" clipPathUnits="objectBoundingBox"%3E%3Cpolygon points="0 0, 1 0, 0.5 1" /%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E#p'); /* fix for firefox (tested in version 52) */
clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
content: '';
height: 50px;
left: 0;
position: absolute;
right: 0;
top: 100%;
}
</style>
Hello!
This works in Chrome and I've added a fix for Firefox. It doesn't work in Edge, however if you decrease the height of the down arrow then it doesn't look so bad.
Please note that if you are using bootstrap you will need to either change the name or override some of the styles it applies. If you decide to rename it then you also need to add the following to the .btn style:
box-sizing: content-box;
I am trying to apply a simple css3 animation, and apply opacity to the background image when the text jumps but it effect the whole div's.
Here is the jsfiddle link
And this is the main wrapper div:
.movie_thumb_wrapper {
float: left;
line-height: 31px;
background-color: #424755;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
overflow: hidden;
height: 140px;
width: 220px;
background-size: 220px 140px;
background-repeat: no-repeat;
background-color:#1a1c26;
}
A slightly different approach from Vitorino Fernandes' answer would be to 'nest' a pseudo element between the text and background:
div {
position: relative;
height: 300px;
width: 300px;
display: inline-block;
color:white;
}
div:before,
div:after {
content: "";
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
transition:all 0.8s;
}
div:before {
background: rgba(0, 0, 0, 0); /*this changes on hover - you might just want to change it here to get rid of the hover altogether*/
z-index: -1;
}
div:after {
z-index: -2;
background: url(http://placekitten.com/g/300/300);
}
div:hover:before{
background: rgba(0, 0, 0, 0.6);
}
<div>Hover to see effect</div>
So, in terms of your fiddle, add:
.movie_thumb_wrapper{
position:relative;
}
.movie_thumb_wrapper:after {
content: "";
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
transition:all 0.8s;
background:rgba(0,0,0,0.6);
z-index:-2;
}
jsfiddle example
Short answer, you can't. you need to create layers, using CSS position absolute, and z-index, so the text sits "on top of" the semi transparent layer. (instead of "inside" it as a a child element)
You can use pseudo element :after
div {
width: 200px;
position: relative;
border-radius: 5px;
text-align: center;
}
div:after {
content: '';
position: absolute;
top: 0;
left: 0;
opacity: .7;
right: 0;
bottom: 0;
z-index: -1; /* so that it goes in the backward */
background: url('http://placeimg.com/200/480/any')
}
<div>
<h1>Check my background image</h1>
</div>
instead of hex color code specify rgba and adjust a as required
background-color:rgba(255,0,0,0.5);
reference
Uhm,
background: rgba(0, 0, 0, 0.75);
does the job!