Vertically align two divs within a background image set to cover - css

I have a div that uses the background-image attribute with background-size set to cover. Within the <div> that contains the background image, I have a <div> that contains a text block and a <div> that contains an image.
I am trying to vertically align the two <div>s within the background image.
I have code (below) that vertically aligns the <div>s relative to each other but not within the background image. I understand that my code does not work because the vertical alignment needs to happen at the bg class level but I can't figure out how to make it work.
I have the following HTML
<div class="bg">
<div class="container">
<div class="row vertical-align">
<div class="col-xs-6">
<h4 class="text-center">Zack Gallinger has an MBA from Rotman School of Management. He also runs The 10 and 3, a Canadian data journalism site.</h4>
</div>
<div class="col-xs-6">
<img src="http://www.lucidwebgrouptest3.com/Images/Zack.jpg" class="img-circle">
</div>
</div>
</div>
</div>
and CSS
body,
html {
height: 100%;
}
.bg {
background-image:
url("http://www.lucidwebgrouptest3.com/Images/Background.jpg");
height: 60%;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.vertical-align {
display: flex;
flex-direction: row;
}
.vertical-align > [class^="col-"],
.vertical-align > [class*=" col-"] {
display: flex;
align-items: center;
justify-content: center; /* Optional, to align inner items
horizontally inside the column */
}
h4 {
color: white;
}
The code is also on CodePen.

You need to add a height to container and row, so they match the bg
.container {
height: 100%;
}
.vertical-align {
height: 100%;
display: flex;
flex-direction: row;
}
Updated codepen

Related

Two rows div layout. Building flexible layout that should adapt to different screen sizes

I'm trying to build a flexible layout that should adapt to different screen sizes as the following pictures show.
It's basically two div rows, occupying each 50% of the vertical size of the screen.
Top div is a container to hold pictures and bottom div will display a leaflet map.
I'd like the Image div to keep aspect ratio so image is not deformed, ans Map div to adapt horizontally.
So far, my code is basic and looks like this :
<div id="container">
<div id="Top div">
<div id='image'>Image</div>
</div>
<div id="Bottom div">
<div id='map'>Map</div>
</div>
</div>
Any idea of the CSS style I should add to each div to achieve this layout ?
Image layout desktop
Image layout smartphone
You could use Flexbox to achieve this layout. Refer to my CSS below and check out the attached Codepen.
#container {
display: flex;
flex-flow: row wrap;
}
#Top {
display: flex;
flex: 1 1 100%;
padding-bottom: 1rem;
}
#image {
flex: 0 1 50%;
margin: auto;
padding: 3rem;
background-color: #ccc;
text-align: center;
}
#Bottom {
flex: 1 1 100%;
}
#map {
padding: 5rem;
background-color: green;
text-align: center;
}
If, for some reason you cannot use flexbox you can achieve this easily. The main trick is to add an element to act as a wrapper to the image, set a height/width to this element and then set the max-width/max-height on the image to 100%. This way it will scale without deforming.
To achieve occupying each 50% of the vertical size of the screen you can set the height to 50vh.
#map {
background-color: green;
height: 100%;
}
.section {
height: 50vh;
}
.img-container {
width: 100%;
text-align: center;
}
.sample-img {
max-width: 100%;
max-height: 100%;
}
<div id="container">
<div id="Top div" class="section img-container">
<img class="sample-img" src="https://via.placeholder.com/180" alt="image" />
</div>
<div id="Bottom div" class="section">
<div id='map'>Map</div>
</div>
</div>

Adaptive mosaic of videos and pictures using flex

