Continue document flow after transform: translateY(-50%) - css

I need to close the gap following a CSS transform: translateY(-50%) so that content flows on naturally.
I have tried other methods but have been unable to move the element up by 50% of its own height. Negative margin as a percentage is based on the height of the window so this doesn't seem like an option, nor can I set a negative margin on the following element as it needs to be based on the height of the header.
HTML:
<div class="header">
<div class="featured-image">
<!-- this is in place of the featured image -->
</div>
<div class="title-container">
<h1>Title<br />goes<br />here</h1>
</div>
</div>
<div class="article-body">
<p>There is too much space above class="article-body". I want the content to flow on naturally after class="title-container", however using translateY is purely visual so an alternate method of moving the yellow block up by 50% of its own height is necessary.</p>
</div>
CSS:
.header {
width: 100%.
position: relative;
}
.featured-image {
width: 100%;
height: 200px;
background-color: blue;
}
.title-container {
width: 50%;
margin: 0 auto;
transform: translateY(-50%);
background-color: yellow;
}
JS Fiddle:
https://jsfiddle.net/robertirish/tyh18orq/16/
It may be that this is only possible using Javascript but it would be great to get it done with pure CSS as JS and media queries are a pain to implement.
Thanks in advance.

Instead of using transform: translateY(-50%), use margin-top: -25vh.This will place the .title-container in the same place, yet keep the .article-body flush below it:
.header {
width: 100%.
position: relative;
}
.featured-image {
width: 100%;
height: 200px;
background-color: blue;
}
.title-container {
width: 50%;
margin: 0 auto;
/*transform: translateY(-50%);*/
margin-top: -25vh;
background-color: yellow;
}
<div class="header">
<div class="featured-image">
<!-- this is in place of the featured image -->
</div>
<div class="title-container">
<h1>Title<br />goes<br />here</h1>
</div>
</div>
<div class="article-body">
<p>There is too much space above class="article-body". I want the content to flow on naturally after class="title-container", however using translateY is purely visual so an alternate method of moving the yellow block up by 50% of its own height is necessary.</p>
</div>

Related

Ionic framework : position absolute with bottom in % doesn't work

I am trying to position a <div> absolutely using bottom=50% in an AngularJS/Ionic page as follows:
HTML:
<ion-view title="BoardLine">
<ion-nav-buttons side="left">
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-content class="has-header">
<div id="imagecontainer">
<img id="boardimage" ng-src="{{mainResultImagePath}}" />
<div id="photocredits" class="rotateimagecredits">
Image courtesy: {{computed.prophotocredits}}</div>
</div>
....
CSS:
#imagecontainer {
position:absolute;
top:3%;
left:0;
right:62%;
bottom:50%;
}
#boardimage {
position:absolute;
left:10%;
max-width:85%;
bottom:0;
height:100%;
}
But just before div id="imagecontainer", Ionic generates a div class="scroll",like below, which has a height of 20px. And the top and bottom css for my imagecontainer refers to this height, but the div class="scroll" has a position:static. Therefore my imagecontainer absolute positioning should refer to the first parent that has a non-static position
which should be the <ion-content>
<ion-content class="scroll-content ionic-scroll has-header">
<div class="scroll" style="-webkit-transform: translate3d(0px, 0px, 0px) scale(1);">
<div id="imagecontainer">
<img id="boardimage" ng-src="./img/boards/SD360.jpg" src="./img/boards/SD360.jpg">
<div id="photocredits" class="rotateimagecredits ng-binding">Image courtesy: john carper</div>
</div>
I'm not really sure this answers a question, but a valuable information for people struggling with Ionic and absolute position would be that
position: absolute
Has to be used with elements outside of ion-content
So:
<ion-content>
</ion-content>
<div class="bottom">
</div>
.bottom {
position: absolute;
bottom: 0px;
width: 100%;
}
The footer component of ionic is fixed regarding the screen, I think you can try to implement an equivalent one. More info about the footer: http://ionicframework.com/docs/v1/components/#footer
The main css-properties of the element are:
.bar-footer {
bottom: 0;
height: 44px;
}
.bar {
display: flex;
user-select: none;
position: absolute;
right: 0;
left: 0;
z-index: 9;
width: 100%;
height: 44px;
}
Modify the above properties with your specific ones (eg. bottom: 50%;) and ensure display is set as absolute.
Considering your parent's positionning issues, you should try to put your piece of code outside <ion-content></ion-content>, inside <ion-view></ion-view>.
It's the only way I succesfully set a button positioned as absolute within ionic mobile framework.
EDIT: /!\ Be careful not to write anything out of <ion-view></ion-view>. My previous answer was creating trouble in the way ionic manages the different pages.

