How to create a custom border with a gap? - css

I need to create a top border around a top that leaves a partial gap. Something such as:
____________________________ (gap) __________________________
| |
| |
The gap I'm trying to create is on the TOP (ignore the ones on the side, that's just to emphasize it's a div). The gap may or may not be perfectly centered -- in other words, it may vary where the gap exists.
Is it possible to do this with css?

You can use a pseudo element absolutely positioned in your container with a background color that matches whatever the background of your page is.
div {
height: 100px;
border: 1px solid black;
position: relative;
}
div:after {
position: absolute;
top: -1px; left: 50%;
transform: translateX(-50%);
content: '';
background: #fff;
width: 100px;
height: 1px;
}
<div></div>

The accepted answer has one flaw, if one want the gap to be "transparent" on top of its background, it won't work if the background is not a solid color.
So to do it on any background, like images, gradient etc., use both pseudo elements, like this:
By altering each pseudo element's width one control both where the gap will be, and its size.
body {
background-image: linear-gradient(to right, orange , yellow);
}
div {
position: relative;
width: 80%;
left: 10%;
top: 45vh;
transform: translateY(-50%);
height: 80px;
border: 1px solid black;
border-top: none;
}
div::before, div::after {
content: '';
position: absolute;
top: 0;
height: 1px;
background: black;
}
div::before {
left: 0;
width: 20%;
}
div::after {
right: 0;
width: 60%;
}
<div>
</div>
And for anyone who need at text in the gap, here's how-to.
body {
background-image: linear-gradient(to right, orange , yellow);
}
div {
position: relative;
width: 80%;
left: 10%;
top: 45vh;
transform: translateY(-50%);
height: 80px;
border: 1px solid black;
border-top: none;
}
div::before, div::after {
content: '';
position: absolute;
top: 0;
height: 1px;
background: black;
}
div::before {
left: 0;
width: 20%;
}
div::after {
right: 0;
width: 60%;
}
div span {
position: absolute;
top: 0;
transform: translateY(-50%);
text-align: center;
}
div span {
left: 20%;
}
div span {
right: 60%;
}
<div><span>Hello</span></div>

Related

Do not rotate label in before

I have before like below and I want rotate just background not label.
How I can do it ?
div {
width: 50px;
height: 5px;
position: relative;
background: #ff756b;
margin-top: 55px;
}
div::before {
content: 'lable';
position: absolute;
left: -5px;
top: -33px;
background: red;
color: white;
border-radius: 20px 20px 3px 20px;
transform: rotate(45deg);
width: 22px;
height: 22px;
}
<div></div>
You can add :after with div and add content
div {
width: 50px;
height: 5px;
position: relative;
background: #ff756b;
margin-top: 55px;
}
div:after {
content: 'Lable';
font-size: 11px;
position: absolute;
left: -5px;
top: -29px;
color: #fff;
}
div::before {
content: '';
position: absolute;
left: -5px;
top: -33px;
background: red;
color: white;
border-radius: 20px 20px 3px 20px;
transform: rotate(45deg);
width: 22px;
height: 22px;
}
<div></div>
transform: rotate (45deg);
Will rotate the complete element, including content and background.
If you want to rotate only the background then you need to keep the background separate or you can add your label in actual element instead of pseudo-element.
You can put the text into an after pseudo element which is not rotated.
div {
width: 50px;
height: 5px;
position: relative;
background: #ff756b;
margin-top: 55px;
}
div::before,
div::after {
position: absolute;
left: -5px;
top: -33px;
width: 22px;
height: 22px;
}
div::before {
content: '';
background: red;
border-radius: 20px 20px 3px 20px;
transform: rotate(45deg);
}
div::after {
content: 'lable';
color: white;
}
<div></div>
However, be aware of accessibility issues. That text may not get read out by a screen reader and if it is important for the user to know it is there is may be better to put the text in a label element actually within the HTML. You can still style it the same way so it is within the red 'bubble'.

Creating a curved shadow with a color gradient

