Creating picture frame by repeating a smaller image - html

I've started working on an app that does image processing and image cropping, using a library called cropper.js. Right now, I've been tasked with investigation and possible implementation of a feature that would take the cropped image and create a visual representation of how a picture frame would look like.
Example:
The difference is, I'm not able to use already stored images, but have to build this type of image using one piece of image that will look like this:
Along with that, I have to somehow cut the side of the image piece under 45 degree angle to be able to reproduce the desired effect.
How would one go about doing this? I've thought of repeating that image piece a couple of times on all four sides, and then somehow cutting the far side parts of the image under 45 degree angle, but have no idea how to go about this :(
Thanks!

The simplest way with pure CSS is taking advantage of multiple-backgrounds for the main frames using 2 images, one vertical and the other is horizontal.
As for the corners, you only need one image of a transparent 45 degrees cut square texture, which will be used in 4 divs, each one is flipped through transform: scale() and positioned to the sides using position: absolute;
.picframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
url('http://i.stack.imgur.com/wyp42.png'), /* top */
url('http://i.stack.imgur.com/wyp42.png'), /* bottom */
url('http://puu.sh/q3NmA/48c4271f4f.jpg'), /* left */
url('http://puu.sh/q3NmA/48c4271f4f.jpg'); /* right */
background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;
background-position: top left, bottom left, top left, top right;
}
.picframe [class^="corner"] {
background: url(http://i.imgur.com/W0Be4ra.png) no-repeat;
height: 62px; width: 62px;
position: absolute;
}
.picframe .corner-t-l {
top: 0;
left: 0;
}
.picframe .corner-t-r {
top: 0;
right: 0;
transform: scale(-1,1);
}
.picframe .corner-b-l {
bottom: 0;
left: 0;
transform: scale(1,-1);
}
.picframe .corner-b-r {
bottom: 0;
right: 0;
transform: scale(-1,-1);
}
<div class="picframe">
<div class="corner-t-l"></div>
<div class="corner-t-r"></div>
<div class="corner-b-l"></div>
<div class="corner-b-r"></div>
</div>
Pros:
Easy to implement
Responsive
Minimal code
Cons:
Might not be the most accurate
Requires creation of 3 images: vertical, horizontal, corner
Requires knowledge of frame size (for corners height/width)
If a one-piece texture is your only option, then you can flip the background by using CSS transform (90 degrees rotation or mirroring with negative scale scale(1,-1) for the main frames (top, bottom, left, right).
The corners are bit more complicated and can be done by making a div that is rotated 45 degrees and has a child or pseudo selector inside that reverses the parent's rotation then applies the background, then hiding the excess with overflow: hidden on the parent corner container:
:root {
--frame-size: 160px;
}
html,
body {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
}
[class^="frame"] {
background: url("https://i.gyazo.com/6836b6d12cebf4b0fd9a2758ad3a04a9.png");
position: absolute;
/*outline:1px solid rgba(255,0,0,0.5);*/
}
.frame--top,
.frame--bottom {
width: 100%;
height: var(--frame-size);
top: 0;
left: 0;
}
.frame--bottom {
top: auto;
bottom: 0;
transform: scale(1, -1);
}
/* optional shading for realism */
.frame--top::after,
.frame--bottom::after {
content: "";
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: RGBA(0, 0, 0, 0.1);
box-shadow: inset 0px 10px 50px rgba(0, 0, 0, 0.25);
}
.frame--left,
.frame--right {
height: var(--frame-size);
width: calc( 100vh - (var(--frame-size)*2));
z-index: 1;
bottom: 0;
left: 0;
transform-origin: 0% 0%;
transform: rotate(-90deg);
}
.frame--right {
bottom: var(--frame-size);
right: var(--frame-size);
left: auto;
transform-origin: bottom right;
transform: rotate(90deg);
}
[class^="frame--corner"] {
height: calc(var(--frame-size)* 1);
width: calc(var(--frame-size) * 1.425);
background: inherit;
overflow: hidden;
left: 0;
top: 0;
z-index: 1;
transform: rotate(45deg);
transform-origin: 0 0;
}
[class^="frame--corner"]::before {
content: '';
position: absolute;
background: inherit;
height: 100%;
width: 100%;
transform: rotate(-135deg);
right: 0;
top: -50%;
}
.frame--corner--tr,
.frame--corner--br {
right: 0;
left: auto;
transform: rotate(-45deg);
transform-origin: 100% 0%;
}
.frame--corner--tr::before,
.frame--corner--br::before {
transform: rotate(135deg);
}
<div class="frame--top">
<div class="frame--corner--tl"></div>
<div class="frame--corner--tr"></div>
</div>
<div class="frame--bottom">
<div class="frame--corner--bl"></div>
<div class="frame--corner--br"></div>
</div>
<div class="frame--left"></div>
<div class="frame--right"></div>
jsFiddle: https://jsfiddle.net/azizn/cb7feu5p/2/
Pros:
Single image (texture)
Responsive
Frame size can be dynamic
Cons:
Might not be the most accurate
Larger amount of code and 8 HTML tags
For this to work as pure CSS, many calculations use a CSS variable (--frame-size), please be sure to check browser compatibility for CSS variables, transforms and calc() expressions. Otherwise, you will need to run all these operations through JavaScript.

You can use the border-image property for this, it should work perfectly for what you're trying to do. It will use the corners of the image for the corners, and will stretch or repeat what is in-between. You can also define the border-width for each border as normal.
The advantage to this method is that it works just like any normal border, therefore there is no worry about scaling or keeping the content always the same size, it will adapt nicely according to the content.
This is how the code would look like, excluding extra code for full browser support:
border-image: url("border.png") 27 fill repeat;
Here's some handy links for browser support & guides:
http://caniuse.com/#search=border-image (I think partial support issues will not be relevant to your case though, as long as you use the shorthand)
https://css-tricks.com/understanding-border-image/
This site makes it really easy to define your borders from the images, as it can be a bit of a pain to count it all manually:
http://border-image.com/

Related

Place image between 2 divs (centered on screen, responsive and not over text)

I'm trying to place an image between 2 divs on my page. I have currently been able to get an image between the two divs, but it isn't responsive (only in the correct position at 1920 width) and it overlaps the text of both divs:
screenshot from my website
css
.btwimg {
width: 90%;
height: auto;
position: absolute;
transform: translate3d(-20%, -50%, 0);
z-index: 1;
left: 50%;
background: url("../img/lara2.png");
background-repeat: no-repeat;
box-shadow: 0 5px 7px rgba(0,0,0,0.1);
}
html
<div class="btwimg">
<img src="img/lara2.png">
</div>
what I am trying to achieve
Is it possible to achieve what I'm after?
Thanks in advance.
First you have to add the same amount of padding-bottom to the upper DIV and padding-top to the subsequent DIV to create enogh space for your image. (trial and error to find the right amount)
Your btwing DIV should be a child element of the subsequent DIV. Then this CSS should work:
.btwimg {
width: 90%;
height: 250px /* Just a random guess - Needs a fixed height! */
position: absolute;
z-index: 1;
left: 50%;
top: -50%;
transform: translate(-50%, -50%);
background: url("../img/lara2.png");
background-repeat: no-repeat;
box-shadow: 0 5px 7px rgba(0,0,0,0.1);
}
Actually the height setting should be a calc value which is derived from the original width/height proportion and the 90% width you set, like height: calc(9/16 * 90%);if the proportion is 16/9
I took #Johannes answer and tweaked a little to get the result I wanted:
.btwimg {
max-width: 800px;
min-width: 300px;
height: 16vw;
position: absolute;
z-index: 1;
left: 50%;
top: calc(2vw - 38px); /* keeps div roughly centred at all target resolutions */
transform: translate(-50%, -50%);
}
I then used an image rather than a background to make the re-sizing easier.
.btwimg img {
height: auto;
width: 100%;
}
btwimg was put as a child of the 2nd div as recommended
result at mobile resolutions
result at desktop resolutions

Repeating pseudo element issue in all versions of IE

There seems to be an issue in IE 9, 10, 11 and Edge with pseudo elements where if they have a repeating background that is semi-transparent, the first half of the background-image is a lot darker than the rest of the image (almost as if there is overlap between the images). It's fine in all other browsers and seems to be such a unique thing that I couldn't find any references about it anywhere.
The effect that is trying to be achieved is to have an image shown, and a pattern with a certain opacity placed over the top to create a subtle pattern effect. Whilst there are other ways that this could potentially be achieved, this seems to be the easiest way.
Image: Example of what is currently happening.
I made a quick CodePen example. If you look on any version of IE or Edge you'll notice that once the image has been displayed in full already, the second time it is repeated, the first half of the image is noticeably darker than the second half of the image as if that half has a higher opacity on it.
CodePen: Example of the issue with code.
As you can see, the first image with a very basic pattern is fine. The second image though is quite large and has the same issue and I can't figure out what is causing it to do such a thing. Both images are repeating in the exact same way.
This is the code for the pseudo element, nothing out the ordinary in terms of CSS3 attributes or tricks etc.
.element::after {
background-image: url(http://example.com/image.png);
background-repeat: repeat;
width: 100%;
height: 100%;
display: block;
content: "";
opacity: 0.5;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
A very strange bug. No idea why this happens. The problem is in the picture. If you reduce it to 1000px in width, for example, it will work well.
body {
background-color: #232323;
}
.wrap {
width: 100%;
margin: 0 auto;
float: none;
display: block;
}
.slider2 {
width: 100%;
height: 200px;
margin: 10px 0;
padding: 10px;
float: left;
display: block;
box-sizing: border-box;
position: relative;
}
.slider2::after {
content: "";
opacity: 1;
width: 100%;
height: 100%;
display: block;
background-image: url('http://i.imgur.com/tmGMRCB.png');
background-repeat: repeat;
background-position: top left;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
<div class="wrap">
<div class="slider2" style="background-image: url(http://img.wallpaperfolder.com/f/4A4B79479EAC/desert-sand-dunes-u6n12nvy10.jpg); background-position: top center;">
Slider 2
</div>
</div>
Solution: try to change picture.

Trouble with overlaying images in CSS

I'm trying to overlay 5 images that are all the same size, namely 614 w x 814 h. Because parts of each image are transparent, together they make one whole picture. I can't use my original images to show you because they've got personal data on them. Instead I used color blocks to show you an example I've made.
Fiddle
I'm trying to center all of the images in the center of the screen, and it's crucial that they remain there, no matter how far the browser is zoomed in, or if the window is resized. To do that, I use this code per image:
#blue{
margin-top: 10%;
padding-left: 0;
padding-right: 0;
margin-left: auto;
margin-right: auto;
display: block;
width: 33%;
height: 100%;
}
My question is: How do I center these 5 images in the middle of the screen, having all them overlay eachother like so; blue < green < purple < yellow < red. And still keep them positioned so that there's no space between each image, so that they may form one block of five different colors?
Is there an easier, more accurate way of doing this than what I've shown you in the fiddle?
I found out a solution. I used this code per color block, which was what I needed
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%); /* Yep! */
width: 48%;
height: 59%;
Put them all in a single div and center that - Paulie_D
Cenctered container with image(s).
html {
height: 100%;
}
body {
position: relative;
width: 100%;
height: 100%;
margin: 0;
}
.container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.container img {
position: absolute;
top: 0;
left: 0;
}
.container img:nth-of-type(1) {
position: relative;
}
<div class="container">
<img src="http://lorempixel.com/g/100/100" />
<!--place images here!-->
</div>

CSS? How is this arrow made?

This is driving me insane. I've been using the Firefox inspector to try to figure out how this arrow was made (below) on the Headway site.
I've whittled away the code by deleting chunks via the inspector, and got it down to this:
No matter where I inspect, I can not find any such shape. No background image, no glyphs, nothing. It hardly even matters at this point, but I'm pulling my hair out trying to figure out how they did this!
Any CSS gurus care to take a look and chime in? For the sake of learning. :)
It's just a rotated square in the form of a ::before pseudo element.
As you can see, the element is a square (same height/width). The element is absolutely positioned with left: 50% and a negative margin-left of -31px (half the width) for horizontal centering. Finally, transform: rotate(-45deg) is used to rotate the square.
Here is the styling used:
.home-testimonial-wrapper:before
.home-cta-area::before, {
display: block;
width: 62px;
height: 62px;
background: #253031;
position: absolute;
top: -15px;
left: 50%;
margin: 0 0 0 -31px;
z-index: 5;
content: "";
-webkit-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
transform: rotate(-45deg);
}
Aside from this, if you're interested in seeing how to make a triangle using CSS, see this answer.
You can make a triangle by playing with borders of a zero width/height div:
.triangleDiv {
width: 0;
height: 0;
border-style: solid;
border-width: 0 100px 100px 100px;
border-color: transparent transparent #000000 transparent;
}
<div class="triangleDiv"></div>
Just adjust the border-widths to get the size you want. No need for transforms. By adjusting which borders have width, you can 'rotate' the triangle.
The previous answers are good!
Just wanted to add, for design elements like that I always use one of two things.
Pseudo element to create the design feature ( as described above )
Pseudo element containing the design feature as an svg
Hope that helps!
You can do what they've done with rotating the square, but a more common solution is to use the border property:
.example {
position: relative;
}
.example:after {
content: '';
display: block;
position: absolute;
top: 0; /* or wherever */
left: 0; /* or wherever */
border: 10px solid transparent;
border-bottom-color: #000;
}

How to make a background text appear under youtube video?

There is a horizontally centered youtube video on the page, but the problem is that on mobile devices (phones/tablets) it takes time before the the video loads (sometimes 1.5 secs). So during this time the area which is designated for a video appears to be blank. So people might think that there is nothing there and move on.
So I tried to make a background text (underneath the video) saying 'Video is loading'. After looking how to make background text, I found the following answer. I tried both approaches (with ::before and with another div inside, but with no success).
Here is my fiddle with the closest I was able to get. Opacity there is just to see that the text is behind the video. And here is my failed part of CSS (just here because SO reject posts without code and with jsfiddle).
.video-preloader{
position: relative;
text-align:center;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: -1;
overflow: hidden;
}
Since the targeted element, .video-preloader is absolutely positioned, it's important that the parent element, .video is relatively positioned.
.video {
/* .. */
margin:0 auto;
position:relative;
}
In order to vertically/horizontally center the text, you could use the following approach. It works with dynamic text of varying dimensions (example)..
EXAMPLE HERE
.video-preloader {
position: absolute;
top: 0; bottom: 0;
left: 0; right: 0;
z-index: -1;
overflow: hidden;
}
.video-preloader > span {
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
transform: translateY(-50%);
position: absolute;
width:100%;
top: 50%;
left: 0;
}
Alternatively, if you want is a background image with a loading .gif, something like this would work:
EXAMPLE HERE
.video-preloader {
position: absolute;
top: 0; bottom: 0;
left: 0; right: 0;
z-index: -1;
overflow: hidden;
background: url('http://i.stack.imgur.com/w28B4.gif') 50% 50% / 80px 80px no-repeat;
}
You can easily modify the background-position/background-size properties within the shorthand property. In this case, the image is centered with background-position: 50% 50%..