How can a vertical align a div with a background color inside a div so the background fills up?

Updated question:
I have a bunch of DIV, they are part of a menusystem and are displayed using display:inline-box. Each div contains text. I want to have different background-color on the different DIVs and that the background fills up the whole height of the div and I also want the text to be vertically aligned along all the div. The fiddle below shows that the background color is only used around the text.
Old text:
I've spent hours on this. I found the vertical alignment quite easy (for example here: How to vertically align div inside another div without display:table-cell) but cannot figure out how i i can fill the whole div with the background color.
My example code is on fiddle: http://jsfiddle.net/joche/s7beksLt/
<div class="DivParent">
<div class="DivWhichNeedToBeVerticallyAligned bg1">
one line
</div>
<div class="DivWhichNeedToBeVerticallyAligned bg2">
<p>one line</p>
</div>
<div class="DivWhichNeedToBeVerticallyAligned bg3">
<p>one line</p>
<p>two line</p>
</div>
<div class="DivHelper"></div>
</div>
css:
.DivParent {
height: 100px;
border: 1px solid lime;
white-space: nowrap;
background-color:#deadad;
}
.DivWhichNeedToBeVerticallyAligned {
display: inline-block;
vertical-align: middle;
white-space: normal;
}
.bg1 {
background-color:#ffaaff;
}
.bg2 {
background-color:#ffffff;
}
.bg3 {
background-color:#ffffa9;
height:100%
}
.DivHelper {
display: inline-block;
vertical-align: middle;
height:100%;
}
I looked at your JSfiddle, and based on your code and question it's a little misleading. Especially since the code at the fiddle is not the code you posted in your question.
So you are trying to fill each div "cell" with a different background color? If so, those "cells" are of the .DivParent class. The internal divs (which you have labeled .bg1, .bg2, .bg3) are simply composed of the text itself - these divs only extend to the boundaries of the text they include (plus any margins, padding, etc.) The .DivParent is actually the entire "cell". See this image to see what I mean: http://i.imgur.com/67y3iWV.png
So all you need to do is apply the classes .bg1, .bg2, etc. to the parent classes. Here is my fiddle with each "cell" a different background color: http://jsfiddle.net/Arkatect/8vmp0124/
Notice in the HTML that the separate bg classes are on the parents, not the divs that just have the text:
<div class="DivParent bg2">
<div class="DivWhichNeedToBeVerticallyAligned">
<p>Two</p>
<p>Lines</p>
</div><div class="DivHelper"></div>
</div>
I hope this is what you were looking for.
Take a look at this one i made for you without .table-cell :http://jsfiddle.net/csdtesting/sos5sxkj/
.DivParent {
height: 100px;
border: 1px solid lime;
white-space: nowrap;
background: gray;
text-align: center;
position: relative;
}
.DivWhichNeedToBeVerticallyAligned {
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background: red;
}
.DivHelper {
display: inline-block;
vertical-align: middle;
height: 100%;
}
<div class="DivParent">
<div class="DivWhichNeedToBeVerticallyAligned">one line</div>
<div class="DivHelper"></div>
</div>
<div class="DivParent">
<div class="DivWhichNeedToBeVerticallyAligned">
<p>Two</p>
<p>Lines</p>
</div>
<div class="DivHelper"></div>
</div>

Set image height to 75% of its container

