Why 'width: 100vw' CSS rule causes scrollbar? - html

I try to have a top banner that matches the screen size. This banner contains the title + a wave SVG.
I have exactly the result I want with these CSS rules, the SVG matches well in responsive, except for a scrollbar that navigates over a few pixels (I tried many other things, including percentage widths).
EDIT : I need the width:100vw rule because I want this container to be full-width while the parent elements are not full-width.
.shape-divider {
/* It is this class which causes the scrollbar */
left: 50%;
line-height: 0;
margin-left: -50vw;
position: relative;
width: 100vw;
}
.shape-divider svg {
display: block;
height: 62px;
margin-top: -1px;
width: calc(100% + 1.3px);
}
<div class="shape-divider">
<div class="shape-divider__top">
<div>
<h1>Title</h1>
<p class="post__date">11/30/2022</p>
</div>
</div>
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 120" preserveAspectRatio="none">
<path d="M321.39,56.44c58-10.79,114.16-30.13,172-41.86,82.39-16.72,168.19-17.73,250.45-.39C823.78,31,906.67,72,985.66,92.83c70.05,18.48,146.53,26.09,214.34,3V0H0V27.35A600.21,600.21,0,0,0,321.39,56.44Z" class="shape-fill"></path>
</svg>
</div>
Rendering :
Does anyone have an idea? Thanks!
Why 'width: 100vw' CSS rule makes a scrollbar appear ?

Its because you have a vertical scrollbar.
See this for reference : https://sbx.webflow.io/100vw-scrollbars
Use width: 100%; instead (works perfectly for me with the html you gived).
Here the full edited CSS :
.shape-divider {
left: 50%;
line-height: 0;
margin-left: -50%;
position: relative;
width: 100%;
}
.shape-divider svg {
display: block;
height: 62px;
margin-top: -1px;
width: 100%;
}

Remove the + 1.3px:
.shape-divider {
/* It is this class which causes the scrollbar */
left: 50%;
line-height: 0;
margin-left: -50vw;
position: relative;
width: 100vw;
}
.shape-divider svg {
display: block;
height: 62px;
margin-top: -1px;
width: 100%;
}
<div class="shape-divider">
<div class="shape-divider__top">
<div>
<h1>Title</h1>
<p class="post__date">11/30/2022</p>
</div>
</div>
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 120" preserveAspectRatio="none">
<path d="M321.39,56.44c58-10.79,114.16-30.13,172-41.86,82.39-16.72,168.19-17.73,250.45-.39C823.78,31,906.67,72,985.66,92.83c70.05,18.48,146.53,26.09,214.34,3V0H0V27.35A600.21,600.21,0,0,0,321.39,56.44Z" class="shape-fill"></path>
</svg>
</div>

Related

CSS svg background covers div content

I want to add waves for one of the divs. I used some website that generated svg with neccessary code. The problem is it covers all the content of my div. What seems to be the problem here?
.Upper-half-wrapper {
background-color: #0A2640;
height: 515px;
position: relative;
}
.custom-shape-divider-top-1655888002 {
position: absolute;
top: 0;
left: 0;
width: 100%;
overflow: hidden;
line-height: 0;
}
.custom-shape-divider-top-1655888002 svg {
position: relative;
display: block;
width: calc(100% + 1.3px);
height: 266px;
transform: rotateY(180deg);
}
.custom-shape-divider-top-1655888002 .shape-fill {
fill: #1B3B5D;
}
<div className="Upper-half-wrapper">
<div className="custom-shape-divider-top-1655888002">
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 120" preserveAspectRatio="none">
<path
d="M0,0V46.29c47.79,22.2,103.59,32.17,158,28,70.36-5.37,136.33-33.31,206.8-37.5C438.64,32.43,512.34,53.67,583,72.05c69.27,18,138.3,24.88,209.4,13.08,36.15-6,69.85-17.84,104.45-29.34C989.49,25,1113-14.29,1200,52.47V0Z"
opacity=".25" className="shape-fill"></path>
<path
d="M0,0V15.81C13,36.92,27.64,56.86,47.69,72.05,99.41,111.27,165,111,224.58,91.58c31.15-10.15,60.09-26.07,89.67-39.8,40.92-19,84.73-46,130.83-49.67,36.26-2.85,70.9,9.42,98.6,31.56,31.77,25.39,62.32,62,103.63,73,40.44,10.79,81.35-6.69,119.13-24.28s75.16-39,116.92-43.05c59.73-5.85,113.28,22.88,168.9,38.84,30.2,8.66,59,6.17,87.09-7.5,22.43-10.89,48-26.93,60.65-49.24V0Z"
opacity=".5" className="shape-fill"></path>
<path
d="M0,0V5.63C149.93,59,314.09,71.32,475.83,42.57c43-7.64,84.23-20.12,127.61-26.46,59-8.63,112.48,12.24,165.56,35.4C827.93,77.22,886,95.24,951.2,90c86.53-7,172.46-45.71,248.8-84.81V0Z"
className="shape-fill"></path>
</svg>
</div>
<div className="Upper-half-content">
Some text
</div>
</div>
It looks like the answer was to use position: relative; on content i wanted to be on top.

