Use part of CSS-Sprite as repeated background image - css

I have a div with a width and height of approximately 300px each. The background of this div should be filled repeatedly with a smaller image of 8px width and 8px height. This smaller image is embedded into a larger sprite image. How can I only use this 8x8 pixel tile to pave the background?
What I've tried so far:
.world {
width: 300px;
height: 300px;
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAIAAABvFaqvAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wcYFjsX3EPV0QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAxklEQVQ4y+2UsQ3CMBBF/0VImYDKFWNQZB28AwOwQ7KOC8agomKCVJ8ituU7GwkhVxFXWT+nF8nvy0JSRFAMye0wqRghxrheTmV+Wx4A9G7BmlpfAi0lswZ0mj2DsiNjLbBx09lRw1oN+m0OAKB7hIQWvFSM43ZY5V7mI88AhB+KZCiZZSiZ9e/RN6BaP1k6MtY2Ry1rPXv01D1yET3qR2ZF+qXX+zMBDJaSuGP1VMXEV/te9q6/G8hV+h2VI2NtrvZn9uzRGzl9Uzsn2uDrAAAAAElFTkSuQmCC') 0 -16px repeat;
}
<div class="world"></div>
In this example code, the shritesheet has a width and height of 24px each. It contains 9 differently coloured points, each of which has a diameter of 7px.
I want that only one single point is used repeatedly as background for the div. However, in this code, the whole picture is repeated instead beginning at the third row of points.
Note, this exemplary spritesheet is only an example. The actual spritesheet is a little more complicated. Replacing the spritesheet
with CSS code is not a solution.

One idea is to consider SVG as background. The trick is to make the image inside the SVG and rely on viewbox to cut the image and show only the needed part then make the whole SVG a pattern for your background.
Simply edit the viewBox to select the pattern you want (x y 8 8 where x,y are equal to [0,8,16])
.box {
width: 100px;
height: 100px;
display:inline-block;
}
.one {
background: url('data:image/svg+xml;utf8,<svg viewBox="16 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAIAAABvFaqvAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wcYFjsX3EPV0QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAxklEQVQ4y+2UsQ3CMBBF/0VImYDKFWNQZB28AwOwQ7KOC8agomKCVJ8ituU7GwkhVxFXWT+nF8nvy0JSRFAMye0wqRghxrheTmV+Wx4A9G7BmlpfAi0lswZ0mj2DsiNjLbBx09lRw1oN+m0OAKB7hIQWvFSM43ZY5V7mI88AhB+KZCiZZSiZ9e/RN6BaP1k6MtY2Ry1rPXv01D1yET3qR2ZF+qXX+zMBDJaSuGP1VMXEV/te9q6/G8hV+h2VI2NtrvZn9uzRGzl9Uzsn2uDrAAAAAElFTkSuQmCC" x="0" y="0" height="24" width="24" /></svg>') repeat;
}
.two {
background: url('data:image/svg+xml;utf8,<svg viewBox="16 8 8 8" width="8" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAIAAABvFaqvAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wcYFjsX3EPV0QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAxklEQVQ4y+2UsQ3CMBBF/0VImYDKFWNQZB28AwOwQ7KOC8agomKCVJ8ituU7GwkhVxFXWT+nF8nvy0JSRFAMye0wqRghxrheTmV+Wx4A9G7BmlpfAi0lswZ0mj2DsiNjLbBx09lRw1oN+m0OAKB7hIQWvFSM43ZY5V7mI88AhB+KZCiZZSiZ9e/RN6BaP1k6MtY2Ry1rPXv01D1yET3qR2ZF+qXX+zMBDJaSuGP1VMXEV/te9q6/G8hV+h2VI2NtrvZn9uzRGzl9Uzsn2uDrAAAAAElFTkSuQmCC" x="0" y="0" height="24" width="24" /></svg>') repeat;
}
.three {
background: url('data:image/svg+xml;utf8,<svg viewBox="8 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAIAAABvFaqvAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4wcYFjsX3EPV0QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAxklEQVQ4y+2UsQ3CMBBF/0VImYDKFWNQZB28AwOwQ7KOC8agomKCVJ8ituU7GwkhVxFXWT+nF8nvy0JSRFAMye0wqRghxrheTmV+Wx4A9G7BmlpfAi0lswZ0mj2DsiNjLbBx09lRw1oN+m0OAKB7hIQWvFSM43ZY5V7mI88AhB+KZCiZZSiZ9e/RN6BaP1k6MtY2Ry1rPXv01D1yET3qR2ZF+qXX+zMBDJaSuGP1VMXEV/te9q6/G8hV+h2VI2NtrvZn9uzRGzl9Uzsn2uDrAAAAAElFTkSuQmCC" x="0" y="0" height="24" width="24" /></svg>') repeat;
}
<div class="box one"></div>
<div class="box two"></div>
<div class="box three"></div>

