I've been trying to create a gray connector between div containers (image below) for a while now. The margin between the containers is set to 2.5vw per container on each side.
I've tried to create it using an .svg background on a :before pseudo element and positioning it, but I couldn't make it work. The gray connector should stay fixed in relation to the boxes until the boxes wrap (mobile version), in which case the connectors should be hidden. The mobile version is easy to setup, but when the elements are next to each other I'm finding it almost impossible to apply the gray connector to the elements. The connector should stay fixed in relation to the containers when transitioning between laptop screens and large desktop screens.
Here's the outcome I want:
Gray connector between boxes.
Here's the outcome I've got and the code I've used:
Outcome I've got.
.box-container:after{
content: '';
height: 700px;
width: 600px;
position: absolute;
background-image: url("folder_path/Connector-1.svg");
background-repeat: no-repeat;
background-position: -80px 60px;
background-overflow: visible !important;
z-index: 0 !important;
}
.box-container{
z-index: 1 !important;
}
Maybe I've been going at it the wrong way, all workarounds are welcome.
Here is one way to do it:
main {
width: 100%;
height: 100%;
position: relative;
}
section {
display: inline-block;
width: 100px;
height: 200px;
background: orange;
box-shadow: 0 5px 15px rgba(0, 0, 0, .3);
}
section + section {
margin-left: 46px;
}
.connector {
position: absolute;
top: 0;
z-index: -1;
background: #444;
width: 100px;
height: 200px;
transform-origin: top left;
transform: skewX(36.87deg); /* do some trigonometry here to get the deg */
}
.connector:nth-of-type(2) {
left: 150px;
}
<main>
<section></section>
<section></section>
<section></section>
<div class="connector"></div>
<div class="connector"></div>
</main>
I figured out the solution! It's to create a pseudo-element, with a height of 100% and a width equal to the margin between the elements. To keep it responsive, it's important to use vw for the width unit, both for the margin between elements and also the width of the decoration itself. The margin of the <div>s are 2.5vw each, so setting the width of the pseudo element to 5 makes it fit perfectly. Heres the code:
.container:after{
content: '';
z-index:-1;
position: absolute;
top: 0;
right: -5vw;
width: 5vw;
height: 100%;
background-color: #444;
clip-path: polygon(0% 0%, 100% 40%, 100% 100%, 0% 60%);
}
Related
I am trying to recreate this:
But I have not been able to do so. I tried with adding a :before on the img but that doesnt work. How would you go on about making this. It has to be responsive in the way that the background doesnt get bigger than the image.
SEO is not important so background-image or whatever is fine with me too.
WRITTEN IN SCSS - CHANGE IN HTML IS OK
UPDATED CODE TO ROB's ANSWER
This is the code I have so far
.imgbox {
padding: 5%;
position: relative;
height: auto;
.backdrop {
position: relative;
min-width: 100px;
min-height: 100px;
div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
background: rgb(208, 0, 0);
background: linear-gradient(
90deg,
rgba(208, 0, 0, 1) 0%,
rgba(149, 0, 0, 1) 100%
);
}
transform: translateX(-5px) translateY(5px);
}
.img {
width: 100%;
height: auto;
transform: translateX(5px) translateY(-5px);
}
}
<div className="imgbox">
<div className="backdrop">
<div></div>
</div>
<img
className="img"
src={'https://source.unsplash.com/400x250'}
alt="test"
>
</div>
It's simple with a box shadow.
The paddings in the parent are there to prevent it from cropping the shadow.
.imgbox {
padding: 0 0 30px 30px;
}
.imgbox .img {
display: inline-block;
box-shadow: -30px 30px 0 rgb(208, 0, 0);
}
<div class="imgbox">
<img
class="img"
src='https://source.unsplash.com/400x250'
alt="test"
/>
</div>
Very easy to get the gradient with a pseudo-element:
.image-container::after {
content:'';
position: absolute;
z-index:-1;
bottom:-24px;
left:-24px;
width:100%;
height:100%;
background: linear-gradient(red, firebrick);
}
You can change the gradient and offset using background, left and bottom respectively. I'm not sure if there is a second gradient as well, to the top right? If so, you pair this with a ::before to get a second background, and play around the with z-index to get the ordering correct.
Just remember - for an absolute positioned pseudo element to work, you'll need to set position:relative on the parent container, and content:'';
Codepen here.
I'm trying to create a div with a triangle on top & a triangle under it..
the div should be responsive in size, so not a fixed width
not a fixed height either
Already experimented with borders only but they don't seem to give me that flexible width I want..
So where I'm at:
I'm using pseudo elements to place svgs I made of the shape!
Problem is, I'm not sure how to place them properly.. feels so strange to have to set 100% from top to place the bottom one & the other way (but as you can see there is a line in between etc)..
Here's the fiddle:
https://jsfiddle.net/benvanlooy/c4vqb1ay/
.box {
position: relative;
display: inline-block;
width: 40%;
background-color: #D01417;
margin-top: 200px;
margin-bottom: 200px;
padding: 30px;
}
.box::before {
content: url('http://www.benvanlooy.be/fiddle/box-triangle-top-red-new-01.svg');
position: absolute;
width: 100%;
left: 0px;
bottom: 100%;
}
.box::after {
content: url('http://www.benvanlooy.be/fiddle/box-triangle-bottom-red-new-01.svg');
position: absolute;
width: 100%;
left: 0px;
bottom: 0px;
top: 100%;
}
<div class="box">
this is some content
<BR/> this
<br/> box
<br/> has
<br/> a <br/> variable
<br/> height
</div>
Has anyone got any experience with something like this? :-)
The answer is probably easy, so I'm feeling rather stupid :/
Any help would be much appreciated!
You can use gradient and no need for complex code and extra SVG:
.box {
position: relative;
display: inline-block;
width: 40%;
background:
linear-gradient(to top right,#D01417 49.5%,transparent 50%) top right/50.2% 200px,
linear-gradient(to top left,#D01417 49.5%,transparent 50%) top left/50.2% 200px,
linear-gradient(to bottom right,#D01417 49.5%,transparent 50%) bottom right/50.2% 200px,
linear-gradient(to bottom left,#D01417 49.5%,transparent 50%) bottom left/50.2% 200px,
linear-gradient(#D01417,#D01417) center/100% calc(100% - 400px);
background-repeat:no-repeat;
padding: 200px 30px;
}
<div class="box">
this is some content
<br> this
<br> box
<br> has
<br> a <br> variable
<br> height
</div>
This creates visual triangles without any images (using borders only):
.box {
position: relative;
display: inline-block;
width: 40%;
background-color: #D01417;
margin-top: 200px;
margin-bottom: 200px;
padding: 30px;
}
.box::before {
content: "";
display: block;
position: absolute;
left: 50%;
top: -40px;
transform: translateX(-50%);
border-width: 22px;
border-color: transparent transparent #D01417 transparent;
border-style: solid;
}
.box::after {
content: "";
display: block;
position: absolute;
left: 50%;
bottom: -40px;
transform: translateX(-50%);
border-width: 22px;
border-color: #D01417 transparent transparent transparent;
border-style: solid;
}
<div class="box">
this is some content
<BR/> this
<br/> box
<br/> has
<br/> a <br/> variable
<br/> height
</div>
You can remove a 4 px line by using calc like this:
.box::before {
bottom: calc(100% - 4px);
}
https://jsfiddle.net/c4vqb1ay/33/
or
https://jsfiddle.net/c4vqb1ay/36/
Another option would be to clip the actual div's shape, without using pseudo elements or SVGs. For example:
div {
background-color: #D01417;
width: 40%;
clip-path: polygon(0 3em,
50% 0,
100% 3em,
100% calc(100% - 3em),
50% 100%,
0 calc(100% - 3em)
);
padding: 4em 1em;
}
html * {
box-sizing: border-box;
}
<div>
this is some content<BR/>
this<br/>
box<br/>
has<br/>
a <br/>
variable<br/>
height
</div>
Browser support for clip-path: https://caniuse.com/#feat=css-clip-path
(works in most current browsers except Edge, if you add a -webkit- prefix)
The polygon is drawn by simply defining it's points:
translates to CSS shape as:
0 3em,
50% 0,
100% 3em,
100% calc(100% - 3em),
50% 100%,
0 calc(100% - 3em)
(starting at top left, but it doesn't really matter)
If you ever decide to go for more complex shapes, this tool is quite useful: https://bennettfeely.com/clippy/
I'm trying to place an image between 2 divs on my page. I have currently been able to get an image between the two divs, but it isn't responsive (only in the correct position at 1920 width) and it overlaps the text of both divs:
screenshot from my website
css
.btwimg {
width: 90%;
height: auto;
position: absolute;
transform: translate3d(-20%, -50%, 0);
z-index: 1;
left: 50%;
background: url("../img/lara2.png");
background-repeat: no-repeat;
box-shadow: 0 5px 7px rgba(0,0,0,0.1);
}
html
<div class="btwimg">
<img src="img/lara2.png">
</div>
what I am trying to achieve
Is it possible to achieve what I'm after?
Thanks in advance.
First you have to add the same amount of padding-bottom to the upper DIV and padding-top to the subsequent DIV to create enogh space for your image. (trial and error to find the right amount)
Your btwing DIV should be a child element of the subsequent DIV. Then this CSS should work:
.btwimg {
width: 90%;
height: 250px /* Just a random guess - Needs a fixed height! */
position: absolute;
z-index: 1;
left: 50%;
top: -50%;
transform: translate(-50%, -50%);
background: url("../img/lara2.png");
background-repeat: no-repeat;
box-shadow: 0 5px 7px rgba(0,0,0,0.1);
}
Actually the height setting should be a calc value which is derived from the original width/height proportion and the 90% width you set, like height: calc(9/16 * 90%);if the proportion is 16/9
I took #Johannes answer and tweaked a little to get the result I wanted:
.btwimg {
max-width: 800px;
min-width: 300px;
height: 16vw;
position: absolute;
z-index: 1;
left: 50%;
top: calc(2vw - 38px); /* keeps div roughly centred at all target resolutions */
transform: translate(-50%, -50%);
}
I then used an image rather than a background to make the re-sizing easier.
.btwimg img {
height: auto;
width: 100%;
}
btwimg was put as a child of the 2nd div as recommended
result at mobile resolutions
result at desktop resolutions
I recently have created this banner for my website, but I realized that I only want the main part of my site to be 900px long. However, I want the banner to run off the page, but have the part where it runs off be darkened (through opacity). So, this means, I need to make the image of my site positioned in the middle. Here is what I developed so far:
https://jsfiddle.net/h3w89t9y/4/
As you can see, this doesn't really get what I need. Here's the issue:
.banner {
background:url(https://i.gyazo.com/74f0fa6b9d9ed6652f3e220ceae113cf.png) no-repeat;
background-position: center;
margin: 0 auto;
height:185px;
}
The banner isn't 800px. If I add in a width of 800px, it will go to the middle just like I wanted. However, the image will be limited to only be 800px long rather than overflowing off of 800px.
This is what I'm trying to get it to look like:
https://i.gyazo.com/c38cae7bd34379477a6fcc8eeb160c22.png
How do I make it to where my banner is centered to the middle, but has the sides overlapped with opacities?
You can achieve what you want using pseudo like this:
body {
margin: 0;
}
.wrapper {
background:url(https://i.gyazo.com/74f0fa6b9d9ed6652f3e220ceae113cf.png) no-repeat center;
width: 100%;
}
.wrapper:before, .wrapper:after {
content:'';
width: calc((100% - 900px) / 2); /*setting the width to the 100% minus your desired header's width / 2 so it will occupy the rest of your content*/
height:185px;
position: absolute;
top: 0;
background: rgba(0, 0, 0, 0.3); /*set the desired opacity*/
}
.wrapper:before {
left: 0;
}
.wrapper:after {
right: 0;
}
.banner {
width: 900px;
height:185px;
margin: 0 auto;
}
<div class="wrapper" style="">
<div class="banner"></div>
</div>
So the idea is your pseudo elements occupy the rest of the content and setting them your desired transparency, notice that in this way you also can set them blur or whatever filter that you want.
Here a working jsfiddle to play with
You can't control opacity of a single background like that, you need another element. For example:
.banner, .bannert {
background:url(https://i.gyazo.com/74f0fa6b9d9ed6652f3e220ceae113cf.png) no-repeat;
background-position: center;
margin: 0 auto;
height:185px;
}
.banner {
max-width: 800px;
position: absolute;
left: 0;
right: 0;
top: 0;
}
.bannert {
background-repeat: repeat-x;
opacity: 0.5;
}
<div style="width: 100%; background: black; padding: 1px;position: relative;">
<div class="bannert"></div>
<div class="banner"></div>
</div>
https://jsfiddle.net/h3w89t9y/6/
Try this; add two divs first, one for the left side, and one for the right,hence you can apply your desired opacity to them and make the banner sides filtered, look at the snippets below;
HTML
<div style="width: 100%; padding: 1px;">
<div class="banner">
<div class="trans_right"></div>
<div class="trans_left"></div>
</div>
</div>
CSS
.trans_right {
padding: 2rem;
width: 13%;
float: right;
background: rgba(71,67,255,0.9);
height: 65%;
}
.trans_left {
padding: 2rem;
width: 13%;
float: left;
background: rgba(71,67,255,0.9);
height: 65%;
}
I'm really not sure if there is a better way to do this, but it gives you what you're looking for, checkout the link:
Transparent Sides
Assume, that I have three boxes (divs) on website (see image below):
header with logo
content with some text
footer with contact info
Each box have unique color (in order: yellow, orange and blue) and black border.
I would like to website always fills the entire screen, the logo was on the top and the footer was at the bottom. So if there is not enough text in content, content should be extended, so that the footer was on the bottom. And if will be a lot of text in content, slider should appear on the right.
How do this in CSS? Important is that boxes have backgrounds. I found many solutions, but none doesn't work properly with backgrounds.
Solution Explained
The black box in your diagram gets min-height 100%, is the scrolling container, and is position relative, to allow child positions to be respective to it.
The red box in your diagram is actually composed of 2 boxes:
one for your dynamically-sized content; this has sufficient top and bottom padding to make room for your header and footer, and force the scrolling container to expand
one for the background; this is position absolute, with top and bottom position specified relative to the black box, its parent.
The yellow and blue boxes in your diagram can be position: absolute, top: 0 and bottom: 0, respectively... or however you choose to position them.
Here's a fiddle of it: http://jsfiddle.net/syndicatedshannon/F5c6T/
And here is another version with explicit viewport elements just to clarify, matching colors, and borders added to replicate the OP graphics (although per the OP the black border is actually the window).
Sample HTML
<html>
<body>
<div class="background"></div>
<div class="content"></div>
<div class="header"></div>
<div class="footer"></div>
</body>
</html>
Sample CSS
html { position: absolute; height: 100%; left: 10px; right: 10px; overflow: auto; margin: 0; padding: 0; }
body { position: relative; width: 100%; min-height: 100%; margin: 0; padding: 0; }
.background { position: absolute; top: 120px; bottom: 120px; background-color: red; width: 100%; }
.content { position: relative; padding: 120px 0; }
.header { position: absolute; top: 10px; height: 100px; width: 100%; background-color: yellow; }
.footer { position: absolute; bottom: 10px; height: 100px; width: 100%; background-color: cyan; }
Also note that this assumes you cannot rely on CSS3 yet.
If you're only targeting modern browsers, you can use calc()
body, html {
height: 100%;
padding: 0;
margin: 0;
}
.header {
height: 50px;
margin-bottom: 10px;
}
.footer {
height: 100px;
margin-top: 20px;
}
.content {
min-height: calc(100% - 50px - 10px - 100px - 20px);
}
The drawback is that you need to know the header and footer sizes and they need to be fixed. I don't know any way around this without using Javascript. For slightly less modern browsers, you can use border-box to get the same effect as above.
body, html {
height: 100%;
padding: 0;
margin: 0;
}
.header {
height: 50px;
margin-bottom: 10px;
z-index: 5;
position: relative;
}
.footer {
height: 100px;
margin-top: -100px;
z-index: 5;
position: relative;
}
.content {
box-sizing: border-box;
padding: 60px 0 120px 0;
margin-top: -60px;
min-height: 100%;
z-index: 1;
position: relative;
}
Lastly, here is the JS solution:
$(function(){
$('.content').css('min-height',
$(window).height()
- $('.header').outerHeight()
- $('.footer').outerHeight() - $('.content').marginTop()
- $('.content').marginBottom());
});
EDIT: My JS solution assumed border-box and no border. This solution should be more robust:
function setContentSize() {
$('.content').css('min-height',
$(window).height()
- $('.header').outerHeight()
- $('.footer').outerHeight()
- ($('.content').outerHeight()
- $('.content').innerHeight()));
}
$(setContentSize);
$(window).on('resize', setContentSize);