Issues mixing position:absolute with responsive layout - css

I'm not entirely sure what I'm after is possible but at present I have an unordered list when in desktop mode will use display: inline-block to display two images horizontally. However when in tablet/portrait mode, display switches to block to make the unordered list display vertically in the usual manner.
However complicating matters, I have two small background images which I want to overlay over each of the main images. I have used absolute positioning to achieve this however when switching to portrait form (width < 750px), the second main image overlays over the first.
Presumably this is due primarily due to the move away from display: inline-block and the continued use of relative/absolute positioning for the main background image and small background images respectively.
I have remedied this to an extent by giving each li element a specific height (500px), however the intention is that the two lis stick together, when by using a fixed height a gap eventually appears (owing to each li having a width of 100% (so regardless of tablet/phone size, the image will fill the container)).
My first thought was that height: 100% would be suitable but this simply results in the second li overlaying the first.
You can see what I am intending in the below Codepen link if my garbled text is unclear (highly likely). Any guidance on ensuring that the two li elements remain together would be gratefully received. Even if it is to say that the intended effect is not possible! There's also a brief diagram below.
http://codepen.io/grabeh/pen/uInrk
HTML:
<ul class="photo-list">
<li>
<div class="image-holder">
<img src="http://lorempixel.com/500/500"/>
<span><a class="flickr-link"></a></span>
<span class="upvote"></span>
</div>
</li>
<li>
<div class="image-holder">
<img src="http://lorempixel.com/500/501"/>
<span><a class="flickr-link"></a></span>
<span class="upvote"></span>
</div>
</li>
</ul>
CSS:
.photo-list {
list-style: none;
padding: 0;
margin: 0;
}
.photo-list li {
margin: 10px 10px 10px 0;
display:inline-block;
width: 48%;
}
.photo-list li:last-of-type {
margin: 10px 0 10px 0;
}
img {
border: none;
width: 100%;
}
.flickr-link {
background-image: url('http://lorempixel.com/40/40/');
background-repeat:no-repeat;
width: 40px;
height: 40px;
float: left;
z-index: 100;
position: absolute;
}
.image-holder {
position: relative;
}
.image-holder img {
position: absolute;
}
.upvote {
background-image: url('http://lorempixel.com/40/40/');
background-repeat:no-repeat;
width: 40px;
height: 40px;
float: left;
z-index: 100;
position: absolute;
margin-left: 50px;
}
#media handheld, only screen and (max-width: 750px) {
.photo-list li {
display: block;
width: 100%;
height: 500px;
}
}

http://jsfiddle.net/xdXv2/
Your main image doesn't have to be absolute positioned. Only the smaller images do since they have to sit on top of it. Putting your main image back into the document flow will give your list items height again, which means you no longer need to give them a fixed height.
.flickr-link {
background-image: url('http://lorempixel.com/40/40/');
background-repeat:no-repeat;
width: 40px;
height: 40px;
float: left;
z-index: 100;
top:0; /*added this*/
position: absolute;
}
.image-holder {
position: relative;
}
.image-holder img {
/*removed absolute position here*/
}
.upvote {
background-image: url('http://lorempixel.com/40/40/');
background-repeat:no-repeat;
width: 40px;
height: 40px;
float: left;
z-index: 100;
position: absolute;
margin-left: 50px;
top:0; /*added this*/
}
#media handheld, only screen and (max-width: 750px) {
.photo-list li {
display: block;
width: 100%;
/*removed fixed height here*/
}
}

Related

How use CSS sprites?