I have a responsive image list. Each image is inside a container.
I want the image container to be 75% of its first container (unit container in this case)
the image ration is 1:1
I played a little with the image container percentage width but it feels like this is not the solution.
<ul class="list-inline unit_list ">
<li class="unit_list_item col-xs-24 col-sm-12 col-md-8">
<a href='#' alt="unit">
<div class="unit_container">
<div class="icon_container unit_icon">
<img class="img-responsive unit_image" src="http://placehold.it/60X60" />
</div>
<div class="unit_name">FREE</div>
</div>
</a>
</li></ul>
Btw, I'm using bootstrap if that's matter.
http://jsfiddle.net/wmu3w3ej/1/
Thanks to #Mary Melody
transform: scale(0.75);
works like magic
I'm a little afraid to use it since it's so simple.
any thoughts?
Using the logic from here: https://stackoverflow.com/a/20117454/3389737
I have applied it to your situation: http://jsfiddle.net/phwaLmen/1/
#wrapper
{
position: relative;
width: 50%;
overflow: hidden;
}
#wrapper:before
{
content: "";
display: block;
padding-top: 75%;
}
#image
{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
height: 100%;
width: 100%;
}
<div id="wrapper">
<img src="http://placehold.it/350x350" id="image">
</div>
Add relative positioning to the parent, set its width as you'd like and make sure the overflow is hidden.
Create a :before element for the wrapper with a padding-top of 75%. Since there is no height specified for the #wrapper, this 75% is based on the width of the element :)
Then you have your image, positioned absolutely and then fitted to the container. If you want the image to be cropped instead of resized, remove the height: 100% and width: 100% style rules from it.
You can do it like this (in your html):
<img src="img.jpg" height="75%" />
Good luck!

Scrollbar on window resize for only one div in multi-div vertical layout

I've been on this for days and read every conceivable article on css, overflow, and layout.
I have a page with a banner (position: absolute), below which is a div containing two block divs. The second block div, in turn has another div containing text.
I would like the inner-most DIV display a scroll bar when the window is resized.
I've read the posting on ensuring height is set on all containing elements, I've set overflow-y: auto in all the right places. Just doesn't work.
The containing DIV looks like this: http://i.imgur.com/oDHM4.png
I want the green part to scroll when the browser window is resized (y-direction only).
Scrollable DIVs in any design are so useful... but shouldn't be this hard.
Any and all help appreciated.
Danny
MARKUP
The markup is very simple:
<body>
<div id="page-header" style='background:blue;'>page-header</div>
<div id="page-content">
<div id="configContent" style='height: inherit; background: steelblue;'>
<h1 id='panTitle'>Panel Title</h1>
<div id='panProbes' class='libPanel' style="background: maroon;">
<p>panProbes</p>
<div id="probesCT1" class="configtable" style='background: red;'>
<p class='pTblTitle'>probesCT1</p>
</div>
<div id="probesCT2" class="configtable" style='background: grey;'>
<p>probesCT2</p>
<div id='pTbl' style='background: green;'>
<div class='pRow'>1st para in pTbl</div>
<div class='pRow'>some data</div>
<div class='pRow'>some data</div>
<div class='pRow'>some data</div>
<div class='pRow'>some data</div>
<div class='pRow'>some data</div>
<div class='pRow'>some data</div>
<div class='pRow'>some data</div>
<div class='pRow'>some more data</div>
<div class='pRow'>some more data</div>
</div>
</div>
</div>
</div>
</div>
</body>
** STYLING **
Here's the CSS cut down to the core essence:
html, body {
position:absolute;
margin: 0px;
padding: 0px;
height: 100%;
width: 1010px;
overflow: hidden;
}
#page-header {
position: absolute;
left: 5px;
top: 5px;
height: 60px;
width: 100%;
}
#page-content {
width: 100%;
height: 100%;
margin-top: 95px;
}
#configContent {
height: 100%;
width: 300px;
padding-left: 0px;
border-width: 3px;
margin-left: 30px;
margin-right: auto;
}
.libPanel { height: 100%; }
#probesCT1 { width: 150px; margin: 0 auto 0 30px; }
#probesCT2 {
width: 200px;
/* height: 100%; */
margin: 0 30px 50px 30px;
padding: 0 10px 10px 10px;
}
#pTbl { overflow-y: auto; }
.pRow { margin-bottom: 10px; }
For overflow-y: auto to work and make scroll bars, that div must have a specific height set. So in this example (with your html above) I set it to 200px, which was less space than necessary to display the content without a scroll bar, and thus shows a scroll bar. However, if set to 100% it does not work, because 1) you need to uncomment the height of the containing divs, and 2) your content in that div is less than needed to fill the height of the div, so no scroll bar shows up. With more content added, you get a scroll bar.
What I think you really want is to insure you always have a scroll bar if needed, but even then, you need to make sure the div does not extend below the bottom of the page or you could still have problems with the scroll bar itself going off the page. I've configured something that is probably more what your intent is, but note that I had to use multiple nested relative or absolute elements to achieve the effect. I also had to guess on some height positioning for the top of elements to clear your titles.

Vertical aligning an absolute positioned div inside a containing div

