Started playing around with SVG and am having trouble getting it to position the way i want to. What I want to achieve is for my SVG to come in front and locked to the bottom of the border-div and be centered on the page as well as resize when the window is resized (responsive). So far I've played with the viewbox and height/width properties of the SVG to get the responsive behavior but I can't figure out to not have the SVG slip under the rest of my page(see picture to have a better idea of what's hapenning). I tried to play with the z-index and position:absolute but to no avail. Here's what I have so far for my code: (I use the bootstrap framework with SASS)
HTML
<section>
a first section
</section>
<section class="parallax1">
<div class="container-fluid">
<div class="row">
<div style="height:500px;">
<div class="col-sm-12 border-div">
<div class="col-sm-12">
<svg xmlns="http://www.w3.org/2000/svg" class="svg-test" viewBox="0 0 500 375">my SVG</svg>
</div>
</div>
</div>
</div>
</div>
</section>
<section>
Another section
</section>
CSS
.border-div{
height:100px;
background-color: $orange-background;
}
.svg-test{
left: 50vw;
width: 100%;
height: 600px;
}
.parallax1{
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
background-image: url("../images/bkgnd.jpg");
}
What i get right now is something like this:current result
And what I am looking for is this:desired result
Preliminary remarks
A few remarks about your problem, which may also explain why you haven't received any answers in such a long time:
Your problem is about the positioning of an SVG image in an HTML document. Playing around with ViewBox won't solve your problem, as this merely dictates what the SVG image should show, and not how the SVG image should be positioned within a parent document, in this case a HTML document. In fact, you could replace the SVG image with a DIV countainer and nothing would change about the solution.
It isn't really clear what you want:
Does come in front and locked to the bottom imply that you want the SVG image to appear when the user scrolls, or with some animation? Or does it mean you want the SVG to be placed there statically, independent of any event?
Does centered on the page mean horizontally only? If you meant also vertically, I don't understand how it should be in relation to the height requirements of the DIVs, or the requiement that it should lock to the bottom of the border-div.
And does resize when the window is resized only mean change its width or also its height? Because you've defined the height as 600px, which clearly won't respond to any resizing of the window.
slip under the rest of my page - I thought the SVG should be on top of everything else?
It's not clear whether the first and the last sections should have a stable width, or be responsive. And how they should relate to the 500px. A bit of CSS for them would be good.
So the 100px of border-div should be part of the 500px? In the "screenshots" it doesn't seem like it, but the code you posted suggests so.
Also, there are some inconsistencies in your formulation of the problem:
The width of the SVG is defined as 100%, but your pictures show that it's clearly not 100%. After all, if it were 100%, you wouldn't have to worry about centering it, either.
The height of the SVG is defined as 600px. If that was the case, it would be taller than the parent DIV, which is only 500px. The pictures show something different.
Last but not least, left: 50vh will make your SVG start at the horizontal center of the page, and not center it. If you want to center it, it should be (100% - width)/2 and not 100%/2.
Possible solution
In any case, here's the HTML code and the accompanying CSS styles to get what I (possibly incorrectly) interpret you are asking for:
<section id="first">
A first section
</section>
<section id="height-500">
<div id="border-div">
<div id="relative">
<div id="bottom">
<svg>
</svg>
</div>
</div>
</div>
</section>
<section id="another">
Another section
</section>
And here the CSS:
#first,
#another {
background: #808000;
height: 150px;
width: 100%;
height: 150px;
}
#height-500 {
background: green;
height: 500px;
position: relative;
}
#border-div {
background: #008080;
height: 100px;
position: absolute;
bottom: 0;
width: 100%;
}
#relative {
position: relative;
width: 100%;
height: 100%;
}
#bottom {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
svg {
display: block;
background: #f00;
width: 20vw;
height: 20vw;
margin: auto;
}
Explanation of key points
Setting the position: relative of #height-500 allows you to position #border-div at its bottom. This trick will be used again for #relative and #bottom to place the SVG at the bottom of #border-div (setting width and height to 100% allows the dimensions of #relative to be identical to #border-div).
Setting the width and height of the SVG to 20vw indicate that we want the SVG to be a square, each side being 20% of the viewport width. If you change the width of your browser, the SVG will resize too.
margin: auto are used to place block elements in the horizontal center. Note that we need to turn the SVG into a block element for this to work, by setting display: block. (Note that margin: auto doesn't work for really old browsers, but there are workarounds with some additional DIVs.)
If you want the height of the SVG remain the same, you may want to play around with the preserveAspectRatio attribute to indicate you you want to deal with the changing aspect ratio.
Note that the viewport width vw also includes the scrollbar and isn't supported by some older browsers. However, there are other methods of keeping the aspect ratio, in case that's a requirement for you.
Related
Moving from backend to the frontend, I was given a design and don’t know the best way to handle how to implement it. It’s gonna be about 6 or some images or layered. All Images are 1920px wide * X px high.
I did a little fiddle so you can see what I’m working with. A few images are in there too. https://www.bootply.com/EEjlR9IaFN#
So the problem is setting the width and height of the image/div causes it to extend outside of the bootstrap container and it’s not responsive. So that’s where I’m stuck, I can’t think of a way to make these images fit inside of this container and be responsive. I was gonna just use the img tag but would rather do it via css if I can
You can do a little trick that I learned to do the same thing, and it's putting an image behind for the responsive and the background for the front.
HTML:
<div class="element">
<div class="background-image"></div>
<img src="http://via.placeholder.com/1920x1080" class="image-responsive" alt="">
</div>
CSS:
.element{
position: relative;
display: inline-block;
}
.background-image{
background-image: url('http://sharksharkshark.net/snow.png');
background-size: cover;
background-position: center;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.image-responsive{
max-width: 100%;
}
NOTE: You can play and change the size of the back image for the responsive. In this way the div will not be empty but it will be responsive.
Example:
https://jsfiddle.net/grg9rc7z/1/
Is it possible to fill a div with an image such that at least one image dimension is 100% and the other dimension is either wider or equal size as the div, whilst respecting the image's aspect ratio.
An example could use the classes wide and tall like this:
<div class="tall">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/ae/Klaproos.jpg/266px-Klaproos.jpg"/>
</div>
<div class="wide">
<img src="https://groenevrijdag.files.wordpress.com/2013/11/klaproos2.jpg"/>
</div>
div {
width: 400px; height: 400px;
display: block;
overflow: hidden;
border-radius: 50%;
display: inline-block;
}
div.tall img { width: 100%; margin-top: -50%; }
div.wide img { height: 100%; margin-left: -50%; }
https://jsfiddle.net/7tuod6vu/
I'm looking for a pure HTML+CSS solution which works for responsive rectangular (not necessarily square) divs. For this particular reason, Javascript would be a pain as one would need to determine whether the width or height should be 100% on every resize. Server side wouldn't even be an option.
Does a pure HTML+CSS solution exist for this?
EDIT Should have been clear about this from the beginning, sorry about that :( I'm not looking for the background-image solution, since it does not allow base64-inhtml representation of images. Moreover, I think background-image's are semantically different from <img>s.
Consider using the CSS object-fit property.
5.5. Sizing Objects: the object-fit
property
The object-fit property specifies how the contents of a replaced
element should be fitted to the box established by its used height and
width.
Here are two of the values:
cover
The replaced content is sized to maintain its aspect ratio while
filling the element's entire content box.
contain
The replaced content is sized to maintain its aspect ratio while
fitting within the element's content box.
So, with cover the image retains its aspect ratio and covers all available space. Of course, this means that much of an image may be cropped off-screen.
With contain the aspect ratio is also maintained, but the image scales to fit within the box. This means that an image may have whitespace on the left and right, or top and bottom.
Browser Compatibility
As of this writing, object-fit is not supported by Internet Explorer. For a workaround see:
Neat trick for CSS object-fit fallback on Edge (and other browsers)
fitie - An object-fit polyfill for Internet Explorer
object-fit-images - Adds support for object-fit on IE9, IE10, IE11, Edge and other old browsers
Polyfill (mostly IE) for CSS object-fit property to fill-in/fit-in images into containers.
More information
MDN object-fit property
CSS-Tricks object-fit property
object-fit browser support # caniuse.com
Here is the solution without using background images and with HTML and CSS only: http://codepen.io/anon/pen/JGGObQ
(change overflow to visible in the .container1 rule to see the full pictures. The numbers in them are their original size in pixels.)
It uses position: absolute on the images, and depending on the format (two classes, as suggested by yourself) a top or left of 50% that moves the position reference into the (horizontal or vertical) center, and a transform : translate setting that moves the position reference point of the image back from that center by 50% of their own size, which results in centering:
.container1 {
position: relative;
float: left;
margin-right: 50px;
width: 400px;
height: 400px;
border-radius: 50%;
overflow: hidden;
border: 1px solid red;
}
img.landscape {
position: absolute;
width: auto;
height: 100%;
transform: translate(-50%, 0);
left: 50%;
}
img.portrait {
position: absolute;
width: 100%;
height: auto;
transform: translate(0, -50%);
top: 50%;
}
<div class="container1">
<img src="http://placehold.it/750x500/09d/fff" class="landscape">
</div>
<div class="container1">
<img src="http://placehold.it/600x900/0d9/fff" class="portrait">
</div>
This is not the exact solution, but it could be an implementation that you could try to make your code work. Here is an example:
As you can't predict the aspect ratio of the image here is what I would do:
HTML:
Set the div tag to 'fill':
<div class="fill"></div>
CSS:
This will place your image as the background, and stretch it to fit the div size without distortion.
.fill {
overflow: hidden;
background-size: cover;
background-position: center;
background-image:"path/to/image.jpg";
}
You could set the images as the div's backgrounds instead and use backkground-size:cover
https://jsfiddle.net/3x5x0v24/
I have seen the layout similar to the image below used on some sites before and I really like the design but don't exactly know how to implement the overlapping image (Profile Image). I am using bootstrap if that helps. Any ideas?
Thanks!
I can see three ways to do this generally.
position: absolute
You could give the image or the image's wrapper the attribute of position:absolute and giving its container (in your example the green box) position:relative. Then you would apply top: -100px or whatever and a left attribute of left: 100px or whatever. This gives the effect of the image being out of flow, aligned to the left and offset by 100px, and 100px offset from the top of the green container. The disadvantage of this approach would be that any body content in your green container could appear under the image.
position: relative
This is the same approach as the first one with the exception of how the image flows in the document. Instead of giving the image position:absolute, you would give it position:relative. Relative works differently from absolute. instead of being x and y coordinates of the parent container, it's just shifted by however much you give as a value for top and left. So in this case, you would apply top:-100px and just leave the other directional values as default. this would shift your element by that amount but also leave its original spot in the document flow. As such you end up with a gap below the image that other content will flow around.
negative margin
I honestly would prefer this method in your case. In this method, you can give the image a negative margin (e.g. margin-top:-100px). This will offset the image, collapse the area below the image, and it will still retain some of its flow in the document. This means that the content of the green container will flow around the image but only around the part that is still inside the container. It won't have a ghost area that content flows around like with relative positioning, but it also doesn't entirely take the image out of flow like absolute positioning. One thing to keep in mind, however, is that if you try to use overflow of any kind other than the initial value, it will cause undesirable effects to your image.
Demo
Here's a quick little demo demonstrating all three methods in a simple use case: http://jsfiddle.net/jmarikle/2w4wqfxs/1
The profile image can be set with position: absolute; top: 20px; left: 20px, or something like that to keep in from taking up space in the flow of the page.
make the html element that holds the header image "position:relative". Then put the header image and the profile image in that element. then make the profile image "position:absolute" and utilize "top: XXpx" depending on how far you want it from the top of the header element. Same for "left".
see fiddle here
<div class="header">
<img src="" alt="my image" class="floatdown">
this is my header, image could go here too
</div>
<div class="body">
this is my body content
</div>
.header {
position: relative;
width: 100%;
height: 150px;
border: 2px solid #000;
text-align: right;
}
.body {
position: relative;
width: 100%;
border: 2px solid #000;
height: 500px;
text-align: right;
}
img {
width: 90px;
height: 90px;
border: 2px solid #ddd;
}
.floatdown {
position: absolute;
top: 100px;
left: 20px;
}
You can use the float property on your profile image to take it out of the "flow" of the document, and play with the margins to place it properly.
CSS :
#profile-image{
width: 100px;
height: 100px;
float: left;
margin: 100px;
}
The marginis used to push it down and place it properly.
You can see an example of this in a Fiddle : http://jsfiddle.net/y706d77a/
I wouldn't recommand using position: absolute as you can get very strange results with different resolutions. I would only use that as a last resort.
This can be done many ways.
Anytime you see something like that on the web you can just use your inspector or firebug and see how they are doing it to get some ideas.
It wouldn't hurt to do some research on the web about CSS positioning.
http://www.w3schools.com/css/css_positioning.asp
Another great site.
http://css-tricks.com/
I just finished it.
Here is a codepen link:
http://codepen.io/anon/pen/zxYrxE
HTML:
<div class="main-container">
<div class="header">
<p>This is the header div</p>
</div>
<div class="profile">
<p>Profile</p>
</div>
<div class="content">
<p>Some dummy content div</p>
</div>
</div>
CSS is to big to be pasted here, so just open the link.
Put the profile image in the header, make the position: absolute; and the image position: relative;, and give it a negative bottom value that's half the height of the image, and set left to position it horizontally to taste.
HTML
<header>
<img class="profile">
</header>
<div>Content</div>
CSS
header, div{
min-height: 110px;
background: darkgray;
}
header{
position: relative;
background: gray;
}
img{
position: absolute;
bottom: -50px;
left: 100px;
}
http://jsfiddle.net/dekqn84c/
(Source:http://imgur.com/5pKaiea.)
Hey I basicly got two of the files above one "header" and one "footer" both same size kinda just flipped.
The problem is the width doesn't fit on page, any ways other than background-image: cover?
The file is basicly 1280 px wide and around 114 px tall.
div #header {
background-image:url(../img/webclient_header.png);
height: 114px;
width: initial;
margin: 0; /* If you want no margin */
padding: 0; /*if your want to padding */
}
In CSS you can use the property background-size to resize the image to fit:
div #header {
background-image:url(../img/webclient_header.png);
background-size:800px 114px; /* Choose your size here W x H */
height: 114px;
width: initial;
margin: 0; /* If you want no margin */
padding: 0; /*if your want to padding */
}
UPDATE: Checkout the code update on jsfiddle http://jsfiddle.net/bKZ8N/
If you're looking to have responsive images on your website, background-image is not really the best path to take. You'd need to either use may CSS media queries to serve different background images sizes or use something like background-size property which is not compatible with older browsers.
I would suggest doing something like this:
<header>
<img src="you-image.jpg" width="100%" height="auto" />
</header>
That's a lot going on for one header / footer image... I would look into possibly breaking it up.. You can make the center part a set width of the whole site that would essentially contain the menu. Then after that you would cut a 1px width (x-value)px height and use that as a repeating background behind your header div. The other elements can be strategically planned to be added to other portions of the site to better reflect the image.
Not a great answer, but it is what I would do in this situation. Otherwise you're looking at the image being stretched and possibly lose some focus.
EDIT:
To answer your question in comments
Kind of...
So you would have at least 3 images header_middle_piece.jpg (the middle of the image that is pointing "down"), footer_middle_piece.jpg (the rotated version of header.), and repeating_pattern.jpg
From there you would have your leveled layout.
<div id="header">
<div id="container">
<div id="content"></div>
</div>
</div>
Use the same type of layout for your footer.
#header{
width: 100%;
background: url('repeating_pattern.jpg') repeat 0 0 scroll transparent;
height: 20px; // Make this the height of the pattern you are using.
}
#container{
background: url('header_middle_piece.jpg') no-repeat 0 0 scroll transparent;
height: 40px; // height of the middle piece.
width: 200px; // width of middle piece
margin: 0 auto; // center the container.
}
Those are the only styles you need to get that working in the whole. After wards you would need to target the background for the repeating background of those stripes if you still do those, and make a div for the other shapes. If you didn't make this image you will have a hard time breaking it up. But it is doable.
For example, I want this page to have the footer fill to the bottom of the page, but I want this page to behave how it does now - so the footer cannot be fixed. I'd prefer to not use JS simply because $(window).resize() is expensive and performance is a concern for us.
Our lowest supported browser is IE9, Firefox 13, Chrome 16 and Safari 5 so I'm not concerned about using a more advanced solution, though probably not bleeding-edge.
You can't - you have to either calculate the window height and footer top offset (which involves JS), or fix the position of the element to bottom: 0.
You could make the page background color match the footer color, and instead of using the graphic as the background for the whole page, make it only for the content area.
so put the background on main-content-container
and make the body background color #EBEBEB
Here is a way to do it, but it does bring other problems with it. You will need to set a min-height and make sure your content does not exceed that min-height or it may get cut off and all text must be at the top of the second div.
The css:
body,html
{
width: 100%;
height: 100%;
}
div#wrapper
{
overflow: hidden;
height: 100%;
min-height: 600px;
}
div#one
{
background-color: #0ff;
height: 200px;
}
div#two
{
height: 100%;
background-color: #f00;
}
The html:
<div id="wrapper">
<div id="one"></div>
<div id="two"></div>
</div>
So the content on the bottom, would not be able to exceed 400px in height in this example. But, if it was larger than that it would be filled in by a solid color.