Solution for variable height elements within relative width div - css

I have an image placed within a relative width div as part of a responsive page design. The div's width (and hence the image's size) is set to ensure that content beneath it appears above the fold on screens down to a certain resolution.
A minority of images that appear here have different dimensions (e.g. 4x5 format vs. 4x6). These taller images push the content beneath it below the fold.
I want to maintain the div's height for the 4x6 dimension, which represents the majority of images, such that when an alt format image appears here, the top and bottom of the image are evenly clipped.
I've tried a couple different approaches, none with the desired effect. Applying a max-height on the image element slightly distorts taller images. I tried max-height on the wrapper div with overflow:hidden, but that doesn't constrain the image element.
I applied max-height to that mainImage div, too, and this almost works. However, as you can see from the CSS, I'm using background-color and padding to create a border around the image. Setting max-height on the main div forces the bottom border of the image element outside of the main div. I also tried applying the border to mainImage, but the bottom border still does not appear. Lastly, with max-height applied to the div and not the image, the image is not centered vertically within the div.
I'm not sure how to accomplish what I'm after, or whether it's possible in a responsive design (i.e. without a fixed height). Any thoughts?
Here's the HTML:
<wrapper>
<header></header>
<content>
<!--the main image -->
<section>
<div id="mainImage" role="main">
<div class="in mainImageWrapper">
<img src="[IMAGEFILE]" />
</div><!--end mainImageWrapper -->
</div><!--end mainImage-->
</section>
<!-- more content -->
</content>
</wrapper>
And here's the CSS:
#wrapper {
width: 100%;
min-height:100%;
height: auto !important;
height:100%;
border: none;
}
#content {
margin: 0 auto;
width: 90%;
max-width: 980px;
}
#mainImage {
margin: 1% auto 3% auto;
width: 100%;
overflow: hidden;
}
.mainImageWrapper {
width: 100%;
max-height: 634px; /* The aforementioned fix that doesn't provide the desired effect */
overflow:hidden;
margin: 0 auto;
padding: 0;
display: table-cell;
text-align: center;
position: relative;
}
#mainImage img {
width: 97%;
padding: 1.5%;
background: #FFFFFF;
margin: auto;
vertical-align: middle;
-moz-box-shadow: 1px 2px 8px #1A1A1A;
-webkit-box-shadow: 1px 2px 8px #1A1A1A;
box-shadow: 1px 2px 8px #1A1A1A;
}

So, it appears that what I want to accomplish above isn't possible through css. I wound up implementing phpThumb and using the z-crop parameter to crop images that exceed a certain height from the center. Works well for most instances. Only issue I've encountered with this approach is that, since this is a photography website that includes watermarked images, occasionally the crop cuts off the watermark in an awkward way.

Related

Why do mobile viewport dimensions change if there is overflow in flexbox container with 'nowrap'?

Unsurprisingly, if a parent with display: flex:
1. Has flex-direction: row and flex-wrap: nowrap and,
2. Has any children that start wide (flex-basis) and don't allow shrinking (via flex-shrink: 0),
the content will exceed the bounds of the parent dimensions.
If this flex parent is the width of the screen, browsers generally just honor the 'nowrap' layout anyway and put up a horizontal scrollbar if the viewport gets too small. But on a mobile screen this isn't the only thing that happens. The window's opinion of its own viewport size seems to change, and it throws off the scale of the page.
I've recreated in a simplified page:
HTML:
<div id="container">
<div id="flex-container">
<div class="flex-child-text">Here's a bunch of text</div>
<div class="flex-child-button">ButtonHere</div>
<div class="flex-child-button">ButtonThere</div>
</div>
<div id="footer-bar"></div>
</div>
CSS:
#container {
display: block;
height: 100vh;
background-color: lightseagreen;
}
#flex-container {
display: flex;
height: 32px;
width: 100%;
padding: 1rem 0;
flex-flow: row nowrap;
}
.flex-child-text {
flex: 1 0 340px;
font-size: 20px;
}
.flex-child-button {
flex: 0 1 auto;
height: 1rem;
margin: 0px 0.25rem;
display: inline-block;
border: solid #aaa 1px;
background-color: #eeeeee;
border-radius: 3px;
padding: 0 8px;
}
#footer-bar {
position: fixed;
bottom: 0;
width: 100vw;
height: 32px;
background-color: black;
}
here it is in a jsfiddle
The jsfiddle is mostly because visuals are helpful, but it can't recreate the bug. Simple resizing of a window doesn't do it - I've observed in Chrome mobile emulator and verified on an Android device. If any intrepid reader were willing to cut/paste/try on their own Chrome mobile, I've included a head tag in the fiddle code to ease that along.
Toggling .flex-child-text flex-shrink property between 0 and 1 changes the viewport dimensions (both width and height, seemingly proportionally). The footer, which gets position and dimensions from the outer container, is flung offscreen. This is also evidenced by consoling window.innerWidth - the result has changed when the layout has broken.
Image - All elements contained within viewport
Image - Children break out of container, bottom-right of scroll dimensions
So to be clear, I understand why in the second image there is white space if you scroll to the right of the green container. What I don't understand is: 1. Why this also causes the y dimension to change like it does, and 2. Why an element position: fixed to bottom: 0 or right: 0 doesn't anchor to the side of the actual viewport in this special case.
Adding overflow: auto to the outer #container makes it work. The offending content still pushes out of the flex container to the right (and can be scrolled to), but the elements that rely on viewport anchoring are now back in place.
Still not clear on why the layout broke in such a way that dimension y was affected, but this fix makes that not an issue. Got the idea in this blog post