Related

SVG ClipPath: Why does applying the clip path to a DIV have different results to an IMAGE?

I need to create a set of 3 triangles that each have content in them (images, copy, etc).
I have setup this Pen to show roughly what I'm trying to achieve: https://codepen.io/andystent/pen/OJyNdmB
And here is an image for quick reference:
In this example the "Top" and "Left" triangles are IMAGES with the clip-path applied and displaying perfectly.
The "Right" triangle (with the red background) is a DIV with the clip-path applied but the proportions are wrong.
It should look like a mirrored version of the "Left" triangle.
When I apply it to an image it is perfect but when I apply to the div it is not. What is the best way to do this?
I am new to SVG so it is extremely likely that I am not doing this correctly. I have looked at numerous posts and the method I have tried is from a few of those but without success... so now I'm reaching out to you geniuses...
Here's the HTML and CSS for the red "Right" triangle with the clip applied to the DIV in the CSS:
#right-wrapper {
position: absolute;
width: 50%;
height: 100%;
right: 0;
padding: 40px 20px;
box-sizing: border-box;
}
#right-content-div {
background-color: red;
height: 100%;
width: 100%;
position: absolute;
top: 0;
right: 0;
clip-path: url(#clip-path-right);
-webkit-clip-path: url(#clip-path-right);
display: flex;
justify-content: center;
align-items: center;
}
<div id="right-wrapper">
<svg width="100%" height="100%" viewBox="0 0 1220 1214" preserveAspectRatio="none">
<defs>
<clipPath id="clip-path-right">
<path d="M1232,1212.58943 L1232,4.82844551 C1232,3.17159126 1230.65685,1.82844551 1229,1.82844551 C1228.53907,1.82844551 1228.08435,1.93465364 1227.67111,2.13882722 L18.145562,599.743544 C13.1941115,602.189966 11.1633848,608.187127 13.6098071,613.138577 C14.582638,615.107544 16.1765951,616.701501 18.145562,617.674332 L1227.67111,1215.27905 C1229.15654,1216.01298 1230.95569,1215.40376 1231.68962,1213.91832 C1231.89379,1213.50508 1232,1213.05036 1232,1212.58943 Z" id="path-1">
</path>
</clipPath>
</defs>
<div id="right-content-div" preserveAspectRatio="none">
<h1>test heading</h1>
</div>
<!-- <image clip-path="url(#clip-path-right)" height="100%" width="100%" preserveAspectRatio="none" xlink:href="https://www.w3schools.com/css/klematis_big.jpg" /> -->
</svg>
</div>
----- UPDATE: -----
As suggested in the comments, I have created a simplified Pen that gets to the heart of what I'm trying to achieve and the embedded HTML and CSS is below.
Essentially I am trying to get the red <div> to be clipped exactly like the <image>.
https://codepen.io/andystent/pen/RwWRjLd
#right-content-div {
background-color: red;
height: 100%;
width: 100%;
position: absolute;
top: 0;
clip-path: url(#clip-path-right);
-webkit-clip-path: url(#clip-path-right);
}
<svg width="20%" height="20%" viewBox="0 0 1220 1214">
<defs>
<clipPath id="clip-path-right">
<path d="M1232,1212.58943 L1232,4.82844551 C1232,3.17159126 1230.65685,1.82844551 1229,1.82844551 C1228.53907,1.82844551 1228.08435,1.93465364 1227.67111,2.13882722 L18.145562,599.743544 C13.1941115,602.189966 11.1633848,608.187127 13.6098071,613.138577 C14.582638,615.107544 16.1765951,616.701501 18.145562,617.674332 L1227.67111,1215.27905 C1229.15654,1216.01298 1230.95569,1215.40376 1231.68962,1213.91832 C1231.89379,1213.50508 1232,1213.05036 1232,1212.58943 Z" id="path-1">
</path>
</clipPath>
</defs>
<image clip-path="url(#clip-path-right)" height="100%" width="100%" preserveAspectRatio="none" xlink:href="https://www.w3schools.com/css/klematis_big.jpg" />
</svg>
<div id="right-content-div" preserveAspectRatio="none">
<h1>test heading</h1>
</div>
Here is an idea where I will be using mask instead of clip-path. The main trick to correctly set the viewBox (you already have it in your code) add preserveAspectRatio="none" then have a mask size of 100% 100%
.box {
width:200px;
height:200px;
display:inline-block;
background:red;
}
.mask {
-webkit-mask:url('data:image/svg+xml;utf8,<svg preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1220 1214"> <path d="M1232,1212.58943 L1232,4.82844551 C1232,3.17159126 1230.65685,1.82844551 1229,1.82844551 C1228.53907,1.82844551 1228.08435,1.93465364 1227.67111,2.13882722 L18.145562,599.743544 C13.1941115,602.189966 11.1633848,608.187127 13.6098071,613.138577 C14.582638,615.107544 16.1765951,616.701501 18.145562,617.674332 L1227.67111,1215.27905 C1229.15654,1216.01298 1230.95569,1215.40376 1231.68962,1213.91832 C1231.89379,1213.50508 1232,1213.05036 1232,1212.58943 Z" /> </svg>') 0 0/100% 100%;
mask:url('data:image/svg+xml;utf8,<svg preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1220 1214"> <path d="M1232,1212.58943 L1232,4.82844551 C1232,3.17159126 1230.65685,1.82844551 1229,1.82844551 C1228.53907,1.82844551 1228.08435,1.93465364 1227.67111,2.13882722 L18.145562,599.743544 C13.1941115,602.189966 11.1633848,608.187127 13.6098071,613.138577 C14.582638,615.107544 16.1765951,616.701501 18.145562,617.674332 L1227.67111,1215.27905 C1229.15654,1216.01298 1230.95569,1215.40376 1231.68962,1213.91832 C1231.89379,1213.50508 1232,1213.05036 1232,1212.58943 Z" /> </svg>') 0 0/100% 100%;
}
<div class="box mask"></div>
<div class="box mask" style="width:300px;"></div>
<div class="box mask" style="height:300px;"></div>
<img src="https://i.picsum.photos/id/1074/200/200.jpg" class="mask">

Scale SVG clipPath and keep aspect ratio of Image

I have an image inside of an SVG element with a clipPath.
I want the clip path to behave like it is in my codePen https://codepen.io/celli/pen/rNBvmyx with preserveAspectRatio="none" so that I always get the same height for my clipPath which matches the parent and stretch from edge to edge of my browser.
The issue is that I want my image to preserve it's aspect-ratio and not appear squashed, while maintaining that the mask is the only element that is being squeezed and not preserving it's aspect ratio.
I tried adding css to the image to preserve the aspect ratio, but it seems to follow the SVGs preserveAspectRatio="none", but I only want that to apply to my clipPath part of the SVG.
<div id="containerId">
<svg class="svg-graphic" preserveAspectRatio="none" viewBox="0 0 1920 1080" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="auto">
<g>
<clipPath id="svgmask">
<polygon points="0,0 0,650 1920,1045 1920,394 "/>
</clipPath>
</g>
<image clip-path="url(#svgmask)" style="width:100%; height:auto; max-width:100%;" xlink:href="https://img-fotki.yandex.ru/get/5607/5091629.6b/0_612e6_b9039c0d_M.jpg" />
</a>
</svg>
</div>
A solution to your problem would be clipping a div with the image as a background. In this case you use a path instead of a polygon where the coords values are from 0 to 1 and clipPathUnits="objectBoundingBox". This won't work on IE and on Edge: https://caniuse.com/#feat=css-clip-path
*{margin:0;
padding:0;}
#containerId {
width: 100%;
height: 800px;
background-color: green;
}
#media (max-width: 800px) {
#containerId {
width: 100%;
height: 500px;
background: orange;
}
}
.img {
width: 100%;
height: 100%;
background-image: url("https://img-fotki.yandex.ru/get/5607/5091629.6b/0_612e6_b9039c0d_M.jpg");
background-size: cover;
-webkit-clip-path: url(#svgmask);
clip-path: url(#svgmask);
}
<svg height="0" width="0" style="position:absolute;">
<defs>
<clipPath id="svgmask" clipPathUnits="objectBoundingBox">
<path d="M0,0 L0,0.6 1,1 1,0.4"/>
</clipPath>
</defs>
</svg>
<div id="containerId">
<div class="img"></div>
</div>
I found an alternative way to do it that works in IE, without SVG, in-case anyone is interested: https://codepen.io/celli/pen/KKPReKE I wanted to use SVG, but this way seems to be the best solution by using a pseudo element and a rotated div.
<div id="head">
<div id="headAddBkgColor"></div>
</div>
<div id="slantElm"></div>

How to make an svg element responsive to it's parent container?

I'm trying to acheive this:
Rendering an svg square (w:h = 1:1 rectangular) inside of div,
when the div's width is greater than height, the square should fit into the container by the height(red box is the div, green box is the svg square):
When the div's height is greater than width, the squire should fit into the container by the width:
It can be easily achieved by specifying the size of the svg view port.But if I remove the size of the svg view port, instead when I add the size to the parent div(red box), it refuses to look at the height of the container, the image turns to be:
Is there a way we can make the square responsive to the container height?
here is my code:
#main {
width: 400px;
height: 100px;
border: 4px solid red;
}
<div id="main">
<svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid Meet">
<rect x="0" y="0" width="100" height="100" fill="green"/>
</svg>
</div>
Just set the width and height attributes of the SVG to "100%". Either in the SVG, or via CSS.
Secondly, fix your other attributes:
viewBox values should not have commas.
it is preserveAspectRatio, not preserveAspect, and meet, not Meet
#main {
width: 400px;
height: 100px;
border: 4px solid red;
}
<div id="main">
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
<rect x="0" y="0" width="100" height="100" fill="green"/>
</svg>
</div>

