CSS-only ribbon with skewed bottom corner - html

What i'm trying to achieve is to create a purely-CSS ribbon which will:
adapt to the included text (working),
floated to the left of container (working),
have a skewed bottom right corner like on below img:
This is my code - HTML:
<div class="container">
<div class="ribbon left_ribbon"><h2>Testing</h2></div>
</div>
and CSS:
.container {
width:80%;
background:grey;
display:block;
min-height:500px;
margin:0 auto;
}
.ribbon{
color: #fff;
margin: 30px 0 50px;
position: relative;
text-transform: uppercase;
background: rgb(0, 164, 239);
box-shadow: 0px 1px 3px rgba(0,0,0,.2);
padding: 10px 15px;
clear: both;
}
div.left_ribbon{
color: #000;
margin-left: -10px;
float: left;
}
div.left_ribbon h2{
margin: 0 12px;
color:#fff;
}
div.left_ribbon::before{
display: block;
width: 10px;
height: 0px;
position: absolute;
bottom: -10px;
left: -10px;
content: "";
border-bottom: 10px solid transparent;
border-right: 10px solid rgb(0, 80, 116);
}
is it doable via CSS or I have to use SVG file?

clip-path can do it easily:
.box {
width:200px;
height:100px;
margin:50px;
position:relative;
background:grey;
}
.box:before {
content:"Ribbon";
font-size:25px;
padding:5px 25px 10px;
position:absolute;
top:10px;
left:-5px;
background:
linear-gradient(#000 0 0) bottom/100% 5px no-repeat
#00a4ef;
clip-path:polygon(0 0,100% 0,80% calc(100% - 5px),5px calc(100% - 5px),5px 100%,0 calc(100% - 5px))
}
<div class="box">
</div>
With some CSS variables to easily control:
.box {
--s:10px; /* skewed part */
--o:5px; /* offset part */
--c:#00a4ef; /* color */
width:200px;
height:100px;
display:inline-block;
margin:5px;
position:relative;
background:grey;
}
.box:before {
content:attr(data-text);
font-size:25px;
padding:5px calc(10px + var(--s)) calc(5px + var(--o)) calc(10px + var(--o));
position:absolute;
top:10px;
left:calc(-1*var(--o));
background:
linear-gradient(#000 0 0) bottom/100% var(--o) no-repeat
var(--c);
clip-path:polygon(0 0,100% 0,calc(100% - var(--s)) calc(100% - var(--o)),var(--o) calc(100% - var(--o)),var(--o) 100%,0 calc(100% - var(--o)))
}
<div class="box" data-text="test"></div>
<div class="box" data-text="another test" style="--c:red;--o:10px;--s:25px"></div>
<div class="box" data-text="another one" style="--c:yellow;--o:0px;--s:40px"></div>

Please modify your CSS as below. pseudo after CSS added making it skewed form bottom right corner and, modified box-shadow from .ribbon for removing visible shadow of skewed area.
.container {
width:80%;
background:grey;
display:block;
min-height:500px;
margin:0 auto;
}
.ribbon{
color: #fff;
margin: 30px 0 50px;
position: relative;
text-transform: uppercase;
background: rgb(0, 164, 239);
box-shadow: 0px 1px 3px rgb(0 0 0 / 0%);
padding: 10px 15px;
clear: both;
}
div.left_ribbon{
color: #000;
margin-left: -10px;
float: left;
}
div.left_ribbon h2{
margin: 0 12px;
color:#fff;
}
div.left_ribbon::before{
display: block;
width: 10px;
height: 0px;
position: absolute;
bottom: -10px;
left: -10px;
content: "";
border-bottom: 10px solid transparent;
border-right: 10px solid rgb(0, 80, 116);
}
div.left_ribbon::after{
content: '';
position: absolute;
top: 0;
right: 0;
border-bottom: 47px solid grey;
border-left: 23px solid rgb(0, 164, 239);
width: 0;
}
<div class="container">
<div class="ribbon left_ribbon"><h2>Testing</h2></div>
</div>

Related

Border behind Button slight below position CSS

I m trying to implement below button CSS, I tried to used box-shadow as well psuedo code i.e before after still not getting the output I wanted.
the button that I wanted:
my code:
.et_pb_button {
background-color: #f16922!important;
width: 65%;
outline: 3px solid #f16922;
outline-offset: 10px;
text-transform: uppercase;
font-size: 14px!important;
}
Button
Please see below snippet:
button {
position: relative;
display: inline-block;
vertical-align: top;
background-color: blue;
color: #fff;
border-radius: none;
text-transform: uppercase;
border: none;
padding: 10px 12px;
}
button::after {
content: '';
position: absolute;
top: 5px;
left: -5px;
right: -5px;
bottom: -5px;
border: 1px solid red;
display: block;
z-index: -1;
}
<button>View Project</button>
.btngroup button{
background-color: rgb(29, 174, 236);
border: 0;
padding: 10px 15px;
font-size: 15px;
color: white;
width: 150px;
height: 50px;
text-transform: uppercase
}
.btngroup .drop{
width: 165px;
height: 50px;
border: 1.5px solid red;
margin-top: -42.5px;
}
<center>
<div class="btngroup">
<button>view project</button>
<div class="drop"></div>
</div>
</center>
Here is an idea with one element and multiple background and border-image:
.button {
display:inline-block;
padding:10px 60px 20px;
margin:10px;
color:#fff;
border:2px solid transparent;
border-image:linear-gradient(to bottom,transparent 10px,red 0) 2;
background:
linear-gradient(blue,blue) top center/calc(100% - 20px) calc(100% - 10px),
linear-gradient(red,red) 0 8px /100% 2px;
background-repeat:no-repeat;
}
<span class="button">Button</span>
And with CSS variable to easily control the whole shape:
.button {
--t:10px; /* Distance of the border from the top*/
--p:10px; /* Distance between the border and background*/
--b:2; /* Thickness of the border (unitless to be used with slice)*/
--c:red; /* border color*/
display:inline-block;
padding:var(--p) 60px calc(2*var(--p));
margin:10px;
color:#fff;
border:calc(1px*var(--b)) solid transparent;
border-image:linear-gradient(to bottom,transparent var(--t),var(--c) 0) var(--b);
background:
linear-gradient(blue,blue) top center/calc(100% - 2*var(--p)) calc(100% - var(--p)),
linear-gradient(var(--c),var(--c)) 0 calc(var(--t) - 1px*var(--b))/100% calc(1px*var(--b));
background-repeat:no-repeat;
}
<span class="button">Button</span>
<span class="button" style="--c:green;--t:15px;--p:8px;--b:3;">Button</span>
<span class="button" style="--c:#000;--t:25px;--p:15px;--b:1;">Button</span>
Here's an alternative based on Hanif's suggestion, which uses both pseudo-elements instead of one with a negative z-index. For some backgrounds (e.g. an image or gradient), it might be necessary to adjust the background-position for the ::after
button {
position: relative;
display: inline-block;
vertical-align: top;
background-color: blue;
color: #fff;
border-radius: none;
text-transform: uppercase;
border: none;
padding: 10px 12px;
}
button::before {
content: '';
position: absolute;
top: 5px;
left: -5px;
right: -5px;
bottom: -5px;
border: 1px solid red;
display: block;
}
button::after {
content: '';
position: absolute;
top: 5px;
left: 0;
right: 0;
height: 1px;
background: inherit;
display: block;
}
<button>View Project</button>

How can I space three dots uniformly as a skinny hamburger menu icon?

I want the code to show up the 3 bars, and the 3 dots to eventually be dropdown options. For some reason the 1st out of the 3 dots does not want to be spaced correctly.
#dropdown {
background: #3f51b5;
padding: 30px;
margin: 0px;
}
#dot {
width: 5px;
height: 5px;
background: white;
border-radius: 50%;
float: right;
}
#bar {
width: 25px;
height: 3px;
background: white;
margin: 5px;
}
<div id="dropdown">
<div id="dot"></div>
<div id="bar"></div>
<div id="dot"></div>
<div id="bar"></div>
<div id="dot"></div>
<div id="bar"></div>
</div>
Picture of what is returned:
This is a hard thing to do with floats.
A possible solution could be to wrap the dots and the bars within a div.
Afterwards you can position those wrapping divs in the style you like.
I used flexbox for this in the following snippet.
#dropdown {
display: flex;
justify-content: space-between;
align-items: center;
background: #3f51b5;
padding: 30px;
margin: 0px;
}
.dot {
width: 5px;
height: 5px;
margin: 5px;
background: white;
border-radius: 50%;
}
.bar {
width: 25px;
height: 3px;
background: white;
margin: 5px;
}
<div id="dropdown">
<div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
</div>
<div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
</div>
p.s.: you should use the keyword class instead of id for repeating elements. This might still work, but is considered bad practice and might break javascript implementations using that id.
You can easily do this with one element for each:
#dropdown {
background: #3f51b5;
padding: 10px 50px;
overflow:hidden;
}
#dot {
width: 10px;
height: 30px;
background:
radial-gradient(5px 5px at center, white 57%, transparent 61%) top/10px 10px;
float: right;
}
#bar {
width: 25px;
height: 22px;
margin: 4px 0;
background:
linear-gradient(#fff,#fff) top/100% 3px,
linear-gradient(#fff,#fff) center/100% 3px,
linear-gradient(#fff,#fff) bottom/100% 3px;
background-repeat:no-repeat;
float:left;
}
<div id="dropdown">
<div id="bar"></div>
<div id="dot"></div>
</div>
Here is another idea:
#dropdown {
background: #3f51b5;
padding: 10px 50px;
overflow:hidden;
}
#dot {
width: 5px;
height: 5px;
background:#fff;
box-shadow:
0 10px 0 #fff,
0 20px 0 #fff;
border-radius:50%;
float: right;
}
#bar {
width: 25px;
height: 23px;
padding:7px 0;
margin: 4px 0;
border-top:3px solid #fff;
border-bottom:3px solid #fff;
background:#fff content-box;
float:left;
box-sizing:border-box;
}
<div id="dropdown">
<div id="bar"></div>
<div id="dot"></div>
</div>
Also like this with pseudo element:
#dropdown {
background: #3f51b5;
padding: 10px 50px;
overflow:hidden;
}
#dot {
width: 5px;
height: 5px;
margin: 15px 0;
background:#fff;
border-radius:50%;
float: right;
position:relative;
}
#dot:before,
#dot:after{
content:"";
position:absolute;
height:inherit;
width:100%;
left:0;
background:inherit;
border-radius:inherit;
top:-8px;
}
#dot:after {
bottom:-8px;
top:auto;
}
#bar {
width: 25px;
height: 3px;
margin: 15px 0;
background:#fff;
float:left;
box-sizing:border-box;
position:relative;
}
#bar:before,
#bar:after{
content:"";
position:absolute;
height:inherit;
width:100%;
left:0;
background:inherit;
top:-8px;
}
#bar:after {
bottom:-8px;
top:auto;
}
<div id="dropdown">
<div id="bar"></div>
<div id="dot"></div>
</div>
Use something like if you want to check for first specific dot
#dropdown div:first-child {
position:relative;
top:4px
}