CSS Height change from set value to dynamic on mobile

Im trying to change the the height of my container from 527px (Which is the height of the background for the desktop) to make the background image hidden and make background color stretch to the bottom of the div when on mobile. The clearfix is handled from bootstrap. There are several floated divs inside of my .partbackdrop class that are not show because they are too long. No matter what I change the #PartCarContainer on the #media, besides setting it to a fixed value, it will not adjust accordingly and stretch the background to the div.
Link Removed. Problem Solved. Setting height to auto for all the divs inside the container.
CSS
#PartCarContainer { background-color: #FFFFFF; -webkit-box-shadow: 0 2px 10px rgba(0,0,0,.25); box-shadow: 0 2px 10px rgba(0,0,0,.25); border-radius: 3px; overflow: visible; }
.partbackdrop { background-image: url(../../_common/img/backdrop.jpg); background-position: top center; height: 527px; }
#media (max-width: 767px) {
#PartCarContainer { height: auto; }
.partbackdrop { background-image: none; }
}
HTML
<div id="PartCarContainer">
<div class="partbackdrop">
Content
<div class="clearfix"></div>
</div>
</div>
Edit: It may be a floating problem because of the floats for the page.
I also believe the footer may be suffering from the same problem. If you shrink the window down to below 767px you will see the red background which is my problem.
You need a height:auto on .partbackdrop and on .partDivMain
.partbackdrop, .partDivMain { height:auto; }

Position a div next to two images that are displayed inline in one containing div

Consider the following site.
I am trying to position a div that is approx 300px wide by about 400px high next to the picture of the woman. I have tried to display the div as inline but to no avail. I tried to float left but once again no luck. Any thoughts?
You can position it next to the image, by using the following CSS:
.emailForm {
width: 260px; /* anything above 260px will fall over to the next line */
/*float: right;*/ /* remove float */
display: inline-block; /* inline-block since you want specific width and height */
height: 434px;
border: 1px solid black;
}
NOTE: Pretty sure you are using it, but in case you aren't, do use Firebug or Chrome dev tools for making such tasks a breeze.
Try this,
<div id="wrap">
<div id="nextTo"></div>
<img id="woman" src="#" width="600px" height="400px" />
</div>
CSS
#wrap {width: 1000px; margin: 0 auto;}
#nextTo {float: right; max-height: 400px;}
This will ensure that your image is fixed width. If you have a wrapper div that is 1000px wide for example, the #nextTo div will be the remainder of what the image takes up (in my example 400px).
Adding the max-height attribute to the #nextTo div ensures that the div will not fall below the image, but not sure if this is what you are after.

HTML5 tag versus Div for Auto Resizing

