How can I draw a border-right in a box using CSS3 like in this image?
One possible solution would be this,
#curve{
margin:0 auto;
position:relative;
width:50px;
height:50px;
border-top:1px solid red;
border-right:1px solid red;
border-top-right-radius:50px;
float:left;
margin-left:50px;
}
#curve:after{
content: "";
position: absolute;
width: 50px;
height: 50px;
border-bottom: 1px solid red;
border-left: 1px solid red;
border-bottom-left-radius: 50px;
left: 50px;
top: 50px;
}
<div id="curve"></div>
SVG is much better option to create such kind of shapes. It is simple and scale able.
We can use SVG's path element to create this shape and fill it with some color, gradient or pattern.
Only one attribute d is used to define shapes in path element. This attribute itself contains a number of short commands and few parameters that are necessary for those commands to work.
Below is the necessary code to create this shape:
<path d="M10,10
L210,10
Q230,10 250,50
T290,90
L10,90
Z" />
I've used 5 commands inside path element. Below is a brief description:
M command is used to define the starting point. It appears at the beginning and specify the point from where drawing should start.
L command is used to draw straight lines.
Q command is used to draw curves.
T produces the same type of curve as earlier, but if it follows another Q command or a T command.
Z command is used to close the current path.
Output:
Working Example:
body {
background: linear-gradient(#466273, #5c8ea8) no-repeat;
min-height: 100vh;
margin: 0;
}
<svg width="300" height="100" viewBox="0 0 300 100">
<path d="M10,10 L210, 10 Q230,10 250,50 T290,90 L10,90 Z" stroke="#000" stroke-width="2" fill="yellowgreen" />
</svg>
Useful Resources:
SVG: Specs, MDN
Related
im using recharts for my graph, i added a cartesian grid, and YAxis with ticks.
but recharts adds additional top and bottom lines.
i tried to add css to my styles file as stated here:
https://github.com/recharts/recharts/issues/861
but im not sure how to pass those styles to recharts , and is it to the yAxis or to the cartesian grid.
tickLine={false} - didnt help
axisLine={false} on <xAxis ... /> - also didnt help
also saw somewhere:
.wrapper {
background-color: aliceblue;
width: 70%;
height: 70%;
box-shadow: 20px 8px 20px grey;
transition: box-shadow .2s ease-in;
display:block;
margin: 20px auto;
}
.wrapper:hover{
box-shadow: 30px 8px 30px grey;
transition: box-shadow .2s ease-in;
}
but it also didnt help , not sure how to apply those styles to recharts.
my cartesian grid:
<CartesianGrid class={styles.horizontal} horizontal={true} vertical={false} />
lines image:
so, any idea how ?
thnx alot
.recharts-wrapper .recharts-cartesian-grid-horizontal line:first-child,
.recharts-wrapper .recharts-cartesian-grid-horizontal line:last-child,
.recharts-wrapper .recharts-cartesian-grid-vertical line:first-child,
.recharts-wrapper .recharts-cartesian-grid-vertical line:last-child {
stroke-opacity: 0 !important;
}
I want to create a border animation for a button element. The design is that the ends of the slanted rectangle are open and then close on hover.
This is what we're trying to do (excuse my artistic "style"):
Here's some code and a codepen example:
a svg rect {
stroke: red;
stroke-width: 5;
transition: 1s;
stroke-dasharray: 100%;
stroke-dashoffset: 0;
}
a:hover svg rect {
stroke-dasharray: 0%;
stroke-dashoffset: 0;
}
codepen example
I'm having trouble understanding the math behind stroke-dasharray, but it seems this should be possible without too much complex math.
The other issue is that it would need to be responsive. So the button can contain different amounts text.
Let me know if you need further clarification.
Here is, I think, about the best you can do to create an automatically responsive button that meets your requirements.
It has a couple of failings:
The gap in the outline of the button varies in size based on the label length.
It needs a fairly recent browser (in order to support pathLength on a <rect> element)
.btn {
display: inline-block;
position: relative;
overflow: auto;
}
.btn + .btn {
margin-left: 20px;
}
.btn svg {
position: absolute;
top: 0;
left: 0;
}
.label {
position: relative;
font-size: 18px;
font-weight: bold;
padding: 5px 20px;
}
.btn, .btn svg {
overflow: visible;
}
.btn svg rect {
fill: gold;
stroke: black;
stroke-width: 2px;
stroke-dasharray: 47 3;
transform-origin: 50% 50%;
transform-box: fill-box;
transform: skewX(-10deg) scale(1, -1);
transition: all 0.75s;
}
.btn:hover svg rect {
stroke-dasharray: 50 0;
stroke-dashoffset: 50;
}
<div class="btn">
<svg width="100%" height="100%">
<rect width="100%" height="100%" pathLength="100"/>
</svg>
<div class="label">Button</div>
</div>
<div class="btn">
<svg width="100%" height="100%">
<rect width="100%" height="100%" pathLength="100"/>
</svg>
<div class="label">Much longer button</div>
</div>
Instead of using a skewed svg element I'm using a polygon. This way I can calculate the total length (perimeter length) of the polygon. I've done this using javascript: console.log(poly.getTotalLength()). This gave me 543.7. For the polygon's stroke-dasharray I'm using 250, 21.85 where 250 + 21.85 = 543.7 / 2.
I'm animating the stroke-dashoffset to 543.7 / 2 = 271.85; and stroke-dasharray to 271.85 0. (the stroke goes from 250 to 271.85 and the gap from 21.85 to 0)
Another change I've made: I'm using a svg <a> element instead of the one you are using and the polygon has pointer-events:all; I've added this to make it sensitive to the mouse although the fill:none.
I hope you'll find this useful.
polygon {
stroke: red;
stroke-width: 4;
stroke-dasharray:250, 21.85;
fill: none;
transition: 1s;
pointer-events:all;
}
polygon:hover{
stroke: #ff0;
stroke-dashoffset: 271.85;
stroke-dasharray: 271.85 0;
}
<svg viewBox = "0 0 250 50" width="250">
<a xlink:href="#" class="py-2 px-5">
<text x="125" y="30" text-anchor="middle">Button Button Button</text>
<polygon id="poly" points="2,48 220,48 248,2 30,2 2,48" />
</a>
</svg>
How would you go about creating an irregular border with variable colours like the one in the screenshot?
I considered creating a border image in a graphics editor and then using border-image property as described in the docs.
However, this technique would not allow me to achieve the effect of multiple background colours (grey and white in the screenshot) entering the border "waves".
Another solution would be to just produce the whole background white and grey in say Photoshop, and the just use it on the website. I really wanted to avoid this for performance reasons, and would prefer to just produce a grey, checked pattern fragment and repeat it.
Moreover, as you can see in the screenshot, the dark fragment is an image from a carousel - the images will all come in different colours so applying a border-image to the carousel container is not a solution either.
I would appreciate some advice. Thanks.
Using SVG:
You can do this using SVG. I would say it is pretty complex because the approach uses patterns for the repeating circles, a mask with the pattern as its fill to produce the transparent cuts. This mask is then applied to the image to produce the full effect. This in my opinion is the closest to what you want and also has good browser support. It works fine in IE10+, Edge, Firefox, Chrome, Opera and Safari.
There are a couple of points to note though - (1) You would have to somehow get your carousel work with SVG image because otherwise mask will have no effect (2) the radius of circles change as the width of the container change and so you'd either have to use a fixed size container (or) assign width of the container to the viewBox attribute using JS (or find some setting to prevent the radius change from happening, I don't know of any) .
.masked {
position: relative;
height: 175px;
width: 100%;
background: linear-gradient(60deg, #EEE 35%, white 35.5%), linear-gradient(300deg, #EEE 35%, white 35.5%);
background-size: 51% 100%;
background-repeat: no-repeat;
background-position: 0% 0%, 100% 0%;
padding-top: 100px;
}
.masked svg {
position: absolute;
top: 0px;
left: 0px;
height: 100px;
width: 100%;
}
path {
fill: #fff;
}
image {
mask: url("#mask");
}
<div class='masked'>
<svg viewBox='0 0 1200 100' preserveAspectRatio='none'>
<defs>
<pattern id="circles" patternUnits="userSpaceOnUse" width="10" height="100">
<path d="M0,0 L10,0 10,95 A5,5 0 0,0 0,95 L0,0" />
</pattern>
<mask id="mask">
<rect height="100%" width="100%" fill="url(#circles)" />
</mask>
</defs>
<image xlink:href='http://lorempixel.com/1200/100/nature/1' x="0" y="0" height="100%" width="100%" />
</svg>
Lorem Ipsum Dolor Sit Amet...
</div>
Using CSS:
This can be done using CSS masks but unfortunately the browser support for this feature is terrible. It is currently supported only in WebKit powered browsers. If other browsers need not be supported then this is a wonderful option. All that we need to do is create a radial gradient (that repeats in X axis) for the mask like in the below snippet, give it the required size and position it accordingly.
.masked {
position: relative;
height: 175px;
width: 100%;
background: linear-gradient(60deg, #EEE 35%, white 35.5%), linear-gradient(300deg, #EEE 35%, white 35.5%);
background-size: 51% 100%;
background-repeat: no-repeat;
background-position: 0% 0%, 100% 0%;
padding-top: 80px;
}
.masked:before {
position: absolute;
content: '';
top: 0px;
height: 80px;
width: 100%;
background: url(http://lorempixel.com/1000/100/nature/1);
-webkit-mask-image: linear-gradient(to bottom, black, black), radial-gradient(circle at 50% 100%, transparent 50%, black 55%);
-webkit-mask-size: 100% calc(100% - 12px), 12px 12px;
-webkit-mask-position: 0% 0%, 0px 68px;
-webkit-mask-repeat: repeat-x;
}
<div class="masked">Lorem Ipsum Dolor Sit Amet</div>
<div class="box">
<div class="pic">
<img src="/images/img.png" class="img_pic" />
</div>
</div>
.box {
border: 1px solid #333;
cursor: pointer;
height: 73px;
margin: 40px 42px 0 0;
width: 269px;
}
.img_pic {
display: block;
margin-left: auto;
margin-right: auto;
}
I want the image ("img_pic") to be centered vertically as well. With what I have I can do it horizontally but not vertically. I tried vertical-align: middle; but that didn't work and I tried line-height: 73px since the height of the box is 73px. I can't seem to figure a way out of this.
How can I center the image vertically while still retaining the horizontal centering?
Don't make the image a block element. As an inline element you can center it as text. Then set the line height to the same as the box, and set vertical alignment on the image to middle to put it in the middle of the text line:
.box {
border: 1px solid #333;
cursor: pointer;
height: 73px;
margin: 40px 42px 0 0;
width: 269px;
text-align: center;
line-height: 73px;
}
.img_pic {
vertical-align: middle;
}
Demo: http://jsfiddle.net/AwgNy/
You cannot vertical-align block elements.
If you know the height of the image you could put an equal top and bottom margin on .img_plc or an equal top and bottom padding on `.box.'
As you've said it's variable height, then you can use display: table-cell for .box with vertical-align: middle;
If you know the dimensions of the image you can do it in the css and either use margin to push it down:
margin-top:/*(box height / 2) - (image height / 2)*/;
or use relative and absolute positioning:
.box
{
position:relative;
/*other code*/
}
.image_pic
{
position:absolute;
top:/*(box height / 2) - (image height / 2)*/;
}
If you cannot guarantee the dimensions of the image then you should use javascript/jQuery to get the image height and use the same formula as above for working out the offset. Then still using javascript/jQuery, edit the css for the image to set the offset for margin-top or top.
Just Use This CSS DEMO HERE
.box {
border: 1px solid #333;
cursor: pointer;
height: 73px;
margin: 40px 42px 0 0;
width: 269px;
position:relative
}
.img_pic {
display: block;
position:absolute;
top:0px;
left:0px;
right:0px;
bottom:0px;
margin:auto
}
what's the best way to programatically (using HTML, CSS, JavaScript, and/or PHP) round the corners of images?
I'm been playing with this CSS-only method:
http://maxvoltar.com/archive/rounded-corners-on-images-css-only
The key features of this method are:
wrapping the image into an element where you can round the borders and where you can set the wrapper element background as the desired image.
setting the actual image opacity to 0
floating the wrapper left so the image and wrapper line up.
here's the HTML:
<p style="background-image: url(http://upload.wikimedia.org/wikipedia/commons/thumb/2/26/YellowLabradorLooking_new.jpg/260px-YellowLabradorLooking_new.jpg)">
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/2/26/YellowLabradorLooking_new.jpg/260px-YellowLabradorLooking_new.jpg" alt="Dog" />
</p>
here's the CSS:
img {
vertical-align: bottom;
/*width:50px;
height:50px */ /*ideally would be able to alter these as needed*/
}
p {
-webkit-border-radius: 50px;
-moz-border-radius: 50px;
border-radius: 50px;
-webkit-box-shadow: #000 0 2px 10px;
-moz-box-shadow: #000 0 2px 10px;
box-shadow: #000 0 2px 10px;
}
Unfortunately, this code fails when you re-size the images. Please compare the following 2 fiddles to see what I mean:
image NOT manually sized:
http://jsfiddle.net/trpeters1/wxXAn/1/
image set to 50px wide/50px height:
http://jsfiddle.net/trpeters1/wxXAn/2/
Is there a way to rescue this method if you want to preserve the ability to re-size the image width/height? Are there better ways than this method?
UPDATE
thanks to Tom (see below), this question is solved. The key to enabling re-sizing is to set BOTH the image and wrapper heights and widths to the same size. Please see this fiddle and compare with the one's above to see what I mean: http://jsfiddle.net/trpeters1/wxXAn/13/
Please note in this fiddle that the <p> AND <img> tags height and widths are BOTH set to 50px.
I managed to get it to work by using the following code
p {
float: left;
-webkit-border-radius: 50px;
-moz-border-radius: 50px;
border-radius: 50px;
-webkit-box-shadow: #000 0 2px 10px;
-moz-box-shadow: #000 0 2px 10px;
box-shadow: #000 0 2px 10px;
background-size:50px 50px;
}
I added the background-size:50px 50px; tag and you then get the small dog with the rounded corners.
Hope this is what you are after.
Thanks