I'm trying to figure out how to use CSS Sprites on a sprite image with 4 sprites.
I have code to show the first two sprites. I have trouble with writing code to show the last two sprites. I am also unable to show the third and 4th sprites by themselves.
This is the image:
How to show the last two?
How to show the 3rd and 4th sprite by themselves?
HTML
<div class="container">
<ul>
<li id="belt-1"></li>
<li id="belt-2"></li>
<li id="belt-3"></li>
<li id="belt-4"></li>
</ul>
</div>
CSS
.container {
position: relative;
width: 600px;
height: 600px;
}
.container ul {
list-style: none;
margin: 0;
padding: 0;
}
.container ul li {
background-image: url(https://i.stack.imgur.com/SBxX4.png);
margin-bottom: 20px;
width: 150px;
height: 78px;
background-size: auto 286px;
background-position: 0 0;
}
.container ul li#belt-2 {
background-position-y: 210px;
}
.container ul li#belt-3 {
background-position-y: 123px;
height: 58px;
}
.container ul li#belt-4 {
background-position-y: 66px;
height: 58px;
}
Always Remember all images in CSS sprites, should have same canvas size
I create a basic example of CSS sprites, I hope this will help you.
Here's a very simple example with the last two images. I recommend you to play around in this fiddle with .block's width, height, and background-position. The last two numbers in the background property allows you to define how many images will appear.
.container {
position: relative;
width: 600px;
height: 600px;
}
.container .block {
background: url(https://i.stack.imgur.com/SBxX4.png) -85px -420px;
width: 310px;
height: 250px;
}
<div class="container">
<div class="block">
</div>
</div>
You can play around with it on JSFiddle

Content Inside a Shape

I want to get my footer to look like this Image. 4 columns inside a triangle shape.
However for some reason it appears that all four columns get stacked on-top of each other, which I confirmed by slight changing the top margin. When I comment out the #right_triangle, I get 4 columns, as you would expect. I believe its the border on the actual triangle that's doing it, but I cant figure out a way to do it or get around it.
Below is the code I'm using.
#right_triangle {
width: 0;
height: 0;
border-bottom: 300px solid #009933;
border-right: 2000px solid transparent;
}
#footer_column1 {
margin-top: 200px;
width: 25%;
float: left;
}
#footer_column2 {
margin-top: 200px;
width: 25%;
float: left;
}
#footer_column3 {
margin-top: 200px;
width: 25%;
float: left;
}
#footer_column4 {
margin-top: 200px;
width: 25%;
float: left;
}
<div id="footer">
<div id="right_triangle">
<div id="footer_column1">Hello</div>
<div id="footer_column2">Hello</div>
<div id="footer_column3">Hello</div>
<div id="footer_column4">Hello</div>
</div>
</div>
Reason:
The problem as you've correctly guessed is with the #right_triangle but it is not because of border. It is because of width: 0 on this element and width: 25% on child #footer_column* elements. May be you overlooked it (or maybe you haven't understood the concept fully) but a percentage width on a child element would use the parent's set width as reference for calculation. Thus the width of all child elements are nothing but 0px. Since they are floated, the second and subsequent elements are offset from their previous sibling only by the width of the previous element(s) and they don't have any margin on the right also. So, effectively they are all placed at 0px on the left (on top of each other).
Again since they are floated they stay in same line unless their width exceeds a line's width. Here the width is also not more than a line's width (which is the parent's width). If you set even width: 1px to any of the first three elements, you'd notice that the others get pushed to the next line.
Solution:
Given how you need the screen's width to be split evenly across the 4 columns (from the image) and without changing your overall approach, you could make use of any one of the following solutions:
Give all the #footer_column* elements, a width in viewport units instead of in percentages, set display: inline-block instead of float: left and add white-space:nowrap to the parent. All these will make them get displayed on the same line without changing your markup.
#right_triangle {
width: 0;
height: 0;
white-space: nowrap;
border-bottom: 300px solid #009933;
border-right: 2000px solid transparent;
}
#footer_column1 {
margin-top: 200px;
width: 25vw;
display: inline-block;
}
#footer_column2 {
margin-top: 200px;
width: 25vw;
display: inline-block;
}
#footer_column3 {
margin-top: 200px;
width: 25vw;
display: inline-block;
}
#footer_column4 {
margin-top: 200px;
width: 25vw;
display: inline-block;
}
<div id="footer">
<div id="right_triangle">
<div id="footer_column1">Hello</div>
<div id="footer_column2">Hello</div>
<div id="footer_column3">Hello</div>
<div id="footer_column4">Hello</div>
</div>
</div>
Make all the 4 footer column elements as children of footer element instead of #right_triangle. Since the footer is a block element, it gets 100% of the screen width by default and so it would be split evenly across the 4 children. Note that you would have to absolutely position the #right_triangle and use z-index: -1 on it for this method.
#footer {
position: relative;
}
#right_triangle {
position: absolute;
width: 0;
height: 0;
border-bottom: 300px solid #009933;
border-right: 2000px solid transparent;
z-index: -1;
}
#footer_column1 {
margin-top: 200px;
width: 25%;
float: left;
}
#footer_column2 {
margin-top: 200px;
width: 25%;
float: left;
}
#footer_column3 {
margin-top: 200px;
width: 25%;
float: left;
}
#footer_column4 {
margin-top: 200px;
width: 25%;
float: left;
}
<div id="footer">
<div id="right_triangle"></div>
<div id="footer_column1">Hello</div>
<div id="footer_column2">Hello</div>
<div id="footer_column3">Hello</div>
<div id="footer_column4">Hello</div>
</div>
Notes:
Using CSS transform for achieving the triangle in this question would be tough because it will require specific angle calculations for both skew and rotate (depending on which one is used) and hence not recommended.
Gradients could have been a good option for this one but unfortunately they get rough and jagged edges at very high dimensions and hence not recommended.
If you can change your overall approach, I'd recommend using SVG to create the triangle. It is not that SVG offers any great advantage for this particular shape but it is generally more useful to start learning and using SVG for shapes as it helps in creating a lot of complex ones with ease. Below is a snippet using SVG.
#footer {
position: relative;
}
#right_triangle {
position: absolute;
width: 2000px;
height: 300px;
z-index: -1;
}
#right_triangle path {
fill: green;
}
#footer_column1 {
margin-top: 200px;
width: 25%;
float: left;
}
#footer_column2 {
margin-top: 200px;
width: 25%;
float: left;
}
#footer_column3 {
margin-top: 200px;
width: 25%;
float: left;
}
#footer_column4 {
margin-top: 200px;
width: 25%;
float: left;
}
<div id="footer">
<svg id="right_triangle" viewBox='0 0 2000 300'>
<path d='M0,0 2000,300 0,300z' />
</svg>
<div id="footer_column1">Hello</div>
<div id="footer_column2">Hello</div>
<div id="footer_column3">Hello</div>
<div id="footer_column4">Hello</div>
</div>