I'm using the jQuery Cycle plugin to rotate images in a slideshow type fashion. That works fine. The problem I'm having is getting these images (of different sizes) to center in the containing div. The images are inside a slidshow div that has it's position set to absolute by the Cycle plugin.
I've tried setting line-height/vertical-align and whatnot but no dice. Here is the relevant HTML and CSS
HTML:
<div id="projects">
<div class="gallery">
<span class="span1">◄</span><span class="span2">►</span>
<div class="slideshow">
<img src="images/img1.png" />
<img src="images/img1.png" />
<img src="images/img1.png" />
</div>
</div>
</div>
CSS:
#main #home-column-2 #projects
{
width: 330px;
background: #fefff5;
height: 405px;
padding: 12px;
}
#main #home-column-2 #projects .gallery
{
width: 328px;
height: 363px;
position: relative;
background: url('images/bg-home-gallery.jpg');
}
#main #home-column-2 #projects .gallery img
{
position: relative;
z-index: 10;
}
And in case you want to see it, the jQuery:
$('#home-column-2 #projects .gallery .slideshow').cycle(
{
fx: 'scrollHorz',
timeout: 0,
next: "#home-column-2 #projects .gallery span.span2",
prev: "#home-column-2 #projects .gallery span.span1"
});
Any ideas on getting these images to center?
Try this:
http://www.brunildo.org/test/img_center.html
Vertical centering is a pain! Here's what the W3C page says about the vertical center:
CSS level 2 doesn't have a property
for centering things vertically. There
will probably be one in CSS level 3.
But even in CSS2 you can center blocks
vertically, by combining a few
properties. The trick is to specify
that the outer block is to be
formatted as a table cell, because the
contents of a table cell can be
centered vertically.
This method involves a little jquery, but works fantastic in most situations...
let me explain:
if all the images of the slideshow are contained within their own element div pos:absolute and those images are pos:relative, then on a $(window).load() you can run a .each() and find each img in the slideshow and adjust it's top positioning to be offset a certain number of pixels from the top..
jcycle automatically sets each parent div containing the image to pos:absolute on every onafter() so it's useless to apply this pos adjustment to them... instead target each img you have set to pos:relative...
Here is the example:
$(window).load(function() {
// move all slides to the middle of the slideshow stage
var slideshowHeight = 600; //this can dynamic or hard-coded
$('.slideImg').each(function(index) {
var thisHeight = $(this).innerHeight();
var vertAdj = ((slideshowHeight - thisHeight) / 2);
$(this).css('top', vertAdj);
});
});
and this is the html it's working on...
<div class="slideshow" style="position: relative; ">
<div style="position: absolute; top: 0px; left: 0px; display: none; width: 1000px; height: 600px; " id="img0">
<img class="slideImg" src="/images/picture-1.jpg" style="top: 0px; "><!-- the style=top:0 is a result of the jquery -->
</div>
<div style="position: absolute; top: 0px; left: 0px; display: none; width: 1000px; height: 600px; " id="img1">
<img class="slideImg" src="/images/picture-1.jpg" style="top: 89.5px; "><!-- the style=top:89.5px is a result of the jquery -->
</div>
<div style="position: absolute; top: 0px; left: 0px; display: none; width: 1000px; height: 600px; " id="img2">
<img class="slideImg" src="/images/picture-1.jpg" style="top: 13px; "><!-- the style=top:13px is a result of the jquery -->
</div>
</div>
just make sure
.slideImg {
position:relative;
}
I think that's everything... I have an example, but it's on a dev site.. so this link might not last.. but you can take a look at it here:
http://beta.gluemgmt.com/portfolio/rae-scarton-editorial.html
The positions are relative according to the style sheet, so did you try setting them to display: block and margin-top: auto; margin-bottom: auto; ?
Another option is to align them manually in javascript based on the containing div's height.
You need to nest two divs inside each cycle item. The first must have the display: inline-table; and the second must have display: table-cell; both these divs have vertical-align: middle.
So the structure would look something like this:
<div class="slide-container">
<div class="slide">
<div class="outer-container">
<div class="inner-container">
Centered content
</div>
</div>
</div>
<div class="slide">
<div class="outer-container">
<div class="inner-container">
Centered content
</div>
</div>
</div>
</div>
With the following css:
.slide-container {
height: 300px;
}
.outer-container {
height: 300px;
display: inline-table;
vertical-align: middle;
}
.inner-container{
vertical-align: middle;
display: table-cell;
}
You can see it working here http://jsfiddle.net/alsweeet/H9ZSf/6/

Resources