I'm implementing a layout for a web-app running on Rails 5.2.
The layout has a header with a Css class (named section-divider) whose background is a SVG and it should occupy all the page width.
The SVG works fine in the HTML file I received from the designer: if I open the html file, it works correctly (check the first image).
The SVG doesn’t behave properly when I run the same code from the rails app (check the second image).
The only difference between the HTML version and the Rails one, is the reference to the SVG in the SCSS file.
I’ve tried multiple options and ways to reference the file without luck.
The SVG is being always displayed but it doesn’t stretch as it should.
It’s driving me crazy because the output HTML and Css are the same (from Rails and from the HTML provided by the designer)
SVG file
<svg xmlns="http://www.w3.org/2000/svg" width="1920" height="638" viewBox="0 0 1920 638">
<path id="Rectangle_69" data-name="Rectangle 69" d="M0,0H1920a0,0,0,0,1,0,0V392a246,246,0,0,1-246,246H246A246,246,0,0,1,0,392V0A0,0,0,0,1,0,0Z" fill="#aaa"/>
</svg>
HTML CODE: the section-divider class is the one whose background is the SVG (just at the beginning, in the header)
<header class='search-bar text-center section-divider'>
<div class='container pt-4'>
<div class='mx-auto input-group col col-md-6 col-xxxl-4 ' >
<input type='text' class='form-control shadow-sm search-input' placeholder='' aria-label='Qué buscas' aria-describedby='button-addon2'>
<div class='input-group-append'>
<button class='btn btn-outline-primary' type='button' id='button-addon2'>Buscar</button>
</div>
</div>
</div>
</header>
CSS in Rails
.section-divider (landing_page.scss){
background: image-url("front/divider/header.svg");
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
padding-bottom: 2rem;
}
CSS in designer files (landing_page.scss)
.section-divider{
background: url('../front/divider/header.svg');
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
padding-bottom: 2rem;
}
In this image, the grey area is the SVG and in this image and it is displayed correctly
In this other image, the grey area is the SVG and it is NOT displayed correctly (because it doesn't stretch)
I suppose this is what you want to achieve.
.section-divider{
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' preserveAspectRatio ='none' viewBox='0 0 1920 638'%3E%3Cpath d='M0,0H1920V392a246,246,0,0,1-246,246H246A246,246,0,0,1,0,392V0Z' fill='%23aaa'/%3E%3C/svg%3E");
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
padding-bottom: 2rem;
border:1px solid;
}
<header class='search-bar text-center section-divider'>
<div class='container pt-4'>
<div class='mx-auto input-group col col-md-6 col-xxxl-4 ' >
<input type='text' class='form-control shadow-sm search-input' placeholder='' aria-label='Qué buscas' aria-describedby='button-addon2'>
<div class='input-group-append'>
<button class='btn btn-outline-primary' type='button' id='button-addon2'>Buscar</button>
</div>
</div>
</div>
</header>
In this case you need to use the following svg instead:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 638" preserveAspectRatio ="none">
<path id="Rectangle_69" data-name="Rectangle 69" d="M0,0H1920V392a246,246,0,0,1-246,246H246A246,246,0,0,1,0,392V0Z" fill="#aaa"/>
</svg>
Please observe that the svg has no width and height. Also I've added preserveAspectRatio ="none".
Please read about the preserveAspectRatio
attribute. If preserveAspectRatio="none" the image will be scaled non-uniformly.
Also your path has 2 arcs with radius 0. I've removed those arcs.
I decided to switch to svg symbols for one of my projects - but need them to be responsive. The main idea is not to have multiple http requests, so I was thinking of merging all SVGs into one SVG, define symbols and use them as follows:
<svg style="display:none;">
<defs>
<symbol id="mys">
<path fill-rule="evenodd" clip-rule="evenodd" fill="#3F77BC" d="M222.1,77.7h-10.3c0.1-0.8,0.2-1.4,0.2-2.3
c0-8.5-6.9-15.4-15.4-15.4c-8.5,0-15.4,6.9-15.4,15.4c0,0.9,0.1,1.5,0.2,2.3h-9.3v4h-24.9v-5.2H89.4c0-0.3,0-0.6,0-0.9
C89.4,67.1,82.5,60,74,60s-15.4,6.9-15.4,15.4c0,0.3,0,0.6,0,0.9h-6.2V60.7h4.3l5.3-5.3h22.8L74.3,44.9l-13.5-3.6l0.5-1.7
l-16.5-4.4c-0.3,0.1-0.7,0.2-1,0.2l0,21.4h2v7.2c0,0-2,0.6-1.9,1.3c0.1,0.7,4.1,2.6,3.4,5.5c-0.6,2.9-1.6,4.8-4.4,4.5
c-2.7-0.3-3.4-1.4-3.4-2.6c-0.1-1.2,0-3,0-3L38,67.9c0,0,2-0.5,2.6,1.1c0.6,1.5-0.2,2.7,0.6,3.5c0.8,0.8,4.1,1.4,4.1-1.1
c0-2.5-0.5-2.4-2.1-3.6c-1.7-1.2-3.4-2.8-3.4-3.3c0-0.5-0.1-7.7-0.1-7.7h2.1l0-21.7c-1.4-0.7-2.5-2.1-2.5-3.8
c0-2.3,1.9-4.2,4.2-4.2c2,0,3.6,1.4,4.1,3.2l15.3,4.1l0.4-1.6l55.8,15.1h28.1c0,0,0-23.5,0-26.2c0-2.7,2.1-2.6,2.1-2.6
s32.5-0.5,35.1,0.5c2.7,1,3.3,3.7,3.3,3.7h-2l5,11.6c0,0,7.3,4.6,17.6,7.6c10.3,3,13.6,7.6,13.6,7.6l-1,17.6l1.3,2V77.7z
M81.5,46.8l8.6,8.6h9.3l2.9-2.9L81.5,46.8z M175.5,25l-17.4-0.1v12.6h9.6l2.7,2.7h6.6L175.5,25z M183,23.7h-4c0,0,2,6.6,3,9.9
s0.9,4.2,2.7,4.2c1.9,0,4.2,0,4.2,0L183,23.7z M74.2,63.8c6.8,0,12.3,5.5,12.3,12.3S81,88.4,74.2,88.4c-6.8,0-12.3-5.5-12.3-12.3
S67.4,63.8,74.2,63.8z M196.6,63.8c6.8,0,12.3,5.5,12.3,12.3s-5.5,12.3-12.3,12.3s-12.3-5.5-12.3-12.3S189.8,63.8,196.6,63.8z"/>
</symbol>
</defs>
</svg>
<div style="position:relative;width:100%;background:blue;">
<svg class="mys" viewBox="0 0 254 108" preserveAspectRatio="xMaxYMax meet" style="width:100%;">
<use xlink:href="#mys"></use>
<svg>
</div>
Here is a jsfiddle, check the different behaviour in IE (I checked 11 but read that 9 has multiple issues as well):
http://jsfiddle.net/ws472q71/
For the life of me I can't get this to work properly. The above code works correctly in Firefox and Chrome, but fails in IE. I read about IE issues, but I couldn't find anything that works.
What am I doing wrong?
Is there any other similar solution that can merge SVGs into one file and use them as responsive images?
Thanks!
As you have discovered, IE has a bug where it doesn't scale the SVG properly if you don't provide both the width and height.
To get it working in IE, you can use a trick discovered (?) by Nicolas Gallagher.
http://nicolasgallagher.com/canvas-fix-svg-scaling-in-internet-explorer/
The trick uses a <canvas> element. IE does properly scale canvas elements. So if you place one in the <div> with the SVG, the SVG will end up the correct size. You just need to give the canvas the same aspect ratio as your SVG.
<div style="position:relative;width:100%;background:blue;">
<canvas width="254" height="108"></canvas>
<svg class="mys" viewBox="0 0 254 108" preserveAspectRatio="xMaxYMax meet">
<use xlink:href="#mys"></use>
</svg>
</div>
with CSS
canvas {
display: block;
width: 100%;
visibility: hidden;
}
svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
canvas {
display: block;
width: 100%;
visibility: hidden;
}
svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
<svg style="display:none;">
<defs>
<symbol id="mys">
<path fill-rule="evenodd" clip-rule="evenodd" fill="#3F77BC" d="M222.1,77.7h-10.3c0.1-0.8,0.2-1.4,0.2-2.3
c0-8.5-6.9-15.4-15.4-15.4c-8.5,0-15.4,6.9-15.4,15.4c0,0.9,0.1,1.5,0.2,2.3h-9.3v4h-24.9v-5.2H89.4c0-0.3,0-0.6,0-0.9
C89.4,67.1,82.5,60,74,60s-15.4,6.9-15.4,15.4c0,0.3,0,0.6,0,0.9h-6.2V60.7h4.3l5.3-5.3h22.8L74.3,44.9l-13.5-3.6l0.5-1.7
l-16.5-4.4c-0.3,0.1-0.7,0.2-1,0.2l0,21.4h2v7.2c0,0-2,0.6-1.9,1.3c0.1,0.7,4.1,2.6,3.4,5.5c-0.6,2.9-1.6,4.8-4.4,4.5
c-2.7-0.3-3.4-1.4-3.4-2.6c-0.1-1.2,0-3,0-3L38,67.9c0,0,2-0.5,2.6,1.1c0.6,1.5-0.2,2.7,0.6,3.5c0.8,0.8,4.1,1.4,4.1-1.1
c0-2.5-0.5-2.4-2.1-3.6c-1.7-1.2-3.4-2.8-3.4-3.3c0-0.5-0.1-7.7-0.1-7.7h2.1l0-21.7c-1.4-0.7-2.5-2.1-2.5-3.8
c0-2.3,1.9-4.2,4.2-4.2c2,0,3.6,1.4,4.1,3.2l15.3,4.1l0.4-1.6l55.8,15.1h28.1c0,0,0-23.5,0-26.2c0-2.7,2.1-2.6,2.1-2.6
s32.5-0.5,35.1,0.5c2.7,1,3.3,3.7,3.3,3.7h-2l5,11.6c0,0,7.3,4.6,17.6,7.6c10.3,3,13.6,7.6,13.6,7.6l-1,17.6l1.3,2V77.7z
M81.5,46.8l8.6,8.6h9.3l2.9-2.9L81.5,46.8z M175.5,25l-17.4-0.1v12.6h9.6l2.7,2.7h6.6L175.5,25z M183,23.7h-4c0,0,2,6.6,3,9.9
s0.9,4.2,2.7,4.2c1.9,0,4.2,0,4.2,0L183,23.7z M74.2,63.8c6.8,0,12.3,5.5,12.3,12.3S81,88.4,74.2,88.4c-6.8,0-12.3-5.5-12.3-12.3
S67.4,63.8,74.2,63.8z M196.6,63.8c6.8,0,12.3,5.5,12.3,12.3s-5.5,12.3-12.3,12.3s-12.3-5.5-12.3-12.3S189.8,63.8,196.6,63.8z"/>
</symbol>
</defs>
</svg>
<div style="position:relative;width:100%;background:blue;">
<canvas width="254" height="108"></canvas>
<svg class="mys" viewBox="0 0 254 108" preserveAspectRatio="xMaxYMax meet">
<use xlink:href="#mys"></use>
</svg>
</div>
The trick works whether you are trying to get it to match a width or a height.
On a side note to help anyone struggling to implement this fix or finding its not working with external svg files rather than in-page svg markup
You need to ensure that when editing your svg file in a text editor it is not missing viewBox or preserveAspectRatio attributes in the opening <svg> tag. If these are missing regardless of what fixes you apply the svg will still not scale in IE - even though it'll scale in other browsers without issue.
If these options are set you can define the width/height on the image element used to pull in the svg to 100% and use max-width or max-height to limit the scaling and it will perform as expected. Though - you could still get some alignment issues.
Nicolas Gallagher's solution works great, however, I ran into some responsive issues as I decreased the viewport. I thought I would pass along the fix I used:
<div class="parent-div">
<canvas width="3" height="1"></canvas>
<svg class="mys" viewBox="0 0 254 108">
<use xlink:href="#mys"></use>
</svg>
</div>
I updated the "parent-div" with max-width:100%;
.parent-div{
position: relative;
display: inline-block;
height: 550px;
max-width: 100%;
}
This will not solve all your scaling issues. You will still have to use media queries to change the height as you go, but at least the svg doesn't blow out its container. Hope this helps someone.
This can be rewritten like so if you're working with <img>
HTML
<div class="ie-svgHeight">
<img src="path.svg" class="ie-svgHeight-img">
<canvas class="ie-svgHeight-canvas"></canvas>
</div>
SCSS
.ie-svgHeight {
position: relative;
&-canvas {
display: block;
visibility: hidden;
position: absolute;
top: 0;
left: 0;
height: 100%;
}
&-img { height: 100%; }
}
I'm having a real difficult time trying to style a checkbox in bootstrap, I currently have the default checkbox, and I need to style it to look like this
I'm aware this picture it's round but the designer made a mistake, so instead of being round it still needs to be square
I have looked at the following and also tried what is suggested.
Twitter Bootstrap radio/checkbox
I did on the other hand find a website which has a similar to style to what i'm trying to achieve which is on here located on the left hand side where you do the filtering
Example of the checkbox
I tried using firebug to get/check out the CSS but I was unable to obtain the CSS.
So if you don't need support for IE8 you can easily do this with a background image and the :checked selector in CSS only. I used an svg image, but you could use a font, sprite or just two images.
#import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css";
body {
background-color:#f5e1c6;
}
.image-checkbox {
position: absolute;
left: 100%;
visibility: hidden;
}
.image-checkbox-label {
height: 50px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 96 84" enable-background="new 0 0 96 84" xml:space="preserve"><path fill="rgb(213,195,170)" d="M74.2,73.5H19.5c-2.8,0-5.1-2.3-5.1-5.1V15.6c0-2.8,2.3-5.1,5.1-5.1h54.7c2.8,0,5.1,2.3,5.1,5.1 v52.7C79.3,71.2,77,73.5,74.2,73.5z"/></svg>') no-repeat;
color: #7b7163;
}
.image-checkbox:checked + .image-checkbox-label {
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 96 84" enable-background="new 0 0 96 84" xml:space="preserve"><path fill="rgb(213,195,170)" d="M74.2,73.5H19.5c-2.8,0-5.1-2.3-5.1-5.1V15.6c0-2.8,2.3-5.1,5.1-5.1h54.7c2.8,0,5.1,2.3,5.1,5.1 v52.7C79.3,71.2,77,73.5,74.2,73.5z"/><polygon id="check" fill="rgb(251,253,223)" points="30.2,31.8 30.2,43 46.1,54 80.1,19.1 80.1,6.1 46.4,44.7 "/></svg>') no-repeat;
color: #c3b39c;
}
.checkbox label {
padding-left: 60px;
line-height: 50px;
font-weight: bold;
font-size: 2em;
}
<div class="container">
<div class="row">
<div class="col-xs-12">
<form>
<div class="form">
<div class="checkbox">
<input id="remember-me" type="checkbox" class="image-checkbox" />
<label for="remember-me" class="image-checkbox-label">
Remember Me
</label>
</div>
</div>
</form>
</div>
</div>
</div>
How it Works
Give the input an id so that you can use the for attribute on the label. Don't forget to make your ids unique. Give the input a class (I used .image-checkbox), and position the input so that it's hidden offscreen but still displayed.
Style your label using the background-image for the unchecked box style. Using the :checked pseudo selector and the sibling selector (+), you can target how the label should be styled when the input is selected. In this case, I changed the background image to the checked image and changed the font color.
To get the actual label text to align nicely, I'm also overriding some of the default Bootstrap styles for .checkbox label. You can adjust them to suit your needs.