how to fix responsive background image?

i need a responsive background image that will scale and keep its aspect ratio when resized within its container, anybody have any suggestions. This is what i been working on for 3 days, everything works great but the container takes up alot of space, and if i mess with the height it will mess up the aspect ratio.
HTML:
<div class="wrapper">
<h2 class="heading">Responsive Background CSS</h2>
<div class="container">
Background Image Applied Here
</div>
<section class="about"></section>
</div>
CSS:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
}
.cf:before, .cf:after, {
display: table;
content:"";
}
.cf:after {
clear: both;
}
.heading {
color: #000;
font-size: 40px;
text-align: center;
}
.container {
position: relative;
min-height:1px;
padding: 0;
max-width: 80%;
background-color:orange;
margin: 30px auto;
}
.image {
background:url(img/image%201.jpg);
display: block;
max-width: 100%;
padding-bottom: 177.7777777777778%;
height: 0;
background-size: 100% !important;
background-repeat: no-repeat;
}
.about {
width:100%;
min-height: 500px;
background-color:tomato;
position: relative;
}
You can try this custom plugin made for responsive images(background)
http://webonise.github.io/jQuery-plugins/fullScreenImage/responsive-full-screen.html
You could always just change the image depending on the screen size. You'd want to use the same image, just different sizes. This way you can crop the images in ways that better display your intentions for the background image.
Here's a demo. Change the browser size to see the changes.