Here is a shadow that I am trying to replicate using just CSS and I just cannot work out how to do it. I have spent hours trying. I think I need to create 2 shadow elements but I'm not sure how to proceed.
The closest thing I get is with this (an abysmal attempt - I know):
.type-product:before, .type-product:after{
z-index: -1;
position: absolute;
content: "";
bottom: 25px;
left: 21px;
width: 50%;
top: 80%;
max-width:300px;
background: #777;
box-shadow: 0 35px 20px #777;
transform: rotate(-8deg);
}
.type-product:after{
transform: rotate(8deg);
right: 20px;
left: auto;
}
Most appreciative if any CSS gurus could provide any help.
NOTE: I don't think that this link covers my problem fully. It just discusses the curve - whilst I need a curve with a color-gradient...
To me that looks like something that can be achieved using a couple of elements like shown below. The shadow is actually a linear-gradient on top of which a white circle is placed. The drawback of this approach is that it would work only with a solid background (because the circle that is overlayed would need a solid color).
That just doesn't look like it could be possible using a box-shadow because the shadow itself seems like a gradient which goes from transparent or white on the left to black in the middle to transparent or white again on the right.
The output is responsive and can adapt itself to all dimensions of the parent container. Just :hover the container in the snippet to see it in action :)
.wrapper {
position: relative;
height: 200px;
width: 200px;
overflow: hidden;
}
.content {
height: 85%;
width: 100%;
border: 1px solid;
}
.wrapper:before {
position: absolute;
content: '';
bottom: 0px;
left: 0px;
height: 15%;
width: 100%;
background: linear-gradient(to right, transparent 2%, #444, transparent 98%);
}
.wrapper:after {
position: absolute;
content: '';
bottom: -186%;
/* height of before - height of after - 1% buffer for the small gap */
left: -50%;
height: 200%;
width: 200%;
border-radius: 50%;
background: white;
}
* {
box-sizing: border-box;
}
/* just for demo */
.wrapper {
transition: all 1s;
}
.wrapper:hover {
height: 300px;
width: 400px;
}
<div class='wrapper'>
<div class='content'></div>
</div>
You can do this with :before pseudo element and box-shadow
div {
width: 200px;
height: 100px;
border: 1px solid #aaa;
position: relative;
background: white;
}
div:before {
content: '';
border-radius: 50%;
height: 100%;
width: 100%;
position: absolute;
z-index: -1;
left: 0;
transform: translateY(103%);
box-shadow: 0px -54px 13px -47px #000000, -4px -45px 35px -28px #999999;
}
<div></div>
Aside from the answers, this could also be a good box shadow for your class as well. (This is just preference & similar to what you want).
.box {
width: 70%;
height: 200px;
background: #FFF;
margin: 40px auto;
}
.type-product {
position: relative;
}
.type-product:before {
z-index: -1;
position: absolute;
content: "";
bottom: 17px;
left: 10px;
width: 50%;
top: 70%;
max-width: 300px;
background: #777;
box-shadow: 0 18px 20px #777;
transform: rotate(-8deg);
}
.type-product:after {
z-index: -1;
position: absolute;
content: "";
bottom: 17px;
right: 10px;
width: 50%;
top: 80%;
max-width: 300px;
background: #777;
box-shadow: 0 18px 20px #777;
transform: rotate(8deg);
}
<div class="type-product box">
</div>
Hope you like it.

Positioning element in the middle of dynamically sized element

I have to put "Play" icon and text "Play" in the center of element that contains and its height and width depend of that image - they are changing depending of the user's screen.
I was trying to use it like this
a.thumbnail:hover:after
{
content: "Play";
width: 50px;
height: 20px;
display: inline-block;
position: absolute;
top:50%;
left: 50%;
background-color: #fff;
border: 1px solid red;
}
But actually the top left corner of the :before element is in the middle and looks displaced... can you suggest me better solution?
add this to the code
margin: -10px -25px; /** height/2 width/2 **/
or use translate the same way
div{
position: relative;
width: 200px;
height: 200px;
background: red;
margin: 20px auto
}
div:after{
content: '';
position: absolute;
width: 50px;
height: 20px;
z-index: 2;
top: 50%;
left: 50%;
background: green;
transform: translate( -50%, -50%)
}
<div><div/>

Center a absolute positioned div vertical?

I have this:
.ce_text.forward {
position: relative;
overflow: hidden;
padding: 20px;
background-color: #F8F8F8;
color: #2d353c;
}
.ce_text.forward p {
position: relative;
}
.ce_text.forward .fill_bottom {
width: 500px;
height: 500px;
bottom: 0;
left: -865px;
position: absolute;
margin: auto;
background-color: #ecedee;
top: 0px;
right: 0;
transition: left 0.3s linear 0s;
transform: rotate(45deg);
}
.ce_text.forward:hover .fill_bottom {
left: 0;
}
<div class="ce_text forward block"><div class="fill_bottom"></div>
<p><strong>Headline</strong>Test Test test test<span>Lesen Sie mehr</span></p>
</div>
It works in chrome but not in firefox, can some one help me with the css?
Fiddle
The problem in Firefox seems to be caused by the usage of margin: auto. I have completely re-built your example to eliminate this.
New and Improved
No fixed height. Height is controlled by a percentage (which can be modified) and a min-height.
No extra markup. The triangle is created with a pseudo element and rotated. The text is centered with its <a> wrapper.
Centered triangle. The triangle is centered at any height with bottom: 50% and a negative bottom margin of half its height.
No gaps - The triangle is large enough to eliminate any spacing in the corners. If you need it to be even larger, it can be as large as required; just keep the height to width ratio 1:1 and increase the size of the negative bottom margin.
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
h1 {
background: #333;
height: 40%;
min-height: 140px;
position: relative;
overflow: hidden;
z-index: 0;
}
h1 a {
display: block;
height: 100%;
position: absolute;
top: 50%;
margin-top: -0.56em;
left: 100px;
}
h1:before {
content:'';
display: block;
position: absolute;
bottom: 50%;
margin-bottom: -1000px;
left: -2000px;
height: 2000px;
width: 2000px;
background: #F00;
transform: rotate(45deg);
transition: left 0.3s;
z-index: -1;
}
h1:hover:before {
left: 0;
}
<h1><a>Text</a></h1>
Old Solution
Archived - fixed height option (no transform, should work back to IE8)
I have approached this differently:
The right triangle and the bar are made with pseudo elements and are positioned with percentages
z-index: -1 keeps the pseudo elements behind the text.
overflow: hidden prevents the scroll bar when the triangle is pushed outside.
* {
margin: 0;
padding: 0;
}
.headline {
height: 100px;
background: #333;
color: #FFF;
position: relative;
z-index: 2;
display: inline-block;
width: 100%;
height: 0;
padding: 30px 0 70px 50px;
overflow: hidden;
}
.headline:before {
width: 30%;
content:'';
display: block;
height: 100px;
background: #F00;
position: absolute;
top:0;
left: 0;
transition: all 0.3s linear 0s;
z-index: -1;
}
.headline:after {
content: '';
display: block;
border-bottom: solid 50px transparent;
border-top: solid 50px transparent;
border-left: solid 50px #F00;
height: 0;
width: 0;
left: 30%;
position: absolute;
top:0;
transition: all 0.3s linear 0s;
z-index: -1;
}
.headline:hover:before {
width: 100%;
}
.headline:hover:after {
left: 100%;
}
<h1 class="headline">Text</h1>

Create a cross shape in CSS

IS it possible, I know all the following shapes are possible in this link:
http://css-tricks.com/examples/ShapesOfCSS/
but cross must be possible too. When I say cross I mean like this:
You could achieve something like this with pseudoelements only:
http://jsbin.com/upiyoc/1/edit
#cross {
width: 100px;
height: 100px;
position: relative;
}
#cross:before, #cross:after {
content: "";
position: absolute;
z-index: -1;
background: #d00;
}
#cross:before {
left: 50%;
width: 30%;
margin-left: -15%;
height: 100%;
}
#cross:after {
top: 50%;
height: 30%;
margin-top: -15%;
width: 100%;
}
The size of the cross will proportionally scale, according to the width and height of the #cross element
Update: another solution (using less code) could simply involve multiple linear-gradients (without pseudolements) e.g.
http://codepen.io/anon/pen/zxwgPo
#cross {
width: 100px;
height: 100px;
background: linear-gradient(to bottom, transparent 35%,
#d00 35%,
#d00 65%,
transparent 65%),
linear-gradient(to right, transparent 35%,
#d00 35%,
#d00 65%,
transparent 65%),
}
Of course it is. You just have to use two elements : See http://jsfiddle.net/92XTx/2/
The enclosing div is relatively positioned so that both children can be absolutely positioned.
#cross {
position: relative;
width: 150px;
height: 150px;
}
Here they are both absolutely positioned:
#cross div {
position: absolute;
background: red;
}
to make them superpose.
And then create your shapes:
.cross-vertical {
left: 33%;
width: 33%;
height: 100%;
}
.cross-horizontal {
top: 33%;
width: 100%;
height: 33%;
}
Because all the answers I see here look either lengthy or vendor-prefix-dependent,
#cross {
background: red;
height: 100px;
position: relative;
left: 50px;
width: 20px;
}
#cross:after {
background: red;
content: "";
height: 20px;
left: -40px;
position: absolute;
top: 40px;
width: 100px;
}
<div id="cross"></div>
This can be done with a regular '+' plus character together with a text-stroke
DEMO (Webkit,Android only)
div {
font-size: 80px;
-webkit-text-stroke: 20px red;
display: inline-block;
padding: 0 20px;
}
<div>+</div>
CSS Transform can be easily used to achieve plus shape
.close {
position: absolute;
right: 10px;
top: 6px;
width: 20px;
height: 20px;
opacity: 0.3;
}
.cross:before, .cross:after {
position: absolute;
left: 15px;
content: ' ';
height: 21px;
width: 2px;
background-color: #333;
}
.cross:before {
transform: rotate(0deg);
}
.cross:after {
transform: rotate(-90deg);
}

Resources