How to make a border overlay child div?

I have to make a border overlay it's content to match the looking of this image:
And I got the big picture of it:
And I need to make that border overlay the green content. How can I accomplish it? I can't use z-index for this, as I researched. The HTML and CSS code follows:
.box-border a {
color: white;
text-transform: uppercase;
font-weight: bold;
font-size: 16px;
}
.box-border a:hover {
text-decoration: none;
color: white;
cursor: pointer;
}
.box-border-participe {
position: relative;
float: right;
margin-right: 30%;
border: 4px solid white;
}
.box-participe {
background-color: #94C120;
padding: 10px 40px;
margin-left: 5px;
margin-top: 5px;
margin-bottom: -20px;
margin-right: -20px;
}
body {
background:grey;
}
<div class="box-border box-border-participe">
<div class="box-participe">
<a>Participe</a>
</div>
</div>
You can consider the use of pseudo element to create the border and avoid extra markup. You can also easily control its position/size:
body {
background: grey;
}
.button {
background: #94c120;
width: 200px;
height: 50px;
margin: 50px;
position: relative;
}
.button:before {
content: "";
position: absolute;
top: -15px;
left: -15px;
width: 100%;
height: 100%;
border: 5px solid #fff;
box-sizing: border-box;
}
<div class="button">
some text
</div>
Here is also another idea using linear-gradient and multiple background:
body {
background:grey;
}
.button {
width: 200px;
height: 80px;
margin: 50px;
padding:20px 0 0 20px;
box-sizing:border-box;
background:
linear-gradient(to right,#fff 5px,transparent 5px calc(100% - 5px),#fff calc(100% - 5px)) 0 0/ calc(100% - 10px) calc(100% - 10px),
linear-gradient(to bottom,#fff 5px,transparent 5px calc(100% - 5px),#fff calc(100% - 5px)) 0 0/ calc(100% - 10px) calc(100% - 10px),
linear-gradient(#94c120,#94c120) 15px 15px;
background-repeat:no-repeat;
}
<div class="button">
some text
</div>
Another syntax with gradient:
body {
background:grey;
}
.button {
width: 200px;
height: 80px;
margin: 50px;
padding:20px 0 0 20px;
box-sizing:border-box;
background:
linear-gradient(#fff,#fff) left -10px top 0 /100% 5px,
linear-gradient(#fff,#fff) top -10px left 0 /5px 100%,
linear-gradient(#fff,#fff) left -10px bottom 10px/100% 5px,
linear-gradient(#fff,#fff) top -10px right 10px/5px 100%,
linear-gradient(#94c120,#94c120) 20px 20px;
background-repeat:no-repeat;
}
<div class="button">
some text
</div>
Another idea using background and box-shadow:
body {
background:grey;
}
.button {
width: 200px;
height: 80px;
margin: 50px;
padding:15px 0 0 15px;
box-sizing:border-box;
background: #94c120 content-box;
border:5px solid #fff;
box-shadow: 20px 20px 0px #94c120; /* value of padding + border*/
}
<div class="button">
some text
</div>

Only show box-shadow on part of a side

So I have a header that is shown in the snippet below.
My problem is I only want the shadow around the a tag to show on the part that has expanded out of its container div, to create the impression that the white edge is all one element.
Basically I only want the shadow on the left and on the right to go from the bottom of the a element to the bottom of the div. While also showing on the bottom of the a element.
Screenshot of what I'm after in case my descriptive capabilities are not functioning:
I've tried playing with z-index but haven't been able to get it to work.
My thought with z-index was to push the a behind the div, then pull the img in front of all.
I would prefer a CSS-only solution, as I don't want to have to modify the html, but if I have to I have to.
* {
padding: 0;
margin: 0;
}
div {
height: 50px;
width: 100%;
background: white;
box-shadow: 0px 0px 5px #000000;
}
a {
display: inline-block;
margin-left: 30px;
padding: 10px;
height: 60px;
background: white;
box-shadow: 0px 0px 5px #000000;
}
img {
height: 100%;
}
<div>
<a href="#">
<img src="https://via.placeholder.com/200x100">
</a>
</div>
Here is box-shadow syntax,
box-shadow: offset-x | offset-y | blur-radius | spread-radius | color
Try reducing it's spread-radius and increase it shadow towards y-axis.
* {
padding: 0;
margin: 0;
}
div {
height: 50px;
width: 100%;
background: white;
box-shadow: 0px 0px 5px #000000;
}
a {
display: inline-block;
margin-left: 30px;
padding: 10px;
height: 60px;
background: white;
position: relative;
}
a:before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
box-shadow: 0px 0px 5px #000000;
z-index: -1;
}
img {
height: 100%;
}
<div>
<a href="#">
<img src="https://via.placeholder.com/200x100">
</a>
</div>
EDIT:-
Using jquery you can compute the css for span dynamically. Check this.
Html modified, added a <span> below anchor tag and added shadow to the span
* {
padding: 0;
margin: 0;
}
div {
height: 50px;
width: 100%;
background: white;
box-shadow: 0px 0px 5px #000000;
}
a {
display: inline-block;
margin-left: 30px;
padding: 10px;
height: 60px;
background: white;
/*box-shadow: 0px 0px 5px #000000;*/
z-index:100;
position:absolute;
}
.shadow {
display: inline-block;
margin-left: 30px;
padding: 10px;
margin-top:50px;
height: 10px;
width:120px;
background: white;
box-shadow: 0px 0px 5px #000000;
z-index:0;
position:absolute;
}
img {
height: 100%;
}
<div>
<a href="#">
<img src="https://via.placeholder.com/200x100">
</a>
<span class="shadow">r
</span>
</div>
You can get it by css pseudo element.
Just add css part
a:after {
content:'';
position:absolute;
bottom:0px;
left:0px;
height:20px;
display:block;
width:100%;
box-shadow:5px 5px 5px -5px #000000;
}
a:before {
content:'';
position:absolute;
bottom:0px;
left:0px;
height:20px;
display:block;
width:100%;
box-shadow:-5px 5px 5px -5px #000000;
}
* {
padding: 0;
margin: 0;
box-sizing:border-box;
}
div {
height: 50px;
width: 100%;
background: white;
box-shadow: 0px 0px 5px #000000;
}
a {
display: inline-block;
margin-left: 30px;
padding: 10px;
height: 60px;
background: white;
position:relative;
/* box-shadow:0px 5px 5px -5px #000000; */
}
a:after {
content:'';
position:absolute;
bottom:0px;
left:0px;
height:20px;
display:block;
width:100%;
box-shadow:5px 5px 5px -5px #000000;
}
a:before {
content:'';
position:absolute;
bottom:0px;
left:0px;
height:20px;
display:block;
width:100%;
box-shadow:-5px 5px 5px -5px #000000;
}
img {
height: 100%;
}
<div>
<a href="#">
<img src="https://via.placeholder.com/200x100">
</a>
</div>

How can I use css to make this?

I suspect using line gradient?I know how to do the ellipse thing but I just don't understand how I can make the red line right through the middle?
I would make something like this: DEMO FIDDLE
CSS:
#container {
position: relative;
width: 200px;
background-color:black;
z-index:-2;
padding: 10px 0;
text-align:center;
}
#line {
position: absolute;
top: 50%;
width: 80%;
left:10%;
height: 1px;
box-shadow: 1px 1px 20px 5px red;
z-index:-1;
background-color: red;
}
#text{
color:white;
font-weight:bold;
text-transform:uppercase;
letter-spacing:8px;
text-shadow: 1px 1px 1px #ccc
}
HTML:
<div id="container">
<div id="text">Text</div>
<div id="line"></div>
</div>