Overlapping border with CSS

I have a webpage header that I am trying to make overlap with a border. Here is a jsfiddle of a simplified version of what I have.
This is what I am aiming for: (The second row of images is what would happen if the page width is reduced.)
I tried using absolute positioning of the green (logo), but this causes the menu (yellow) to overlay with the logo instead of vertically stacking on the page like happens now.
My next idea was to give the border (red) absolute positioning, but in various attempts at that I always seemed to end up with the border at the top of the page, like the header div was ignoring the height of the logo/menu. That was set up something like:
#header {
position: relative;
}
#border {
position: absolute;
bottom: 0;
}
Any suggestions on how to set this up, either fixing what I have or trying a different approach altogether?
Edit:
Here's a better depiction of why I'm trying to do this, using the same colors (why the overlap and why the yellow menu should end up over the logo):
So something like this?
The green block is overlapped by the red border block.
Edit - Added percentage width and #media query so it resizes.
Have a fiddle!
HTML
<div id="header">
<div id="menu">
Contents
</div>
<div id="logo"></div>
</div>
CSS
#header {
width: 100%;
max-width: 700px;
min-width: 320px;
height: 200px;
position: relative;
background: blue;
}
#logo {
background: green;
height: 80px;
width: 190px;
position: absolute;
top: 80px;
left: 40px;
}
#menu {
height: 40px;
width: 300px;
background: yellow;
display: block;
position: absolute;
top: 80px;
right: 0;
}
#media screen and (max-width: 600px) {
#menu {
top: 30px;
}
}
#header:after {
content:'';
height: 80px;
width: 100%;
display: block;
position: absolute;
bottom: 0;
background: #F00;
}

CSS fluid two column and min-width

I have a two-column fluid layout, with the left-hand side set to width: 40% and the right-hide side set to width: 60%. I'd like to allow users to resize their browser as large or small as they'd like, but I must have the left-hand side display a minimum width of 300px.
The following is the code I am currently using for the fluid layout, which includes the min-width specification. But, CSS is ignoring it! It allows the left-hand column to shrink below 300px.
I've also attempted to set min-width to a percentage, such as 20%, but CSS ignores this specification as well.
div#left {
background: #ccc;
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 40%;
min-width:300px;
height: 100%;
}
div#right {
background: #aaa;
position: fixed;
top: 0;
width:60%;
right: 0;
bottom: 0;
}
​
jsFiddle Fullscreen Example: http://jsfiddle.net/umgvR/3/embedded/result/
jsFiddle Code: http://jsfiddle.net/umgvR/3/
What is causing this? How can the code be corrected?
If you're not too attached to the fixed positioning, this should do what you want.
View on JSFiddle
HTML
<div id="left">Left</div><div id="right">Right</div>
Note the lack of whitespace between the elements
CSS
html, body {
height: 100%;
}
body {
min-width: 800px;
}
div#left {
background: #ccc;
display: inline-block;
width: 40%;
min-width:300px;
height: 100%;
}
div#right {
background: #aaa;
display: inline-block;
width:60%;
height: 100%;
}
This should also work...
html
<div id="container">
<div id="left">Left</div>
<div id="right">Right</div>
</div>
css
body, div {width:100%;
height:100%;
margin: 0;
}
#container {
display:block;position: fixed;
}
#left, #right {
display: inline-block;
}
div#left {
background: #ccc;
min-width: 300px;
max-width: 40%;
}
div#right {position:fixed;
background: #aaa;
width: 60%;
}
I found out that the left hand div is keeping the minimum width, but its going underneath the right div. If you bring it forward, you can see it on top of the right div. I don't think that this is ideal though.
z-index: 1;
I used z-index: 1; on the left right and z-index: 0; on the right div.
It works but I think there are better solutions out there.

Resources