I'm hoping for a solution, but worst case scenario, an explanation of why my div isn't resizing, and it may be because I'm using a nav tag.
I have the following html. When the content within my 'section' tag grows, so does the div with the class of page-content. However, when my nav menu items increases, the div doesn't resize.
<div class="page-content">
<nav>
<ul>{menu items here}</ul>
</nav>
<section id="main">
{bunch of text here}
</section>
</div>
Here is my css.
.page-content
{
display: block;
position:relative;
width: 100%;
margin-left: auto;
margin-right: auto;
background-image: url(images/bg-home-main.jpg);
background-repeat: no-repeat;
background-position: center;
}
nav {
display: block;
float: left;
padding: 15px;
position: relative;
margin: 0px 0px 0px -45px;
}
#main {
padding: 5px 25px 5px 25px;
margin-left: 175px;
}
The problem I have then is that the div has a background image that should cover the background of the both the nav and section areas. However, this only happens if my section area is larger (top to bottom) than my nav, as the div will stretch to accommodate the section size. However, if my nav area is bigger, it actually expands outside of the div and there for the image.
When you float an element, you take it out of the flow, and it won't
expand it's containing element. One workaround to this is to add
overflow: hidden; to the containing element.
Using overflow: hidden; is a form of clearfix - a fix to cause the containing element to expand to show any floated, contained elements. Actually any value of overflow works, but overflow: auto causes scrollbars in Explorer on Mac (not sure if anyone still actually uses that) and overflow: scroll causes scrollbars which is the same issue. For some versions of IE, you also need to include a width value to cause this to work. There are other clear fixes, usually involving inserting some kind of element after the floated element that clears that floated element, also causing the containing element to expand to contain it - a div with no height but clear applied to it, or using the :after pseudo element, but I usually use overflow as it doesn't add any presentational markup.

Pixel and percentage width divs side-by-side

I've found a lot of similar questions, and tried out several solutions (including some of the so-called "holy grail" CSS layouts), but they don't quite do what I need.
I have a containing div (a CSS containing block) with id right. Inside it on the left side, I want a fixed-width div (a splitter bar, but it doesn't matter what it's being used for; id splitpane); on the right, filling the rest of the space, another div (id right-box below).
I've tried making the two inner divs display: inline-block (with vertical-align: top), setting the left one to width: 3px, but then there's no way to set the right to have width 100% - 3px. I've also tried using the float: left/margin-left: -100%/margin-left: 3px trick, but it has the same problem: the 100% plus the 3px overflows the parent containing block and causes a scroll bar to pop up. (Of course, it's not the scroll bar per se that's the problem; I could use overflow: hidden to remove it, but then content on the right would be truncated.)
Currently I'm using width: 99.5% for the right div, but that's a terrible hack (and is subject to overflow depending on screen width). It looks a bit like this:
<div id="right"><div id="splitpane"></div><div id="right-box">
...
</div></div>
With CSS as follows (float version, but the inline-block version is similar):
#right {
display: inline-block;
vertical-align: top;
height: 100%;
width: 85%; /* this is part of a larger div */
}
#right-box {
width: 99.5%; /* stupid hack; actually want 100% - 3px for splitter */
height: 100%;
}
#splitpane {
float: left;
width: 3px;
height: 100%;
background: white;
border-left: solid gray 1px;
border-right: solid gray 1px;
cursor: e-resize;
}
Is it even possible to do this? This is for an internal app., so solutions only need to work in Firefox 3 (if they are specific to FF3, though, preferably it's because the solution is standards-compliant but other browsers aren't, not because it's using Firefox-only code).
DIVs are the wrong element type for this since they don't "talk" to each other. You can achieve this easily with a table:
<table style="width:200px">
<tr>
<td id="splitpane" style="width: 3px">...</td>
<td id="rightBox" style="width: 100%">...</td>
<tr>
</table>
The 100% will make the rightBox as wide as possible but within the limits of the table.
This is possible. Because block level elements automatically expand to take up any remaining horizontal space, you can utilise a block level element next to an uncleared floated element with your desired width.
<style type="text/css">
div {
height: 100px;
}
#container {
width: 100%;
}
#left {
background: #FF0;
}
#splitpane {
position: relative;
float: right;
background: #000;
width: 3px;
}
</style>
<div id="container">
<div id="splitpane"></div>
<div id="left"></div>
</div>
See http://jsfiddle.net/georeith/W4YMD/1/
why you didn't use margin-left (since it was float layout) on right box?
so no need to create a splitter div...
#right{
width:200px; /*specify some width*/
}
#rightbox{
float:left;
margin-left: 3px; /*replace the splitter*/
/*margin: 0 3px; /*use this to give left & right splitter*/ */
}
yeah something like that, i hate empty div, it's not semantic and it's like putting a splitter on the "old" table way
If the div #right-box is only going to contain non-floated content it might be an idea to just put the content inside #right instead and let it wrap around the floated #splitpane.

Resources