why do I need background-size 200% instead of cover - html

I'm trying to use an inline svg as a background-image (data url), but background-size:cover does not seems to work well, however with 200% its fits perfectly.
I'd like to understand the issue so that I can make sure I have a consistent render with different browsers. Ideally I'd like to keep using background-size:cover if possible
.card {
display: inline-flex; /* required in my context */
width: 45vmax;
background-color: lightblue;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" viewBox="0 0 2 2"><g fill="red"><path d="M0,1v-1h1z" opacity=".4" /><path d="M1,0v1h-1z" opacity=".2"/></g></svg>');
background-size: cover;
}
._200percent {
background-size: 200%;
}
.video {
padding-top: 56.25%;
}
body {
margin: 0;
}
<a class="card">
<div class="video"></div>
</a>
<a class="card _200percent">
<div class="video"></div>
</a>

As commented you can adjust the viewbox to cover the path and avoid having extra spaces and the use of 200%
svg {
border:1px solid;
width:200px;
}
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" viewBox="0 0 2 2"><g fill="red"><path d="M0,1v-1h1z" opacity=".4" /><path d="M1,0v1h-1z" opacity=".2"/></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" viewBox="0 0 1 1"><g fill="red"><path d="M0,1v-1h1z" opacity=".4" /><path d="M1,0v1h-1z" opacity=".2"/></g></svg>
You can also do this using CSS and gradient without the need of SVG
.card {
display: inline-flex; /* required in my context */
width: 45vmax;
background:
linear-gradient(to bottom right,rgba(255,0,0,0.4) 49.5%,rgba(255,0,0,0.2) 50%),
lightblue;
}
.video {
padding-top: 56.25%;
}
body {
margin: 0;
}
<a class="card">
<div class="video"></div>
</a>

Related

How to get an SVG to have a fluid width without changing its height?