Translate a SVG element relative to right of screen?

Is it possible to translate a SVG element relative to the right of the screen as opposed to the top left that is it's default?
<svg class="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<text id="text" class="svgText">test text test text</text>
<rect id="border" class="textOutlineBox" x="0" y="0" width="440.5" height="90"/>
</svg>
#text, #border {
transform-origin: right center;
}
#text {
transform: translate(15vw, 20vh);
}
#border {
transform: translate(10vw, 10vh);
}
When I do this it still moves from the left of the screen. Is there a way to get it to transform relative to the right side of the screen?
jsFiddle describing my problem here!
When you use CSS translate (or translateX or translateY), you don't translate the element relative to the edge of the screen, but relative to where the element would be on the screen, were it not translated.
So if you want to move a SVG rect leftwards from the right of the screen, you first need to position it somewhere near to the right edge of the screen.
One way to do this might be to:
Give the <svg> element a viewBox so you have a parental width to work with
Subtract the width of the element from the width of the viewBox
Apply the value from 2. as the element's x value.
Now, with the rect over towards the right hand edge of the screen, you can translate it leftwards, by giving it a negative translateX value.
Working Example:
body {
margin: 0;
}
svg {
width: 99vw;
border: 1px solid gray;
}
#border {
transform: translate(-10vw, 10vh);
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1000 200">
<rect id="border" x="559.5" y="0" width="440.5" height="90" />
</svg>

