Two column layout with sidebar and responsive image and text - css

I have a layout with 2 columns : a left sidebar and a main content.
The sidebar is 25% of the total, (the main is 75% !).
In the main content bloc there should be an image with 6 areas (each 25% width of the full layout width).
The layout has to be fluid/responsive.
My problem is that obviously, when the viewport is not full width, the image is resized. But
the height of the sidebar doesn't follow the image height resizing.
For the moment, i've set a absolute positioned image . I haven't manage to set it correctly as (responsive) background image. The sidebar block height are obviously wrong (set to image height/2) but i don't see how to have responsive height (auto or 50%
the text in the blocks doesn't "follow" the image resizing
How can i achieve this ? I would like the solution to be valid for IE 8+. I know, i'm asking too much
I've done a jsfiddle to show the principle (there is no breakpoint here, at the moment)
<div id="page">
<div id="main">
<div id="main-content">
<div id="primary">
<div id="content">
<img src="http://s18.postimg.org/a8ary6c8p/image.gif" class="bgimg responsiveimg">
<div class="bloc bloc1">Content for bloc 1</div>
<div class="bloc bloc2">Content for bloc 2</div>
<div class="bloc bloc3">Content for bloc 3</div>
<div class="bloc bloc4">Content for bloc 4</div>
<div class="bloc bloc5">Content for bloc 5</div>
<div class="bloc bloc6">Content for bloc 6</div>
</div>
</div>
<div id="secondary">
<div class="sbloc sec_bloc1">Some content</div>
<div class="sbloc sec_bloc2">Some content</div>
</div>
</div>
</div>
<div id="footer">Some footer content</div>
</div>
I'm working on a Wordpress child template
----- EDIT -
Since the "real" image will be a actual picture of people (with a colored grid overimposed into the jpg - i'm not the graphist :( ), so it won't be an option.
The image will be responsive : no deformation but homothetic resizing.
i would like to have the sidebar responding to the height of the image (one image, not a repeated one), with each of two part of the sidebar (equal height), resizing to stay aligned with the grid on the image.
In fact my fiddle is questionnable, because the default viewport is small : i would like a responding version where the result is "always" like when the viewport is entirely stretched.

In order to keep the image aspect ratio, we need to set the height of each sidebar to match the height of the responsive image. I'm using jQuery here.
var h = $('.bgimg').height();
$('.sbloc').css('height', h);
Due to your complex layout 1 sidebar + 3 text blocks in a row, and 2 rows total. So the height of the container #content would be 2x of image height.
We need the inline image there with CSS set to max-width: 100%; height: auto; for responsiveness. But we actually set it to visibility: hidden; (hidden, but keep the space), instead we use the same image as background and set it to contain.
$('.bgimg').css('visibility', 'hidden');
$('#content').css({
'height' : h * 2,
'background' : 'url(http://s18.postimg.org/a8ary6c8p/image.gif)',
'background-size' : 'contain'
});
Then, we combine ready() + resize() functions, the entire script is:
$(document).ready(myfunction);
$(window).on('resize', myfunction);
function myfunction() {
var h = $('.bgimg').height();
$('.sbloc').css('height', h);
$('.bgimg').css('visibility', 'hidden');
$('#content').css({
'height' : h * 2,
'background' : 'url(http://s18.postimg.org/a8ary6c8p/image.gif)',
'background-size' : 'contain'
});
}
Lastly, remove the background color from the blocks, as we use background image.
.bloc1, .bloc3, .bloc5{/* background-color: red */}
.bloc2, .bloc4, .bloc6{/* background-color: green */}
jsfiddle
EDIT
The only image should cover the the entire content area (two rows). Minimal jQuery code update as needed.
$(document).ready(myfunction);
$(window).on('resize', myfunction);
function myfunction() {
var h = $('.bgimg').height();
$('.sbloc').css('height', h / 2);
$('.bgimg').css('visibility', 'hidden');
$('#content').css({
'height' : h,
'background' : 'url(http://s18.postimg.org/a8ary6c8p/image.gif)',
'background-size' : 'contain'
});
}
jsfiddle

Related

How can I add absolute overlays over an img tag with object-contain behaviour?

I am working on a touch screen display for a museum. The screen will display old photos with touchable zones laid on top of it that reveal more information about people/objects show in the photos.
The screen size is fixed (it's a TV) but the photos could be in any aspect ratio; landscape or portrait.
There will be a header and footer at the top and bottom of the screen. In the middle I want to display the photo as large as possible. That is to say:
if the photo is portrait it should span the full height between the header and footer with empty space to the left and right.
if the photo is landscape (more landscape than the TV is) it should span the full width of the screen from left to right with empty space above and below.
This, I believe, is classic object-fit: contain; behaviour.
What I'm struggling with is adding the overlay on top. This consists of many rectangles that a user can touch. I know the top and left position and width and height of each box as a percent of the image it is overlaying.
I have made a tailwind playground here: https://play.tailwindcss.com/1c8QufeAFj
My understand is that I can't add the overlain boxes as children of the <img> tag, so they are placed in a <div> that is the <img> tag's sibling.
<!-- Check out the tailwind playground to see a live preview -->
<div class="flex h-screen flex-col">
<div id="header" class="bg-gray-500 p-6"><p>Header</p></div>
<!-- Main content which grows to fill the space between the header and footer -->
<main class="grow bg-gray-900">
<!-- Wrapper around the img and it's overlay -->
<div id="wrapper" class="relative">
<!-- The image: Should be as large as possible within main content (object contain style behaviour) -->
<img class="h-full w-full" src="https://placekitten.com/600/400" />
<!-- Div container boxes to draw on top of image (and move and scale with the image) -->
<div class="absolute inset-0 z-10">
<!-- Boxes overlaid on each kitten -->
<div style="left:48%; top:28%; width:11%; height:15%;" class="absolute border-2 border-orange-300"></div>
<div style="left:36%; top:29%; width:10%; height:14%;" class="absolute border-2 border-orange-300"></div>
<div style="left:16%; top:33%; width:10%; height:14%;" class="absolute border-2 border-orange-300"></div>
<div style="left:69%; top:43%; width:11%; height:15%;" class="absolute border-2 border-orange-300"></div>
</div>
</div>
</main>
<div id="footer" class="bg-gray-500 p-6"><p>Footer</p></div>
</div>
Since the boxes' positions and sizes are relative to the image, this sibling div must have the same size as the img at all times.
I can't get this to work with object-fit:contain; the sibling div that contains the boxes doesn't have the same size as the img so the boxes don't line up where they are supposed to.
If I try to find a solution without object-fit then I can either get it to work for portrait photos (using h-full) or landscape photos (using w-full) but I haven't managed to find code that works for both portrait and landscape.

Responsive block layout

I have a design which is that of rows consisting of two blocks.
http://jsfiddle.net/dhxr25m6/
<div class="homepageBlockRow">
<div class="homepageBlock">
<img src="http://s1059327.instanturl.net/images/HomeTiles/BigJob.jpg" alt="">
</div>
<div class="homepageBlock homepageBlockText orangeBackground" style="height: 372px;">
...
</div>
<div style="clear: both;"></div>
</div>
<div class="homepageBlockRow">
<div class="homepageBlock homepageBlockText greyBackground" style="height: 372px;">
...
</div>
<div class="homepageBlock">
<img src="http://s1059327.instanturl.net/images/HomeTiles/Rental.jpg" alt="">
</div>
<div style="clear: both;"></div>
</div>
The page looks good on a full size monitor but on tablet resolutions the images are about half the height as the text blocks.
I tried scaling up the text block to match the row height, but that doesn't work when the image is smaller.
What would be a good way to scale things so that the images and text are always the same height?
CSS3 has object-fit property that can achieve this (while retaining the aspect ratio).
Just add the following code to the css for the image:
width:100%;
height:100%;
object-fit:cover;
object-position: 0 0;
FYI, I changed the structure of the div definitions a bit and added some height/width/float attributes and you can see a demo here (fiddle doesn't seem to run my code for some reason as mentioned in the comments): object-fit-solution
RESPONSIVE DESIGN:
For mobile devices, you will need to write media queries.
Some pointers for that:
1) make the clearfix div to float to left
2) remove floats on image and text blocks. Also make the width to 100%.

Layout 3 image links in a row HTML

Hi, I'm making a website and i need to have some image links laid out like they are in the image above. The grey rectangles are placeholders for where the images would be, they are all the same size (275 x 186) and need a margin in between them all. I also need to be able to add in more that 6 images.
I can't seem to get them to line up properly. Any help would be appreciated.
one way to do this is to use the "float" property of CSS. here is how I would approach this problem.
create a div that has width of "275px + border-size" x 3
within this div add all your images with size 275 x 186 plus borders
assign the css property "float:left" to each image.
<
style>
div.wrapper{
width: ("275 + YOUR border-size" x 3)px;
}
div.image{
background-image: url(..path to your img);
float: left
}
</style>
<div class="wrapper">
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
... add all your imgs here
<div style="clear: both"></div> //need this one here to make the wrapper extend
</div>

Bootstrap Element 100% Width

I want to create alternating 100% colored blocks. An "ideal" situation is illustrated as an attachment, as well as the current situation.
Desired setup:
Currently:
My first idea was to create an div class, give it a background color, and give it 100% width.
.block {
width: 100%;
background: #fff;
}
However, you can see that this obviously doesn't work. It's confined to a container area. I tried to close the container and that didn't work either.
The container class is intentionally not 100% width. It is different fixed widths depending on the width of the viewport.
If you want to work with the full width of the screen, use .container-fluid:
Bootstrap 3:
<body>
<div class="container-fluid">
<div class="row">
<div class="col-lg-6"></div>
<div class="col-lg-6"></div>
</div>
<div class="row">
<div class="col-lg-8"></div>
<div class="col-lg-4"></div>
</div>
<div class="row">
<div class="col-lg-12"></div>
</div>
</div>
</body>
Bootstrap 2:
<body>
<div class="row">
<div class="span6"></div>
<div class="span6"></div>
</div>
<div class="row">
<div class="span8"></div>
<div class="span4"></div>
</div>
<div class="row">
<div class="span12"></div>
</div>
</body>
QUICK ANSWER
Use multiple NOT NESTED .containers
Wrap those .containers you want to have a full-width background in a div
Add a CSS background to the wrapping div
Fiddles: Simple: https://jsfiddle.net/vLhc35k4/ , Container borders: https://jsfiddle.net/vLhc35k4/1/
HTML:
<div class="container">
<h2>Section 1</h2>
</div>
<div class="specialBackground">
<div class="container">
<h2>Section 2</h2>
</div>
</div>
CSS: .specialBackground{ background-color: gold; /*replace with own background settings*/ }
FURTHER INFO
DON'T USE NESTED CONTAINERS
Many people will (wrongly) suggest, that you should use nested containers. Well, you should NOT.
They are not ment to be nested. (See to "Containers" section in the docs)
HOW IT WORKS
div is a block element, which by default spans to the full width of a document body - there is the full-width feature. It also has a height of it's content (if you don't specify otherwise).
The bootstrap containers are not required to be direct children of a body, they are just containers with some padding and possibly some screen-width-variable fixed widths.
If a basic grid .container has some fixed width it is also auto-centered horizontally.
So there is no difference whether you put it as a:
Direct child of a body
Direct child of a basic div that is a direct child of a body.
By "basic" div I mean div that does not have a CSS altering his border, padding, dimensions, position or content size. Really just a HTML element with display: block; CSS and possibly background.
But of course setting vertical-like CSS (height, padding-top, ...) should not break the bootstrap grid :-)
Bootstrap itself is using the same approach
...All over it's own website and in it's "JUMBOTRON" example:
http://getbootstrap.com/examples/jumbotron/
This is how you can achieve your desired setup with Bootstrap 3:
<div class="container-fluid">
<div class="row"> <!-- Give this div your desired background color -->
<div class="container">
<div class="row">
<div class="col-md-12">
... your content here ...
</div>
</div>
</div>
</div>
</div>
The container-fluid part makes sure that you can change the background over the full width. The container part makes sure that your content is still wrapped in a fixed width.
This approach works, but personally I don't like all the nesting. However, I haven't found a better solution so far.
There is a workaround using vw. Is useful when you can't create a new fluid container.
This, inside a classic 'container' div will be full size.
.row-full{
width: 100vw;
position: relative;
margin-left: -50vw;
left: 50%;
}
After this there is the sidebar problem (thanks to #Typhlosaurus), solved with this js function, calling it on document load and resize:
function full_row_resize(){
var body_width = $('body').width();
$('.row-full').css('width', (body_width));
$('.row-full').css('margin-left', ('-'+(body_width/2)+'px'));
return false;
}
In bootstrap 4, you can use 'w-100' class (w as width, and 100 as 100%)
You can find documentation here:
https://getbootstrap.com/docs/4.0/utilities/sizing/
If you can't change the HTML layout:
.full-width {
width: 100vw;
margin-left: -50vw;
left: 50%;
}
<div class="container">
<div class="row">
<div class="col-xs-12">a</div>
<div class="col-xs-12">b</div>
<div class="col-xs-12 full-width">c</div>
<div class="col-xs-12">d</div>
</div>
</div>
Demo: http://www.bootply.com/tVkNyWJxA6
Sometimes it's not possible to close the content container.
The solution we are using is a bit different but prevent a overflow because of the
firefox scrollbar size!
.full-width {
margin-top: 15px;
margin-bottom: 15px;
position: relative;
width: calc(100vw - 10px);
margin-left: calc(-50vw + 5px);
left: 50%;
}
Here is a example: https://jsfiddle.net/RubbelDeKatz/wvt9253q
Instead of
style="width:100%"
try using
class="col-xs-12"
it will save you 1 character :)
Sorry, should have asked for your css as well. As is, basically what you need to look at is giving your container div the style .container { width: 100%; } in your css and then the enclosed divs will inherit this as long as you don't give them their own width. You were also missing a few closing tags, and the </center> closes a <center> without it ever being open, at least in this section of code. I wasn't sure if you wanted the image in the same div that contains your content or separate, so I created two examples. I changed the width of the img to 100px simply because jsfiddle offers a small viewing area. Let me know if it's not what you're looking for.
content and image separate: http://jsfiddle.net/QvqKS/2/
content and image in same div (img floated left): http://jsfiddle.net/QvqKS/3/
I would use two separate 'container' div as below:
<div class="container">
/* normal*/
</div>
<div class="container-fluid">
/*full width container*/
</div>
Bare in mind that container-fluid does not follow your breakpoints and it is a full width container.
I'd wonder why someone would try to "override" the container width, since its purpose is to keep its content with some padding, but I had a similar situation (that's why I wanted to share my solution, even though there're answers).
In my situation, I wanted to have all content (of all pages) rendered inside a container, so this was the piece of code from my _Layout.cshtml:
<div id="body">
#RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
<div class="container">
#RenderBody()
</div>
</section>
</div>
In my Home Index page, I had a background header image I'd like to fill the whole screen width, so the solution was to make the Index.cshtml like this:
#section featured {
<!-- This content will be rendered outside the "container div" -->
<div class="intro-header">
<div class="container">SOME CONTENT WITH A NICE BACKGROUND</div>
</div>
}
<!-- The content below will be rendered INSIDE the "container div" -->
<div class="content-section-b">
<div class="container">
<div class="row">
MORE CONTENT
</div>
</div>
</div>
I think this is better than trying to make workarounds, since sections are made with the purpose of allowing (or forcing) views to dynamically replace some content in the layout.
Though people have mentioned that you will need to use .container-fluid in this case but you will also have to remove the padding from bootstrap.
The following answer is not exactly optimal by any measure, but I needed something that maintains its position within the container whilst it stretches the inner div fully.
https://jsfiddle.net/fah5axm5/
$(function() {
$(window).on('load resize', ppaFullWidth);
function ppaFullWidth() {
var $elements = $('[data-ppa-full-width="true"]');
$.each( $elements, function( key, item ) {
var $el = $(this);
var $container = $el.closest('.container');
var margin = parseInt($container.css('margin-left'), 10);
var padding = parseInt($container.css('padding-left'), 10)
var offset = margin + padding;
$el.css({
position: "relative",
left: -offset,
"box-sizing": "border-box",
width: $(window).width(),
"padding-left": offset + "px",
"padding-right": offset + "px"
});
});
}
});
This must work (Mobile phone as well as Desktop screen):
class: alignfull and class: img-fluid will do the magic.
<div class="alignfull">
<img class="img-fluid" style="background-size: cover;
background-position: center ;
background-repeat: no-repeat;
height: auto;
min-width: 100%;
width: -moz-available; "
src="{{ $image->image }}" alt="An image">
</div>