I would like to accomplish two things:
The SVG width scales dynamically to take up 100% of the container's width.
SVG's is either stretched or smushed when the container's width changes (meaning the wave drawn with the svg's path)
SVG's height remains fixed to 760px. Currently if you resize the container, the SVG's height is reduced which is not desired.
.container {
width: 100%;
background: green;
height: 760px;
}
svg {
width: 100%;
}
svg path {
width: 100%;
}
<div class="container">
<svg width="1440" height="760" viewBox="0 0 1440 760" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M677.112 54.1657C400.36 -43.9336 110.391 13.291 0 54.1657V760H1440V54.1657C1301.02 95.0404 953.865 152.265 677.112 54.1657Z"
fill="purple"
/>
</svg>
</div>
I would probably use the SVG as background of a div and you can make the height of the div fixed and adjust the background-position to be top
.container {
width: 100%;
background: green;
height: 760px;
}
.container>div {
height: 100%;
background:
url('data:image/svg+xml;utf8,<svg width="1440" height="760" viewBox="0 0 1440 760" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M677.112 54.1657C400.36 -43.9336 110.391 13.291 0 54.1657V760H1440V54.1657C1301.02 95.0404 953.865 152.265 677.112 54.1657Z" fill="purple"/></svg>') top/100% no-repeat,
/*cover the bottom part with the same color*/
linear-gradient(purple, purple) bottom/ 100% calc(100% - 20vw) no-repeat;
}
<div class="container">
<div>
</div>
</div>
You can also reduce the code to keep only the container:
.container {
height: 760px;
background:
url('data:image/svg+xml;utf8,<svg width="1440" height="760" viewBox="0 0 1440 760" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M677.112 54.1657C400.36 -43.9336 110.391 13.291 0 54.1657V760H1440V54.1657C1301.02 95.0404 953.865 152.265 677.112 54.1657Z" fill="purple"/></svg>') top/100% no-repeat,
/*cover the bottom part with the same color*/
linear-gradient(purple, purple) bottom/ 100% calc(100% - 20vw) no-repeat,
green;
}
<div class="container">
</div>
You can try adding preserveAspectRatio="none" to the svg tag. This does seem to mess with the position a bit but might be a good start.
.container {
width: 100%;
background: green;
height: 760px;
}
svg {
width: 100%;
}
svg path {
width: 100%;
}
<div class="container">
<svg width="1440" height="760" viewBox="0 0 1440 760" fill="none" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M677.112 54.1657C400.36 -43.9336 110.391 13.291 0 54.1657V760H1440V54.1657C1301.02 95.0404 953.865 152.265 677.112 54.1657Z"
fill="purple"
/>
</svg>
</div>

Insert hero image into a section

I would like to append a hero image into an HTML section. But the problem is this image doesn't take the whole page as intended when it is wrapped into a section.
For exemple
<div id="home">
<div class="text-vcenter">
<h1>Reunion Qualité</h1>
<h2>Meeting Manager</h2>
<svg height="10" width="605">
<line x1="0" y1="0" x2="611" y2="0" style="stroke:rgb(255,255,255);stroke-width:3" />
</svg>
<h3>Namur-Belgium</h3>
</div>
</div>
Will work, but
<div>
<div id="home">
<div class="text-vcenter">
<h1>Reunion Qualité</h1>
<h2>Meeting Manager</h2>
<svg height="10" width="605">
<line x1="0" y1="0" x2="611" y2="0" style="stroke:rgb(255,255,255);stroke-width:3" />
</svg>
<h3>Namur-Belgium</h3>
</div>
</div>
</div>
Won't. Why ? How can i fix this ?
Here is the CSS linked regarding the Hero image :
html, body {
height: 100%;
width: 100%;
font-family: 'Quicksand', sans-serif;
}
#home {
background: url(../img/qualite_01.jpg) no-repeat center center fixed;
color: #f6f8f8;
display: table;
height: 100%;
position: relative;
width: 100%;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
The reason the second example isn't working is because you haven't specified the height of the first div (the div that wraps the #hero div). So just add the following rule to your CSS:
body div {
height: 100%;
}
A percentage height defines the height as a percentage of containing block's height (see MDN article about height and MDN article about percentage). #home's height was set to 100%, but its containing block didn't have a height specified. In the first example, on the other hand, #home's containing element is body, which has a height of 100% specified.
I think it's because of the outer <div> tag you are wrapping it all in. Naturally, a <div> won't take up the entire width of the body. An example snippet is below. With the border on it, we can see that it does not take up the full width of the body. Why is it needed to wrap the working solution in an extra <div>?
body {
background-color: red;
}
div {
border: 5px solid blue;
}
<html>
<body>
<div>
Some Text
</div>
</body>
</html>
Second snippet to show changes plus adding margin and padding equal to 0, which removes whitespace around the page
html, body {
height: 100%;
width: 100%;
font-family: 'Quicksand', sans-serif;
margin: 0;
padding: 0;
}
#outerDiv {
height: 100%;
width: 100%;
border: 5px solid blue;
}
#home {
background: url(../img/qualite_01.jpg) no-repeat center center fixed;
color: #f6f8f8;
display: table;
height: 100%;
position: relative;
width: 100%;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
<div id="outerDiv">
<div id="home">
<div class="text-vcenter">
<h1>Reunion Qualité</h1>
<h2>Meeting Manager</h2>
<svg height="10" width="605">
<line x1="0" y1="0" x2="611" y2="0" style="stroke:rgb(255,255,255);stroke-width:3" />
</svg>
<h3>Namur-Belgium</h3>
</div>
</div>
</div>

How do you separate parallax elements from header?

I have moving parallax elements overlaying a large header image, however I can't seem to figure out how to separate the two so that the header image isn't affected by the parallax movement.
I'd like for only the circles to be moving upwards as you scroll, but it looks like the header image is attached to the same movement as the black circle.
Something I've tried was taking
<div class="background">...</div>
outside of
<div class="parallax">...</div>
but then the circles were no longer overlaying the header image.
Here is my JSFiddle: https://jsfiddle.net/uk0x33mj/3/
Thank you - I really appreciate the help!
As I understood you, you need something like that. Please let me know, if you need something else.
.parallax {
perspective: 1px;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
}
.parallax__layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index:9999;
}
.parallax__layer--base {
transform: translateZ(0);
}
.parallax__layer--back {
transform: translateZ(-1px) scale(2);
}
.circle {
position:absolute;
top:400px;
left:300px;
color:#ffffff;
}
.circle_2 {
position:absolute;
top:300px;
}
.background {
background:red;
background-image: url('http://i59.tinypic.com/2eofekz.jpg');
background-size: cover;
height: 350px;
width: 100%;
position: fixed;
}
.spacer {
height:1000px;
}
<div class="background">
</div>
<div class="parallax">
<div class="parallax__layer parallax__layer--back">
<svg class="circle_2" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="576px" height="576px" viewBox="0 0 576 576" enable-background="new 0 0 576 576" xml:space="preserve">
<circle fill="#EC008C" cx="63.215" cy="61.778" r="41.83"/>
</svg>
</div>
<div class="parallax__layer parallax__layer--base">
<svg class="circle" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="576px" height="576px" viewBox="0 0 576 576" enable-background="new 0 0 576 576" xml:space="preserve">
<circle fill="#231F20" cx="63.215" cy="61.778" r="41.83"/>
</svg>
</div>
<div class="spacer"></div>
</div>

