ViewBox issue for SVG responsive button - html

I'm creating a button with rounded corners using SVG (I have to use SVG).
So I succeed to make it responsive related to his parent element #btnTour which I put a width and a height on. But I always have a gap between this #btnTour and the path of my SVG I think it's related to the viewbox but after reading bunch of articles about it I still can't figured out how to solve my issue.
Thanks for your help.
#btnTour{
display: inline-block;
background: none;
border: none;
outline: none;
position: relative;
margin: 1em;
padding: 0;
width: 192px;
height: 70px;
text-decoration: none;
}
#svgContainer{
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 100;
border: dotted 1px red;
}
#btnTourText{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: block;
margin: 0;
text-align: center;
z-index: 100;
font-size: 25px;
color: #2b5e9d;
font-weight: 600;
white-space: nowrap;
}
<a id="btnTour" href="page2.php">
<div id="svgContainer">
<svg width="100%" height="100%" viewBox="0 0 300 125" preserveAspectRatio="none">
<path id="svgBtn" style="fill:none;stroke:#2b5e9d;stroke-width:2;" d="M286.5,62.5C286.5,90.39099999999999,263.891,113,236,113C236,113,171.64499999999998,113,150,113C128.355,113,64,113,64,113C36.109,113,13.5,90.39099999999999,13.5,62.5C13.5,62.5,13.5,62.5,13.5,62.5C13.5,34.609,36.109,12,64,12C64,12,128.35500000000002,12,150,12C171.645,12,236,12,236,12C263.891,12,286.5,34.609,286.5,62.5C286.5,62.5,286.5,62.5,286.5,62.5C286.5,62.5,286.5,62.5,286.5,62.5"></path>
</svg>
</div>
<p id="btnTourText">Go on a Tour</p>
</a>

yes, you have to set the view box to fit the path ( eg. something like viewBox="12.5 11 275 103"); you can do it programmatically via js ( compute the bounding box to the to be fit svg element ) or set/get it from your preferred svg authoring app...

Related

SVG width does not update when resizing window

I've found a weird issue where the rect inside the svg stays the same width as the svg on page load. Resizing the window (causing the svg to resize) doesn't update the width of the rect. Inspecting the element and toggling off/on the height or width then causes the width to update. This issue does not occur in Safari but does occur in Chrome and Firefox.
Is there a more correct way of doing the HTML and CSS to get the effect I need? I essentially want a dashed stroke around the box. I can't use dashed border as the dashes are not wide enough.
.box {
background: black;
min-height: 300px;
padding: 65px;
border-radius: 20px;
position: relative;
max-width: 700px;
margin: auto;
}
svg {
width: calc(100% - 46px);
height: calc(100% - 46px);
fill: none;
stroke: white;
stroke-dasharray: 8px;
position: absolute;
top: 23px;
left: 23px;
pointer-events: none;
}
svg rect {
width: calc(100% - 2px);
height: calc(100% - 2px);
}
<div class="box">
<svg xmlns='http://www.w3.org/2000/svg'>
<rect x='1' y='1' rx='5' />
</svg>
</div>
You can apply border-radius and padding properties to the svg and make the inner <rect> responsive using relative units.
body {
}
*{
box-sizing:border-box
}
.resize {
resize: both;
overflow: auto;
padding: 1em;
border: 1px solid red;
width: 100%;
}
.box{
width: 100%;
height:100%;
}
svg {
display: block;
width: 100%;
height:100%;
padding: 23px;
background: #000;
border-radius: 20px;
overflow:visible;
}
rect {
stroke: white;
stroke-dasharray: 8px;
stroke-width:1px;
}
<div class="resize">
<div class="box">
<svg xmlns='http://www.w3.org/2000/svg'>
<rect x='0' y='0' rx='5' width="100%" height="100%" />
</svg>
</div>
</div>
<p>Resize me</p>
overflow:visible will prevent any stroke clipping.
It is also important to set a box-sizing: border-box property - otherwise padding will introduce overflows.
This way we don't need any calc() width/height values, that can cause issues when applied to svg elements (... in some browsers).

Two elements absolutely positioned at the same place but not showing at the same place