Using flex, I would like to display an adaptive mosaic of Videos and Pictures, so each time I will add a new video or picture, the Tile will auto adjust.
Here is an exemple of what I m looking for:
[NOTE]: all the Tiles are the same width and height :)
Here is the HTML code:
[NOTE]: I didnt find how to make work flex on StackOverflow.
.flex-container {
display: flex;
background-color: Green;
flex-wrap: wrap;
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
z-index: 10;
}
.flex-container > div {
background-color: pink;
height:100%;
}
.flex-container > div > div.image {
background-image: url("https://www.gettyimages.ca/gi-resources/images/EnterpriseSolutions/StandOut_Creative.jpg");
background-position: center right;
background-size: cover;
width:100%;
height:100%;
}
<div class="flex-container">
<div style="width:50%">
<div class="image"></div>
</div>
<div style="width:50%">
<div class="image"></div>
</div>
<div style="width:50%">
<div class="video">
<video src="http://link.to.video.mp4" autoplay loop muted></video>
</div>
</div>
<div style="width:50%">
<div class="image"></div>
</div>
</div>
So In the wrap flex-container, I have "image" div where the Image is in Background. And "video" div.
I found the way the auto adjust the image, but I dont how to do the same for the video.
Did you find a way to auto adjust video in wrap container?
Thanks.
Your flexbox code is okay (by default, the flex direction is by row, and it wraps on multiple lines to give the mosaic effect). The main problem is the position property in the main container. I removed the fixed position property, along with the associated containers.
/* Main Container */
.flex-container {
display: flex;
/* flex-direction: row; <-- Value by default */
flex-wrap: wrap;
width: 100%;
z-index: 10;
background-color: green;
}
I´ve also removed the height on both the main container and the direct children. As for the heights of the <div> with the .image class, i replaced the percentage value with a vh value. Let's define the element in the mosaic taking the full height of the viewport with the value 100vh.
/* Image Container */
.flex-container > div > div.image {
background-image: url("https://www.gettyimages.ca/gi-resources/images/EnterpriseSolutions/StandOut_Creative.jpg");
background-position: center right;
background-size: cover;
width:100%;
height:100vh; /* <-- Height is full height of the viewport */
}
Let´s tackle the video issue. Maintaining the conditions in the HTML code, I've defined CSS for both the video container and the video element, Both will take the same width and height as the <div> elements with the .image class (100% width, 100vh height).
To adjust the video to take the entire size of the container, in it I used the object-fit property, with the value fill.
/* Video Container */
.flex-container > div > div.video {
width: 100%;
height: 100vh;
}
/* Video Element */
.flex-container > div > div.video video {
width: 100%;
height: 100vh;
object-fit: fill; /* <-- The video fills the entire video container */
}
Code Snippet
The mosaic is in action in the snippet below. Note that:
I added margin zero and padding zero to the entire page for aesthetic reasons.
The video elements feature a sample MP4 video.
Your original code has four mosaic elements, the snippet below has six. Along with the four original elements, there are two more. You can play with it and see the mosaic adjusts itself with the present elements.
* {
margin: 0;
padding:0;
box-sizing: border-box;
}
.flex-container {
display: flex;
flex-wrap: wrap;
width: 100%;
z-index: 10;
background-color: green;
}
.flex-container > div {
background-color: pink;
}
.flex-container > div > div.image {
background-image: url("https://www.gettyimages.ca/gi-resources/images/EnterpriseSolutions/StandOut_Creative.jpg");
background-position: center right;
background-size: cover;
width:100%;
height:100vh;
}
.flex-container > div > div.video {
width: 100%;
height: 100vh;
}
.flex-container > div > div.video video {
width: 100%;
height: 100vh;
object-fit: fill;
}
<div class="flex-container">
<div style="width:50%">
<div class="image"></div>
</div>
<div style="width:50%">
<div class="image"></div>
</div>
<div style="width:50%">
<div class="video">
<video src="http://techslides.com/demos/sample-videos/small.mp4" autoplay loop muted></video>
</div>
</div>
<div style="width:50%">
<div class="image"></div>
</div>
<div style="width:50%">
<div class="image"></div>
</div>
<div style="width:50%">
<div class="video">
<video src="http://techslides.com/demos/sample-videos/small.mp4" autoplay loop muted></video>
</div>
</div>
</div>

Centering a H1 vertically with background image at 100%