Different behavior of SVG image in Chrome and IE 11

I have an svg image and I am using flex to center the svg image inside div. svg image is getting properly centered in Chrome, but if I am trying to use the same behavior in IE 11, svg image is getting completely expanded and it covers the entire div.
jsbin link: https://jsbin.com/qufuqekera/1/edit?html,css,output
.svgImage {
width: auto;
display: flex;
align-items: center;
height: 100%;
padding-left: 10px;
padding-right: 10px;
}
svg {
-webkit-transform: scale(2);
transform: scale(2);
-webkit-transform-origin: left;
transform-origin: left;
position: absolute;
border: 1px solid red;
background-color: yellow;
}
.defaultSize {
position: relative;
width: 100%;
height: 100%;
box-sizing: border-box;
border: 1px solid black;
padding-top: 18px;
padding-bottom: 18px;
}
.scroll-bar {
overflow: auto;
position: absolute;
width: 100%;
}
.container {
height: 60vh;
position: relative
}
<div class="container">
<div class="defaultSize">
<div class="scroll-bar" style="height: calc(100% - 36px)">
<div class="svgImage">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1575.01 278.01">
<defs>
<style>.cls-1,.cls-3{fill:#009a38;stroke:#000;stroke-miterlimit:10;}.cls-1{stroke-width:1.01px;}.cls-2{font-size:7px;fill:#f2f2f2;font-family:SiemensSans-Roman, Siemens Sans;}.cls-3{stroke-width:0.99px;}.cls-4{fill:#c8c8c8;}</style>
</defs>
<title>SVG Image</title>
<g id="Layer_2" data-name="Layer 2">
<g id="svgImage" data-name="SVG Image">
<g id="Auto_SVGImage" data-name="Auto_SVGImage">
<g id="Right_Image" data-name="Right Image">
</g>
</g>
</g>
</g>
</svg>
</div>
</div>
</div>
</div>
Screenshot of output in Chrome displaying as expected: https://i.stack.imgur.com/COSm1.png
Screenshot of output in IE 11: https://i.stack.imgur.com/CWxo9.png

SVG size in comparison to parent container. Why doesn't 100% min-height fill parent?

I have an SVG (the red rectangle in the screenshot)in a child DIV element, which is inside parent DIV element (the green rectangle).
.parent {
position: relative;
background: green;
left: 50%;
transform: translateX(-50%);
display: inline-block;
overflow: hidden;
height: 400px;
width: 270px;
}
.child {
display: block;
position: absolute;
top: 50%;
left: 50%;
min-height: 100%;
min-width: 100%;
transform: translate(-50%, -50%);
}
<div class="parent">
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" viewPort="550 0 600 430.95" viewBox="246 0 600 430.95" preserveAspectRatio="xMidYMid meet" >
<rect width="100%" height="100%" fill="red" />
</svg>
</div>
</div>
I want to the SVG to scale to the same size as the parent DIV, so I've used the min-height attribute, which I've set to 100%. For some reason the SVG in the child DIV doesn't scale to the size of the parent DIV, and is much smaller. I am confused why this is the case, and would have thought it would have scaled to the same size. Does anyone know why it doesn't?
min-width and min-height don't work in this situation, just use width and height instead.
If you don't specify a height for your SVG, the browser will calculate one for you based on the width and the aspect ratio of the viewBox. The width defaults to "100%", so the width will be 100% of the parent width (270px) and the height will be:
270 * 430.95 / 600 ~= 194px
Setting the height of the SVG to "100%" will make the SVG the same height as div.child, but the preserveAspectRatio="xMidYMid meet" will mean that the SVG contents will be centred in the div.
.parent {
position: relative;
background: green;
left: 50%;
transform: translateX(-50%);
display: inline-block;
overflow: hidden;
height: 400px;
width: 270px;
}
.child {
display: block;
position: absolute;
top: 50%;
left: 50%;
height: 100%;
width: 100%;
transform: translate(-50%, -50%);
}
<div class="parent">
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" viewBox="246 0 600 430.95" preserveAspectRatio="xMidYMid meet" width="100%" height="100%">
<rect width="846" height="100%" fill="red" />
</svg>
</div>
</div>
If you want the SVG to ignore the aspect ratio, and stretch to the height of the div, then set preserveAspectRatio="none".
.parent {
position: relative;
background: green;
left: 50%;
transform: translateX(-50%);
display: inline-block;
overflow: hidden;
height: 400px;
width: 270px;
}
.child {
display: block;
position: absolute;
top: 50%;
left: 50%;
height: 100%;
width: 100%;
transform: translate(-50%, -50%);
}
<div class="parent">
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" viewBox="246 0 600 430.95" preserveAspectRatio="none" width="100%" height="100%">
<rect width="846" height="100%" fill="red" />
</svg>
</div>
</div>
PS. there is no such SVG attribute as viewPort.

How to transform block in css?

How to transform block in CSS? Pseudo-elements is need or not? I try to create block look like block on the picture below. I can't create such block as on the picture below.
This is my code:
.transform_items {
width: 40%;
height: 80px;
position: relative;
margin: 0 auto;
perspective: 600px;
margin-top: 150px;
left: 50px;
}
.block,
.block::before{
display: block;
position: absolute;
margin: 0 auto;
}
.block {
border: 5px solid transparent;
width: 350px;
height: 60px;
}
.block::before {
content: '';
border: 5px solid #52B352;
transform: rotateY(30deg);
top: -5px;
right: -5px;
bottom: -5px;
left: -35px;
}
.block a {
font-size: 24px;
}
<div class="transform_items">
<div class="block"><a>Block</a></div>
</div>
The expected result:
If you can use SVG (1), it could be like this
codePen
svg #block {
stroke: orange;
fill: none;
stroke-width: 5
}
svg text {
font-size: 25px
}
<svg version="1.1" x="0px" y="0px" width="274px" height="84px" viewBox="0 0 274 84">
<polygon id="block" points="33,13 245,24 245,60 29,64 " />
<text x="100" y="50">BLOCK</text>
</svg>
You can also save the svg code as a .svg file,without the text element, and use it as background-image for the div that contains your text
Read this to learn how to use svg in different ways: https://css-tricks.com/using-svg/
(1) Browser support for SVG is a little better than browser support for transform, caniuse: SVG