So, I have these two things. One is a transparent button and the other one is an image behind it.
I did that because adding a background didn't work. Here's what I tried:
.top-container > button {
background-image: url(path-to-image); /* I also tried image() */
background-repeat: no-repeat
width: 100px;
height: 33px;
color: white;
border: none;
font-family: 'CapitalisTypOasis', 'CapitalisTypOasisMedium';
text-align: center;
z-index: 2;
position: absolute;
top: 1.7em;
padding: 0;
}
I did all of the tiny variations I could think of, and since my deadline is soon, I put an image behind the button. Works perfectly.
.boutonsim {
display: block;
height: 33px;
width: 100px;
position: absolute;
top: 1.7em;
z-index: 1;
}
.top-container > button {
display: block;
width: 100px;
height: 33px;
background-repeat: no-repeat;
background-color: rgba(255, 255, 255, 0);
color: white;
border: none;
font-family: 'CapitalisTypOasis', 'CapitalisTypOasisMedium';
text-align: center;
z-index: 2;
position: absolute;
top: 1.7em;
padding: 0;
}
HTML:
<div class="top-container">
<img id="img2" src="images/haut.png" />
<img id="title" src="images/nom.png" />
<img id="logo" src="images/LOGO.png" />
<div class="boutonsim" style="right: 80px;"><img src="images/clipart/boutonORIGINAL.png" /></div>
<button style="right: 80px;">Culture</button>
</div>
They're supposed to be at the same place but when I open my file in Chrome, they're not.
Could anyone help? Thanks.
This is a GIF of the result in a snippet if it can help:
<img src="https://i.gyazo.com/c849e62e7893453a2b442f2060bce1e4.gif" alt="Image from Gyazo" width="166"/>
TL;DR; position them with anything but em.
The button must have a different font-size than the rest of the dom (which is also default behaviour), which means that the div and the button have different font-sizes. So because you are positioning them with em, they will be positioned differently (div: 27.2px and button: 22.667px), since the CSS compiler looks at the elements font-size to determine the top value in px.
In case you need to apply a background image to your button (I believe it's your real problem).
button {
width: 100px;
height: 33px;
padding: 0;
background:url(https://picsum.photos/id/1019/100/33) no-repeat;
color: white;
border: none;
}
<button>Culture</button>

Make HTML/CSS responsive

Due to the skills of others in the community I have created this:
http://codepen.io/anon/pen/NbdoKV
HTML:
.clipboard:after, .clip, .clip:before, .paper {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.clipboard {
position: relative;
display: block;
height: 27em;
width: 23em;
margin: 5em auto;
border-radius: 3%;
background: #b69b4c;
}
.clipboard:after {
top: 2.25em;
content: "";
height: 1.5em;
width: 20em;
background: #fefefe;
}
.clip {
z-index: 2;
top: 4.2em;
display: block;
height: 10em;
width: 17em;
border-radius: 50%;
background: #A7A7A7;
}
.clip:before {
content: "";
top: -.5em;
height: 5.3em;
width: 5.3em;
border: 2.2em solid #A7A7A7;
border-radius: 50%;
}
.paper {
z-index: 2;
display: block;
height: 23em;
width: 20em;
margin-top: .5em;
background: #fefefe;
}
.paper:before {
content: "";
position: absolute;
bottom: 0;
right: 0;
height: 3.25em;
width: 3.25em;
}
.paper:after {
content: "";
position: absolute;
height: 1.25em;
width: 1.5em;
}
<i class="clipboard">
<i class="clip"></i>
<i class="paper"></i>
</i>
As you can see this graphic does not scale / respond very well. If I set the width to 100%, everything loses its ratio / perspective. Ideally, I want to be able to set the clipboard width to 100% and everything (height, the clip at top, padding etc) will then scale correctly - much like an image would.
I can see 2 ways of making this responsive:
Changing the HTML/CSS - I have tried and failed
Converting this HTML/CSS to SVG - no idea where to start
How would you make this responsive?
This is an example as svg. There are a few sites where you can draw svgs.
Then you have the paths.
I think the different attributes are self explaining. If you have any questions ask please. I think the best is to read more about this if you want to use it.
Maybe here but there are many more good sources.
<svg height="200" width="450">
<path
id="lineAB"
fill="khaki"
d="M9.778,96h108.445c5.400000000000006,0,9.778000000000006,-4.378,
9.778000000000006,-9.778000000000006v-68.445c0,-5.4,-4.378,-9.778,
-9.778000000000006,-9.778h-108.445c-5.4,0,-9.778,4.378,-9.778,
9.778v68.445c0,5.400000000000006,4.378,9.778000000000006,
9.778,9.778000000000006ZM8,16h112v72h-112v-72Z"
transform="matrix(0.000503985 -1.04456 1.29502 0.000406514 -10.7973 124.73)
translate(-60,150)" />
<path
fill="#C0C0C0"
d="M109.58289641986332,32.006086609509h8v-6.222000000000001c0,-5.3999999999999995,
-4.378,-9.778,-9.778000000000006,-9.778h-30.221999999999994v-6.2219999999999995c0,
-5.4,-4.378,-9.778,-9.778000000000006,-9.778h-20.445c-5.3999999999999995,0,
-9.777999999999999,4.378,-9.777999999999999,9.778v6.222000000000001h-30.222c-5.3999999999999995,
0,-9.778,4.378,-9.778,9.777999999999999v6.222000000000001h112ZM45.58289641986323,
8.006086609509033h24v8h-24v-8Z"
transform="matrix(0.560377 0.00141111 -0.00141111 0.560377 25.8245 -9.95107)
translate(340,90)"/>
Now you only need to adjust the height and with
respectively adding a scale at the transform attribute.

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