Thank you for getting into this question.
i want to add a border/line that have one side incline that works as a divider between image and title. Below is the screenshot.
here is the html i have right now
<div class="entry-wrap">
<img class="x-img x-img-thumbnail" src="{image-src}" alt="Place Alt Text Here">
<div class="cut-border"></div>
<div class="x-recent-posts-content">
<h5>Title</h5>
</div>
Thank you so much for your effort.
Its possible using css, but it would probably be easier if you added that border in photoshop or something and insert it on your page
Note: The shape I use in these example does not match the one in the question. Mainly in that the shape on the question does not go down to the corner. Another difference is that I used a fixed height to define the "border" (it measures 5px vertically everywhere) while the one in the question seems to have a fixed width that takes into account the angle on the "stroke". These are details that make the construction of the polygons a bit more complicated, yet do not invalidate the presented approaches.
CSS Clip-Path
What you want can be done using CSS Clip-Path. Which, by itself will make the cut you want in the image, and also will make the cuts in the div that stands in for border.
Some tweaks are necesary to place the objects ontop of each other (clip path does not affect box sizing).
img {
width:250px;
height:250px;
-webkit-clip-path: polygon(100% 0, 100% 100%, 75% 75%, 0 75%, 0 0);
clip-path: polygon(100% 0, 100% 100%, 75% 75%, 0 75%, 0 0);
display:block;
}
.cut-border {
width:250px;
height: calc(250px * 0.25);
background-color: red;
-webkit-clip-path: polygon(75% 0, 100% calc(100% - 5px), 100% 100%, 75% 5px, 0 5px, 0 0);
clip-path: polygon(75% 0, 100% calc(100% - 5px), 100% 100%, 75% 5px, 0 5px, 0 0);
position:relative;
top: calc(250px * -0.25);
}
.x-recent-posts-content {
position:relative;
top: calc(250px * -0.5);
}
<div class="entry-wrap">
<img src="http://lorempixel.com/250/250/city/" alt="lorempixel"><div class="cut-border"></div>
<div class="x-recent-posts-content">
<h5>Title</h5>
</div>
</div>
One drawback I see is that it does not get pixel perfect cuts (you can see the pieces do not match perfectly, this deffect may or not be visible depending on zoom level). It is possible to hide it, I did not do any of that in the examples above.
Another drawback is that will not work in IE or Edge.
See browser support.
SVG
Instead of trying to solve this with CSS, we can have a stab at it with SVG:
.x-recent-posts-content {
position:relative;
top: calc(250px * -0.25);
}
<svg width="250" height="250" viewBox="0 0 250 250" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="img" patternUnits="userSpaceOnUse" width="250" height="250">
<image xlink:href="http://lorempixel.com/250/250/city/" x="0" y="0" width="250" height="250" />
</pattern>
</defs>
<polygon fill="url(#img)" points="250,0 250,250, 187.5,187.5 0,187.5 0,0"></polygon>
<polygon fill="#f00" points="187.5,187.5 250,245 250,250 187.5,192.5 0,192.5 0,187.5" />
</svg>
<div class="x-recent-posts-content">
<h5>Title</h5>
</div>
See browser support.
Related
A very simple example:
HTML:
<body>
<img class="test" src="https://images.unsplash.com/photo-1453728013993-6d66e9c9123a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8bGVuc3xlbnwwfHwwfHw%3D&auto=format&fit=crop&w=600&q=60" />
</body>
CSS:
.test:hover, .test:focus {
clip-path: polygon(70% 0, 100% 30%, 100% 100%, 0 100%, 0 0);
}
Whenever I hover on the image the animation works fine but when I hover on the clip path it breaks and the full image is displayed, which is wrong. Kindly help me to maintain the animation while I hover on the clip path as well.
I want to achieve the below animation on hover, which is working:
But when I try to hover my mouse towards the below direction, the animation hides but I want that the animation should be maintained.
Put image in container then use hover on container with image
.test {
width: fit-content;
height: fit-content;
}
.test:hover .img {
clip-path: polygon(70% 0, 100% 30%, 100% 100%, 0 100%, 0 0);
}
<body>
<div class="test">
<img class="img" src="https://images.unsplash.com/photo-1453728013993-6d66e9c9123a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8bGVuc3xlbnwwfHwwfHw%3D&auto=format&fit=crop&w=600&q=60" />
</div>
</body>
You can use mask if you don't want an extra wrapper:
img:hover {
-webkit-mask: linear-gradient(-145deg,#0000 15%,#000 0);
}
<img class="test" src="https://images.unsplash.com/photo-1453728013993-6d66e9c9123a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8bGVuc3xlbnwwfHwwfHw%3D&auto=format&fit=crop&w=600&q=60" >
There's lots of techniques that cover the simplicity of the question, here are my requirements:
I'd like an <hr /> element to be visible, with a portion of it cut out (e.g.; fully transparent)
The width of the <hr /> is unknown
The cutout region has fixed dimensions and must be centered on top of the <hr />
Use 1x <hr /> element
Supported in IE11 and Safari 11, as well as modern browsers
Due to the browser support, I think I am left with using clipPath within an SVG and setting that as the clipping region via CSS on the <hr /> element.
The following demo is not tested in IE/Safari yet and it highlights my attempts to firstly draw an SVG shape with a portion cut out. That part is nearly fine apart from my requirements #2 and #3 because I don't yet have a fluid filling path with a fixed and centred second path inside it.
Requirement #1 currently fails completely, when I convert the path inside the SVG into a clipPath and then assign that to the hr /> element.
Codepen demo: https://codepen.io/davewallace/pen/WNNRMoR
Markup:
<p>1. Aspect ratio in action, box is correctly centered, but I need the black region to stretch all the way to the far left and right edges, leaving the inner cut-out box in the middle.</p>
<div>
<hr />
<svg xmlns="http://wwww3org/2000/svg" height="32" width="100%" viewBox="0,0,10,10">
<path d="M 0,0 h 10 v 10 h -10 z
M 2,2 v 6 h 6 v -6 z" />
</svg>
</div>
<p>2. So I tried removing the aspect ratio. That sort of helped, but I need the inner cut-out box to be a fixed width and centered.</p>
<div>
<hr />
<svg xmlns="http://wwww3org/2000/svg" height="32" width="100%" viewBox="0,0,10,10" preserveAspectRatio="none">
<path d="M 0,0 h 10 v 10 h -10 z
M 2,2 v 6 h 6 v -6 z" />
</svg>
</div>
<p>3. Regardless of the stretching accuracy of the two techniques above, I expected the supplied paths, converted into a clipPath, to hide the centre part of the HR element, leaving only its left/right sides visible.</p>
<div>
<hr class="clipped" />
<svg xmlns="http://wwww3org/2000/svg" height="32" width="100%" viewBox="0,0,10,10">
<defs>
<clipPath id="square">
<path d="M 0,0 h 10 v 10 h -10 z
M 2,2 v 6 h 6 v -6 z" />
</clipPath>
</defs>
</svg>
</div>
CSS (mostly to illustrate):
div {
position: relative;
border: 1px solid red;
margin: 50px;
padding: 20px;
background: #999;
}
hr {
height: 5px;
background: lime;
&.clipped {
clip-path: url(#square);
}
}
svg {
position: absolute;
left: 0;
top: 20%;
border: 1px dotted red;
}
Research so far:
https://css-tricks.com/clipping-masking-css/
https://css-tricks.com/cutting-inner-part-element-using-clip-path/
How can I cut one shape inside another?
Alternative approaches so far:
Use flexbox and have 1 <hr />, a gap, and then another element like a <div /> finishing off the second half of the effect. So it's not 'cutting a hole' in the <hr /> but stopping and starting it visually. This approach, in my context, would need some magic numbers and isn't so clean. Pretty sure it's still accessible in that I am still using 1x <hr /> element mostly as it is intended to be used.
Nothing else so far, but this is to achieve a "fancy horizontal rule" effect, where someone can drop their image/SVG asset into the middle of the horizontal rule without worrying about the horizontal line going under the asset. I also don't know what the page background colour is, no assumptions can be made about that.
Thank you!
I suppose your hr element will have a solid coloration as background. Considering this you can play with background to coloration to color only the needed part keeping the middle on transparent.
I will rely on calc() that should work on IE11 but I cannot test it.
hr {
height:10px;
margin:10px 0;
border:none;
background:
linear-gradient(blue,blue) left,
linear-gradient(blue,blue) right;
background-size:calc(50% - 10px) 100%; /* Cut 20px from the middle */
background-repeat:no-repeat;
}
body {
background:pink;
}
<hr>
You can also add some border if you want to have a hole in your element:
hr {
height:20px;
margin:10px 0;
border-top:10px solid blue;
border-bottom:10px solid blue;
background:
linear-gradient(blue,blue) left,
linear-gradient(blue,blue) right;
background-size:calc(50% - 10px) 100%; /* Cut 20px from the middle */
background-repeat:no-repeat;
}
body {
background:pink;
}
<hr>
Just use clip-path and calc().
I used this tool to make a relative path, and then I added manually the calc().
https://bennettfeely.com/clippy/
hr {
clip-path: polygon(0% 0%, 0% 100%, calc(50% - 10px) 100%, calc(50% - 10px) calc(50% - 10px), calc(50% + 10px) calc(50% - 10px), calc(50% + 10px) calc(50% + 10px), calc(50% - 10px) calc(50% + 10px), calc(50% - 10px) 100%, 100% 100%, 100% 0%);
height:40px;
background: black;
}
body {
background: url(http://placekitten.com/200/300);
margin: 10px;
}
<hr>
I am working on svg image (as shown in the screenshot marked by an arrow having four triangles) html code as show below belonging to the webpage in which I want to increase the height of it.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<style>.path-one,.path-two{fill-rule:evenodd;clip-rule:evenodd;fill:#00afc9}.path-two{opacity:.4;fill:#93c83d}</style>
<path class="path-one" d="M30 30H0V0"></path>
<path class="path-two" d="M0 30V0h30"></path>
</svg>
I tried adding inline width="150px" and height="150px" in svg tag but it doesn't seem to work.
Problem Statement:
I am wondering what changes I should make in the code above so that the height of the svg image gets changed
You can achieve the same result using CSS and it will be easier to handle:
.box {
display:inline-block;
width:150px;
height:150px;
background:
linear-gradient(to top left ,transparent 49.3%,rgb(147, 200, 61,0.4) 50%),
linear-gradient(to bottom left,transparent 49.3%,#00afc9 50%);
}
<div class="box">
</div>
You can also integrate it as background for your black bar:
.box {
height:60px;
background:
linear-gradient(to top left ,transparent 49.3%,rgb(147, 200, 61,0.4) 50%),
linear-gradient(to bottom left,transparent 49.3%,#00afc9 50%),
#000;
background-size:60px 100%;
background-repeat:no-repeat;
}
<div class="box">
</div>
apply it on the svg element:
svg { width: 150px; height: 150px }
Please note that, the svg image is actually taking the height and width that you want to set by using height and width properties only. The problem however lies in you paths. You can add a background-color to svg element to verify that it actually is changing the height and width.
<svg xmlns="http://www.w3.org/2000/svg" height="300" width="150"
viewBox="0 0 30
30" enable-background="new 0 0 311.7 311.5">
<path fill="red" class="path-one" d="M30 30H0V0"></path>
<path fill="blue" class="path-two" d="M0 30V0h30"></path>
</svg>
<!-- CSS Code-->
<style>
svg {
background-color: black;
}
</style>
A handly website to quickly play around SVG images is :
https://www.rapidtables.com/web/tools/svg-viewer-editor.html
Make good use of it.
I've got some layers of divs with svg backgrounds. Set at 100% width and auto height:
<div class="group section hot-bonus">
<div class="layer layer-base clouds"></div>
<div class="layer layer-back1 clouds-1"></div>
<div class="layer layer-back2 clouds-2"></div>
<div class="layer layer-back3 clouds-3"></div>
<div class="layer layer-back5 bg"></div>
</div>
The .group has these styles:
height: 65%;
z-index: 8;
text-align: center;
All of the clouds follow this format:
.clouds {
z-index: 6;
background: url(../images/hot_bonus_clouds.svg) center bottom no-repeat;
background-size: 100% auto;
#include transform( scale(1.1) );
}
The result is this (full width browser screenshot):
However, I can't seem to get it working on IE10. This is what it's giving me (never mind the design/layout differences, just the unstretched cloud backgrounds):
And this is despite IE10 showing that they have the style background-size: 100% auto; applied.
Any ideas what's going on?
Answer found here: https://stackoverflow.com/a/22970897/1192861
Be sure that your SVG has a width and height
I generated my SVG's from illustrator, I had to open them up again and set a width/height for each one. A really quick way to set it was to pay attention to this part of the svg element:
viewBox="0 0 1428.5 521.8" where 1428.5 is the width and 521.8 is the height. So the fix makes sure the SVG element looks something like this:
<svg viewBox="0 0 1428.5 521.8" width="1428.5" height="521.8"....>/***/</svg>
Let's say I want a way to display just the the center 50x50px of an image that's 250x250px in HTML. How can I do that. Also, is there a way to do this for css:url() references?
I'm aware of clip in CSS, but that seems to only work when used with absolute positioning.
As mentioned in the question, there is the clip css property, although it does require that the element being clipped is position: absolute; (which is a shame):
.container {
position: relative;
}
#clip {
position: absolute;
clip: rect(0, 100px, 200px, 0);
/* clip: shape(top, right, bottom, left); NB 'rect' is the only available option */
}
<div class="container">
<img src="http://lorempixel.com/200/200/nightlife/3" />
</div>
<div class="container">
<img id="clip" src="http://lorempixel.com/200/200/nightlife/3" />
</div>
JS Fiddle demo, for experimentation.
To supplement the original answer – somewhat belatedly – I'm editing to show the use of clip-path, which has replaced the now-deprecated clip property.
The clip-path property allows a range of options (more-so than the original clip), of:
inset — rectangular/cuboid shapes, defined with four values as 'distance-from' (top right bottom left).
circle — circle(diameter at x-coordinate y-coordinate).
ellipse — ellipse(x-axis-length y-axis-length at x-coordinate y-coordinate).
polygon — defined by a series of x/y coordinates in relation to the element's origin of the top-left corner. As the path is closed automatically the realistic minimum number of points for a polygon should be three, any fewer (two) is a line or (one) is a point: polygon(x-coordinate1 y-coordinate1, x-coordinate2 y-coordinate2, x-coordinate3 y-coordinate3, [etc...]).
url — this can be either a local URL (using a CSS id-selector) or the URL of an external file (using a file-path) to identify an SVG, though I've not experimented with either (as yet), so I can offer no insight as to their benefit or caveat.
div.container {
display: inline-block;
}
#rectangular {
-webkit-clip-path: inset(30px 10px 30px 10px);
clip-path: inset(30px 10px 30px 10px);
}
#circle {
-webkit-clip-path: circle(75px at 50% 50%);
clip-path: circle(75px at 50% 50%)
}
#ellipse {
-webkit-clip-path: ellipse(75px 50px at 50% 50%);
clip-path: ellipse(75px 50px at 50% 50%);
}
#polygon {
-webkit-clip-path: polygon(50% 0, 100% 38%, 81% 100%, 19% 100%, 0 38%);
clip-path: polygon(50% 0, 100% 38%, 81% 100%, 19% 100%, 0 38%);
}
<div class="container">
<img id="control" src="http://lorempixel.com/150/150/people/1" />
</div>
<div class="container">
<img id="rectangular" src="http://lorempixel.com/150/150/people/1" />
</div>
<div class="container">
<img id="circle" src="http://lorempixel.com/150/150/people/1" />
</div>
<div class="container">
<img id="ellipse" src="http://lorempixel.com/150/150/people/1" />
</div>
<div class="container">
<img id="polygon" src="http://lorempixel.com/150/150/people/1" />
</div>
JS Fiddle demo, for experimentation.
References:
clip — note: deprecated.
clip-path (MDN).
clip-path (W3C).
One way to do it is to set the image you want to display as a background in a container (td, div, span etc) and then adjust background-position to get the sprite you want.
Another alternative is the following, although not the cleanest as it assumes the image to be the only element in a container, such as in this case:
<header class="siteHeader">
<img src="img" class="siteLogo" />
</header>
You can then use the container as a mask with the desired size, and surround the image with a negative margin to move it into the right position:
.siteHeader{
width: 50px;
height: 50px;
overflow: hidden;
}
.siteHeader .siteLogo{
margin: -100px;
}
Demo can be seen in this JSFiddle.
Only seems to work in IE>9, and probably all significant versions of all other browsers.
Adjust the background-position to move background images in different positions of the div:
div {
background-image: url('image url');
background-position: 0 -250px;
}
div{
width: 50px;
height: 50px;
background: no-repeat -100px -100px/500% url("https://qce.quantum.ieee.org/2022/wp-content/uploads/sites/6/2022/02/QCE22-250x250-website#1x.jpg")
};
<html>
<head>
</head>
<body>
<div></div>
</body>
</html>