Two divs; left should be fixed width, right should fill rest of space

I've got the following HTML code:
<body>
<div id="Frame">
<div id="Body">
<div id="Panel">Side panel, fixed width.</div>
<div id="Content">The rest of the content, should be dynamic width and fill up rest of space horizontally.</div>
</div>
<div id="Foot">
<div>FooBar.</div>
</div>
</div>
</body>
What I'm trying to do is make it so that #Panel is of a fixed width (~200 pixels) and on the left hand side, and that #Content is immediately to the right of #Panel but is of "dynamic" width and fills the rest of the space in the browser screen horizontally. I've tried a lot of different things but haven't been able to get it working -- the farthest I've gotten is to the point where #Panel is on the left and #Content is to the right of #Panel and fills of the rest of the space, but #Content starts below #Panel whereas I'd like it to start at the same vertical position.
I did find In CSS, how do I get a left-side fixed-width column with a right-side table that uses the rest of the width?, however I wasn't able to apply it to the HTML above.
Here's that link, applied to your code:
CSS
#frame { background:pink }
#panel { background:orange; width:200px; float:left }
#content { background:khaki; margin-left:200px }
#foot { background:cornflowerblue }
HTML
<div id='frame'>
<div id='body'>
<div id='panel'>
Side panel, fixed width.
</div>
<div id='content'>
The rest of the content, should be dynamic width and fill up rest of space
horizontally.
</div>
</div><!-- End #body -->
<div id='foot'>
<div>FooBar.</div>
</div>
</div><!-- End #frame -->
Works pretty well! Although, IMHO, you don't need the frame or body (but I don't know the master plan). That would look like this:
<div id='panel'>
Side panel, fixed width.
</div>
<div id='content'>
The rest of the content, should be dynamic width and fill up rest of space
horizontally.
</div>
<div id='foot'>
<div>FooBar.</div>
</div>

Resources