How to create a polygon shape div

I would like to create HTML element like on image here:
A problem is the DIV element has polygon shape instead of regular rectangle, will be placed above other elements as something like popup and inside that element there is necessary to show an image with rectangular shape in source but showed on web like filling all space included triangle on the left side.
Do you think is there any possibility to realize that without preparing showed images as transparent PNGs in proper polygon format? Only by CSS3 transform or use canvas or SVG?
One method could be to split the image into two containers which are 50% the size of the parent, transform each of them separately and position the backgrounds to look like they are one single image. The transform could either be a skew (used in the answer) or a perspective based rotation.
Note that since we are transforming the container, we have to apply the reverse effect to the actual image for it to look normal.
.image {
position: relative;
height: 150px;
width: 450px;
overflow: hidden;
}
.top-container,
.bottom-container {
position: absolute;
left: 0px;
height: 50%;
width: 100%;
overflow: hidden;
backface-visibility: hidden;
}
.top-container {
top: 0px;
transform-origin: right bottom;
transform: skew(-20deg);
}
.bottom-container {
bottom: 0px;
transform-origin: right top;
transform: skew(20deg);
background-position: 0% 100%;
}
.top-container:after,
.bottom-container:after {
position: absolute;
content: '';
height: 100%;
width: 100%;
left: -14px; /* tan(20) * (height/2) / 2 */
background: url(http://lorempixel.com/450/150);
background-size: 100% 200%;
}
.top-container:after {
top: 0px;
transform: skew(20deg);
}
.bottom-container:after {
bottom: 0px;
transform: skew(-20deg);
background-position: 0% 100%;
}
/* Just for demo */
body {
background: linear-gradient(90deg, crimson, indianred, purple);
}
.image2 {
margin-top: 10px;
height: 150px;
width: 450px;
background: url(http://lorempixel.com/450/150);
}
<div class="image">
<div class='top-container'></div>
<div class='bottom-container'></div>
</div>
<!-- this is the actual image for comparison -->
<h3>Original Image</h3>
<div class='image2'></div>
I was about to suggest usage of SVG and clipPath but since Persijn has already posted that sample, I have added below a different version with polygon.
.vector {
position: relative;
height: 150px;
width: 450px;
}
svg {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
polygon {
fill: url(#image);
}
/* Just for demo */
body {
background: linear-gradient(90deg, crimson, indianred, purple);
}
<div class='vector'>
<svg viewBox='0 0 450 150' preserveAspectRatio='none'>
<defs>
<pattern id='image' height='150' width='450' patternUnits='userSpaceOnUse'>
<image xlink:href='http://lorempixel.com/450/150' height='150' width='450' />
</pattern>
</defs>
<polygon points='15,0 450,0 450,150 15,150 0,75' />
</svg>
</div>
SVG
Fiddle example
Solution found by Jbutler438
using a clip-path and image tag in svg you can easily cut out an arrow shape at the front.
<?xml version="1.0" ?>
<svg width="300px" height="300px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="myClip">
<path d="M30 0, 100 0, 100 100, 30 100 0,50Z" />
</clipPath>
</defs>
<image xlink:href="http://lorempixel.com/300/300" x="0" y="0" width="100%" height="100%" clip-path="url(#myClip)" />
</svg>

SVG scaling with parent container

I'm trying to adjust a triangle that will cover 50% of the parent container from corner to corner, no matter what the ratios of the box are the triangle can be skewered.
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" preserveAspectRatio="xMinYMin meet" viewBox="0,0,100,100">
<polygon points="100,100 100,0 0,100"/>
</svg>
</div>
.container {
height:160px;
background-color:#ccc;
margin-top:10px;
}
I've setup a fiddle with the code, I'm trying to replicate the same behaviour that I was able to achieve with css, the reason why I want to go the route of svg is to stop the line from getting pixelation this is the previous code of css.
How to achieve the same result in css
<div class="parent">
<div class="arrow-right"></div>
</div>
.parent {
position:relative;
width:230px;
height:150px;
background-color:red;
}
.arrow-right {
position: absolute;
width: 100%;
height: 100%;
left: 0px;
bottom: 0px;
background: linear-gradient(to left top, #333 50%, transparent 50%);
opacity: 0.5;
}
How do I change the viewBox to allow for the polygon shape to not stay in proportion?
You need to add preserveAspectRatio="none" and stretch svg svg {width:100%; height:100%}
fiddle