Creating s-shaped curve using css

I want to create a curve as shown in below image using css.
I was trying something like this:
.curve {
background-color: #8aa7ca;
height: 65px;
width: 160px;
-moz-border-radius-bottomright: 25px 50px;
border-bottom-right-radius: 25px 50px;
}
<div class="curve">
<p>This is a sample text.</p>
</div>
Please help me
SVG
As Harry suggested in the comments, SVG would be your best option as a double curve in CSS isn't feasible without using multiple elements, pseudo elements or using possibly unsupported CSS3 properties.
SVG stands for Scalable Vector Graphic. The web browser views it as an image but you can add text and normal HTML elements within an SVG.
It is well supported across all browsers as viewable here: CanIUse
<svg width="466" height="603" viewbox="0 0 100 100" preserveAspectRatio="none">
<path d="M0,0
L100,0
C25,50 50,75 0,100z" fill="#8aa7ca" />
</svg>
SVG on MDN
CSS
Ofcourse this is still possible with CSS but does take using pseudo elements :before and :after. It is also not best for the curves as it will render them without anti-aliasing
div {
background: blue;
width: 50px;
height: 75px;
position: relative;
}
div:before {
content: '';
background-image: radial-gradient(circle at 100% 100%, rgba(204, 0, 0, 0) 100px, blue 100px);
position: absolute;
top: 0;
left: 100%;
width: 100px;
height: 75px;
}
div:after {
content: '';
position: absolute;
width: 50px;
height: 75px;
background: blue;
border-radius: 0 0 100% 0 / 0 0 100% 0;
top: 100%;
left: 0;
}
<div></div>
SVG
In svg this can be created using a single path
<svg height="300px" viewBox="0 0 100 100">
<path fill="CornFlowerBlue" d="M0,0
100,0
C50,20 50,80 0,100 Z" />
</svg>
You could make this using pure CSS if you so wished.
Demo
This uses a large box shadow to create the second curve:
.wrap {
position: relative;
height: 400px;
width: 100%;
margin: 0 auto;
max-width: 1024px;
}
.shape {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 50%;
overflow: hidden;
z-index: 10;
}
.shape:after {
content: "";
position: absolute;
top: 10%;
left: 0;
width: 100%;
height: 90%;
border-radius: 0 50% 0 0;
box-shadow: 0 0 0 999px lightgray;
}
.shape2 {
position: absolute;
top: 0;
left: 50%;
height: 100%;
width: 50%;
background: lightgray;
border-radius: 0 0 0 50%;
z-index: 10;
}
/******************************/
html,
body {
margin: 0;
padding: 0;
height: 100%;
vertical-align: top;
overflow: hidden;
background: cornflowerblue;
}
<div class="wrap">
<div class="shape"></div>
<div class="shape2">This will be where you can place the text to go down the right hand side of the slider</div>
</div>
I had a similar requirement but found the CSS for this task to be far too complex for my knowledge level. So, instead, I used an online wave generator.
With that, you can draw the wave you need and generate the SVG.
Then all you have to do is just copy-paste code for the generated wave.
This is the one I used:
svg wage generator