Arrow Box with CSS

How can I make this box in CSS?
I've seen a few tutorials that teach how to create boxes with arrows, however, in my case, none of those tutorials are suitable.
I created your element with the surrounding 1px border. I'm using one <div> element and taking advantage of the :before and :after pseudo-elements (browser-support). The main rectangle has a regular 1px border, but the triangle elements are essentially 2 triangles, one darker than the other.
The lighter triangle sits on top of the darker triangle, which has the effect of hiding it, and is shifted slightly to the left to show the darker triangle underneath. The resulting illusion is a 1px dark border on the triangle itself.
Here's a question that asks a similar question:
How can I create a "tooltip tail" using pure CSS?
One of the answers actually has a great explanation of how one can achieve this triangle effect:
https://stackoverflow.com/a/5623150/196921
Also, this is an excellent reference for all the fancy things you can do with borders (thanks to PSCoder):
http://css-tricks.com/examples/ShapesOfCSS/
... and here's a sweet css generator (thanks to David Taiaroa):
http://cssarrowplease.com/
Anyway, here's the corresponding code:
#arrow {
width: 128px;
height: 100px;
background-color: #ccc;
border: 1px solid #999;
position: relative;
}
#arrow:after {
content: '';
position: absolute;
top: 0px;
left: 128px;
width: 0;
height: 0;
border: 50px solid transparent;
border-left: 12px solid #ccc;
}
#arrow:before {
content: '';
position: absolute;
top: 0px;
left: 129px;
width: 0;
height: 0;
border: 50px solid transparent;
border-left: 12px solid #999;
}
<div id="arrow"></div>
Here is the solution I created
There are 2 simple ways to do this. The first, less efficient way is to have 2 elements. I take advantage of the :after pseudo element. I used position:absolute on the :after for 2 reasons.
You can place the element where you need to
It prevents the end of the triangle from being cut off
The key to creating the triangle is using the border property. You have 2 borders with the color of transparent set. These 2 borders are opposite of the direction you want to go. So if you want to make a right triangle, then use top and bottom. What gives the arrow it's shape is the last border. It also goes in the opposite direction. So for a right triangle, you would use border-left with a color. To get this to be the proper height, you must do half of the height of the box you want to place it on
SVG is the recommended way to create such shapes. It offers simplicity and scale-ability.
We can use SVG's polygon or path element to create a shape like above and stroke / fill it with some solid color, gradient or a pattern.
Only one attribute points is used to define shapes in polygon element. This attribute consists of a list of points. Each point must have 2 numbers, an x coordinate and a y coordinate. A straight line is drawn automatically from the last point to the starting point to close the shape.
Below is the necessary code to create this shape:
<polygon points="10,12 265,10 285,93 265,184 10,184"
stroke="#333"
stroke-width="2"
fill="#eee" />
Below is a brief description of the above code:
points attribute defines the structure of the shape.
stroke attribute defines the color for the outline / border.
stroke-width defines the thickness of the outline / border.
fill attribute defines the color for the interior shape to be filled.
Output Image:
Working Example:
body {
background: #b6cdc7 url("https://www.hdwallpapers.net/previews/hot-air-balloon-over-the-mountain-987.jpg") no-repeat;
background-position: center bottom;
background-size: cover;
margin: 0;
}
.box {
justify-content: center;
align-items: center;
height: 100vh;
display: flex;
}
<div class="box">
<svg width="300" height="200" viewBox="0 0 300 200">
<polygon points="10,12 265,10 285,93 265,184 10,184" stroke="#333" stroke-width="2" fill="#eee" />
</svg>
</div>
This shape can be filled with gradient or pattern as well.
Working Example:
body {
background: #b6cdc7 url("https://www.hdwallpapers.net/previews/hot-air-balloon-over-the-mountain-987.jpg") no-repeat;
background-position: center bottom;
background-size: cover;
margin: 0;
}
.box {
justify-content: center;
align-items: center;
height: 100vh;
display: flex;
}
<div class="box">
<svg width="300" height="200" viewBox="0 0 300 200">
<defs>
<linearGradient id="grad">
<stop offset="0" stop-color="#11a798" />
<stop offset="1" stop-color="#23645d" />
</linearGradient>
</defs>
<polygon id="shape" points="10,12 265,10 285,93 265,184 10,184" stroke="#333" stroke-width="2" fill="url(#grad)" />
</svg>
</div>
We can apply shadow on this shape using SVG's filters.
Working Example:
body {
background: #b6cdc7 url("https://www.hdwallpapers.net/previews/hot-air-balloon-over-the-mountain-987.jpg") no-repeat;
background-position: center bottom;
background-size: cover;
margin: 0;
}
.box {
justify-content: center;
align-items: center;
height: 100vh;
display: flex;
}
<div class="box">
<svg width="300" height="200" viewBox="0 0 300 200">
<defs>
<linearGradient id="grad">
<stop offset="0" stop-color="#11a798" />
<stop offset="1" stop-color="#23645d" />
</linearGradient>
<filter id="shadow">
<feGaussianBlur in="SourceAlpha" stdDeviation="4" />
<feMerge>
<feMergeNode />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<polygon id="shape" points="10,12 265,10 285,93 265,184 10,184" stroke="#333" stroke-width="2" fill="url(#grad)" filter="url(#shadow)" />
</svg>
</div>

Resources