I'm trying to get a H1 vertically center aligned within a div that has a background image.
I tried this method I found: https://jsfiddle.net/vdqdpyc0/12/
But found that the full height of the banner was only visible if I specifically added a px height to the div, or added padding to either element. This meant that when I resized, there was lots of white space above and below the banner. This wouldn't be an issue if the background was intended to repeat, but it isn't.
The end product needs to look like this.
html,
body {
height: 100%;
}
.outer-wrapper {
background: url("http://paulmason.name/media/demos/full-screen-background-image/background.jpg") no-repeat center center;
background-size: cover;
max-height: 360px;
height: 100%;
}
.inner-wrapper {
display: table;
width: 100%;
height: 100%;
}
.header-wrapper {
display: table-cell;
text-align: center;
vertical-align: middle;
}
h1 {
color: #fff;
}
<div class="outer-wrapper">
<div class="inner-wrapper">
<div class="header-wrapper">
<h1>
Vertically aligned text
</h1>
</div>
</div>
</div>
I could go through reducing the padding for various responsive viewpoints, but I figured there has to be a more streamlined way of going about it.
You can achieve this much more easily these days with flexbox, e.g.
html,
body {
height: 100%;
}
.outer-wrapper {
background: url("http://paulmason.name/media/demos/full-screen-background-image/background.jpg") no-repeat center center;
background-size: cover;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
h1 {
color: #fff;
}
<div class="outer-wrapper">
<div class="inner-wrapper">
<div class="header-wrapper">
<h1>
Vertically aligned text
</h1>
</div>
</div>
</div>
Example: https://jsfiddle.net/0yxctLne/
You can use a flexbox for this. Here is a pretty simple guide to flexbox. For your issue, it should be enough to pass
display: flex;
flex-direction: column;
justify-content: center;
to the element surrounding the H1 tag, IF the surrounding element is the same height and width as the space you want the H1 tag to be centered in. This will define the main axis as vertical (read: column) and then center all content along the main axis. If you want, you can also add
align-items: center;
to have the text centered along the cross axis (as in horizontally).
Do you need something like this? Flexbox is a nice way to do:
.header-wrapper {
background: url("http://paulmason.name/media/demos/full-screen-background-image/background.jpg") no-repeat center center;
background-size: cover;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
h1 {
color: #fff;
}
<div class="outer-wrapper">
<div class="inner-wrapper">
<div class="header-wrapper">
<h1>
Vertically aligned text
</h1>
</div>
</div>
</div>
Fiddle

Autofitting height for image with flexbox not working

I am trying to achieve the following solution with css flexbox:
I have create a Plunkr at https://plnkr.co/edit/TbJIdOrJLtDfczno4Kpu?p=preview which shows what I currently have.
The grid row has a fixed height (class grid-row in Plunkr)
The red container should autofit the height (article in Plunkr)
The header and footer have a fixed height (header and footer in Plunkr)
The image should autofit the remaining space and is set as a background image (Picture in Plunkr)
Whatever I try, the image does autofit the height of the grid-row. Does someone see what I am doing wrong?
My HTML
<div class="grid-row">
<article>
<header>
Header text
</header>
<picture class="image">
</picture>
<footer>
footer text
</footer>
</article>
</div>
My CSS
.grid-row {
background: orange;
height: 200px;
}
.image {
background-image: url('http://lorempixel.com/400/200/sports/5/');
background-size: cover;
flex: auto;
}
article {
display: flex;
flex-direction: column;
}
The problem was that you didn't extend the flexbox styling up/down through the structure.
.grid-row {
background: orange;
height: 200px;
display: flex;
flex-direction: column;
}
.image {
background-image: url('http://lorempixel.com/400/200/sports/5/');
background-size: cover;
flex: 1; /* remaining height of article */
}
article {
display: flex;
flex-direction: column;
flex: 1; /* 100% height of row */
}
header {
background: red;
}
footer {
background: green;
}
<div class="grid-row">
<article>
<header>
Header text
</header>
<div class="image"></div>
<footer>
footer text
</footer>
</article>
</div>

multiple divs, some left, some right, all vertically aligned with CSS

What would be the best way, given any number of elements in a container, to align some elements to the left and some to the right while centering both left and right content vertically?
For example, given this markup:
<div class="action">
<div class="message">This is our message</div>
<div class="comment">Comments for the message</div>
<div class="person">John Doe</div>
<div class="date">01/18/2013</div>
<div class="time">12:35 PM</div>
</div>
Can the message and comment be left aligned in the action container while the person, date and time are right aligned with both left and right content vertically centered? Can this be done without new markup and with any content length for each element?
Thanks.
Some CSS would do the trick. Have the containing div position: relative, and float the children div's either left or right. Also center-align the text.
.container{
position: relative;
}
.left{
float: left;
width: 50%;
background-color: Silver;
text-align: center;
}
.right{
float: right;
width: 50%;
background-color: Yellow;
text-align: center;
}
Fiddle Example
With a minimal change to existing markup (introduction of two div tags, one for each column), this becomes rather trivial if you use Munawwar's flex-helper.
HTML:
<div class="hbox flex">
<div class="left vbox main-center">
<div class="message">
<p>This is our message.</p>
<p>It spans many lines.</p>
<p>Or rather, paragraphs.</p>
<p>Additional waffle.</p>
<p>Syrup, bacon, a banana.</p>
<p>Tall glass of milk.</p>
</div>
<div class="comment">Comments for the message.</div>
</div>
<div class="right vbox main-center">
<div class="person">John Doe</div>
<div class="date">01/18/2013</div>
<div class="time">12:35 PM</div>
</div>
</div>
CSS:
/*Example-specific CSS*/
/*left column*/
.left {
width: 80%;
background-color: Silver;
text-align: center;
}
/*right column*/
.right {
width: 20%;
background-color: Yellow;
text-align: center;
}
/*Minimal use of Munawwar's flex-helper*/
/* https://github.com/Munawwar/flex-helper */
/*Stack child items vertically*/
.vbox {
display: flex;
/*Align children vetically*/
flex-direction: column;
align-content: flex-start;
/*Prevent extending beyond boundaries*/
overflow: hidden;
}
/*Stack child items horizontally*/
.hbox {
display: flex;
/*Align children horizontally*/
flex-direction: row;
align-content: flex-start;
/*Wrap items to next line on main-axis*/
flex-wrap: wrap;
/*Prevent extending beyond boundaries*/
overflow: hidden;
}
/*Stretch item along parent's main-axis*/
.flex {
flex: 1;
}
/*Stack child items to the main-axis center*/
.main-center {
justify-content: center;
}
JSFiddle demo
No waffles were harmed in the production of this answer, though some may have been eaten.

Resources