I'm looking for an easy and elegant solution to do the following:
I've seen a bunch of Q&A here on StackOverflow, however the majority describes some fixed (known) sizes in pixels. What I would like to achieve is really flexible layout where:
1) Position the div at certain vertical position and have it a certain height -> solved with setting position: fixed; top: 30%; height: 40%;
2) Position the div at the center horizontally -< tried width: auto; margin: 0 auto; but this didn't work
3) Size the nested divs (I'm using the spans right now, but probably that doesn't matter in this context) with their height equal to their width and height of 1 line to be equal to 1/3 (roughly) of the parent div. Also I would like those nested divs to be content agnostic, i.e. set the font size based on the size of the div rather than pushing the divs by increasing the text size. Also, so far the whole thing will break if I exclude couple of captions from the nested divs
So far it looks like this:
I'm pretty sure this is achievable without any js and I'd be happy to get any advice on this.
Thanks
Update 1: I'm updating the post with the link to fiddle, thanks to Sari for the advice.
You may want to consider using a flexbox for this layout. By its nature a flexbox is a flexible box.
Try this:
HTML (no changes to your fiddle demo)
<div id="flexdiv">
<div id="li1" class="li">
<span id="l1" class="l">1</span>
<span id="l2" class="l">2</span>
<span id="l3" class="l">3</span>
<span id="l4" class="l">4</span>
</div>
<div id="li2" class="li">
<span id="l5" class="l">5</span>
<span id="l6" class="l">6</span>
<span id="l7" class="l">7</span>
<span id="l8" class="l">8</span>
</div>
<div id="li3" class="li">
<span id="l9" class="l">9</span>
<span id="l10" class="l">A</span>
<span id="l11" class="l">B</span>
<span id="l12" class="l">C</span>
</div>
</div>
CSS
html, body { height: 100%; }
body {
display: flex; /* establish flex container */
justify-content: center; /* center #flexdiv horizontally */
align-items: center; /* center #flexdiv vertically */
}
#flexdiv {
display: flex; /* establish (nested) flex container */
flex-direction: column; /* align li boxes vertically */
height: 48vmin; /* height relative to viewport size */
}
.li {
display: flex;
text-align: center;
height: 16vmin; /* height relative to viewport size */
}
.l {
width: 16vmin; /* boxes maintain aspect ratio */
line-height: 16vmin; /* vertically center text */
font-size: 7vmin; /* font size scales */
}
DEMO: http://jsfiddle.net/6bsoze4z/4/
Try setting top using the calc function:
top: calc(30%);
Related
I have a big html project due at work and I just have to add one final touch. I am trying to create a horizontal icon list on my page but have been running into issues. Here is a picture of EXACTLY what I need to create. please point me in the right direction or send over some code to try. Thanks
Here is a (very) basic implementation of how to use flexbox to create this three-column effect. Each individual cell will grow/shrink to equally fill the available width. Of course this needs some fine-tuning, but I hope it at least gives you a good starting point :)
.flex-container {
display: flex;
height: 100px;
width: 100%;
background-color: #00ff00;
justify-content: space-between; /* could also try with space-around */
}
.flex-child {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
background-color: #ff0000;
height: calc(100% - 20px); /* for demonstration purposes, subtracts top and bottom margin from height */
margin: 10px; /* for demonstration purposes */
}
<div class="flex-container">
<div class="flex-child">
Content here
</div>
<div class="flex-child">
Content here
</div>
<div class="flex-child">
Content here
</div>
</div>
What issues have you been running into?
It just a big flex container that contains 3 small flex containers.
In each small container, you will need 3 divs, the first div also flex, contain an icon and a text.
I have a .parent div and within that I have an unknown number of .child divs. I need the child divs to be in a vertical grid and all of them need to be equal height. Unfortunately, I can't use javascript for this.
I have tried different combinations of display: inline-block and float: left, but I can't get the children to be the same height.
I am able to achieve same height using display: table-cell but then I run into another problem that the children don't split onto multiple lines if the total width exceeds the container width.
Is there a way to do this with pure css? I only need to support IE10+ if that helps (flexbox?)
You can use a wrapping flexbox - see how the heights are auto-adjusted (due to the align-items:stretch property which is default) when the child divs wrap as you resize the window.
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.wrapper {
display: flex;
flex-flow: row wrap;
}
.wrapper > div {
border: 1px solid red;
}
<div class="wrapper">
<div>
some text here some text here
</div>
<div>
some text here
<br/>more text here
</div>
<div>
some text here
<br/>more text here and some more and some more
</div>
<div>
some text here
<br/>more text here
<br/>more text here
</div>
</div>
Yes you could use flexbox.
.parent{
display: flex;
}
.child{
flex:1;
}
You could try using viewport units.
Something like this might work:
.child {
height: 1vw;
}
This will make the child elements have 1/100 of the viewport width.
To read more about viewport units
Viewport units support
I have two different divs with various contents, and would like them to be the same height and width. It seems like a bad idea to set their height and width to a fixed pixel size, because their size should probably vary based on browser/screen size. Setting their width to a percentage works, but percentage is not an option for height.
Is there a way to ensure two divs have the same dimensions without setting to fixed pixel sizes? Or are fixed pixel sizes really so bad?
Having an outer div with display: table; and these two divs inside it with display: table-cell; should work for you.
I'd suggest defining a container div which varies according to screen width (using #media screen) and using css3's flex to define your divs like so :
HTML
<div class="container">
<div class="first-div">first div </div>
<div class="second-div">second div </div>
</div>
CSS
.first-div{
-webkit-flex: 1; /* Safari 6.1+ */
flex: 1;
background-color:yellow;
border: 2px solid black;
}
.second-div{
-webkit-flex: 1; /* Safari 6.1+ */
flex: 1;
background-color:blue;
border: 2px solid black;
}
.container{
width:auto;
display: -webkit-flex; /* Safari */
-webkit-align-items: center; /* Safari 7.0+ */
display: flex;
align-items: center;
}
https://jsfiddle.net/sujy3bq4/19/
Hope this helps you.
When using height, you need to make sure that you have a full body to work with. By default, the body height is auto. If you set the height to 100%, you can start to use the height attribute on child elements.
Just remember that height is always set to it's parent:
body,html{height:100%;}
div{width:50%; height:50%;}
.el1{float:left; background:#f00;}
.el2{float:right; background:#0f0;}
<div class="el1"></div>
<div class="el2"></div>
If using CSS3 is an option in your case then you can use the 'ViewPort Percentage Lengths" Details on W3.
Something like below should work. (Refer question here for more details.)
div {
height:100vh;
}
Super easy and intuitive way to make responsive, square containers
Scalable percentage heights with padding-bottom:
See Codepen
Basically, set the height to 0, and set the bottom padding to any percentage you'd like.
.box {
float: left;
width: 23%;
height: 0;
padding-bottom:23%;
margin: 1%;
background-color: #e6e6e6;
box-sizing: border-box;
text-align: center;
}
<section>
<div class="box">
1
</div>
<div class="box">
2
</div>
<div class="box">
3
</div>
<div class="box">
4
</div>
</section>
I have a complex hierarchy structure in my code that can't really be changed. It is a collection of inline-block divs that contain images, inside of an outer div. Something like this:
<div> <!-- text-align: center -->
<div><img/></div><!-- display: inline-block -->
<div><img/></div><!-- display: inline-block -->
<div><img/></div><!-- display: inline-block -->
<div><img/></div><!-- display: inline-block -->
<!-- ... -->
</div>
I need these images to fill the screen based on the users browser window. I also need the images themselves to be left-aligned - so if the browser can fit 5 images per row, and the last row has only 1 image, that image needs to be all the way to the left, not centered. However, I need the entire group to be center aligned, so we don't have a huge white margin on the right side.
I have tried adding another div in the hierarchy, something like this:
<div><!-- text-align: center -->
<div><!-- display: inline-block -->
<div><img/></div><!-- display: inline-block -->
<div><img/></div><!-- display: inline-block -->
<div><img/></div><!-- display: inline-block -->
<div><img/></div><!-- display: inline-block -->
<!-- ... -->
</div>
</div>
This does not work, as the middle div ends up being at full width, despite being inline-block. An example can be found here: http://jsfiddle.net/cwmRw/
Any ideas on how I can do this? Thanks!
You can do this using CSS3 Media Queries by setting the width of the div based on different resolution bounding values. I've copied the css here, in case jsfiddle doesn't keep it around forever.
.img-block{
max-width: 160px;
max-height: 160px;
}
.div-block{
display: inline-block;
}
.img-container{
margin-left: auto;
margin-right: auto;
}
#media all and (min-width:984px){
.img-container{
width: 985px;
}
}
#media all and (min-width:820px) and (max-width: 984px){
.img-container{
width: 820px;
}
}
#media all and (min-width:656px) and (max-width:820px){
.img-container{
width: 656px;
}
}
#media all and (min-width:492px) and (max-width:656px){
.img-container{
width: 492px;
}
}
#media all and (min-width:328px) and (max-width:492px){
.img-container{
width: 328px;
}
}
#media all and (min-width:164px) and (max-width:328px){
.img-container{
width: 164px;
}
}
Here's a modified version of the original code http://jsfiddle.net/hxHuV/9/
Here is a working solution if you are allowed to use jQuery:
http://jsfiddle.net/cwmRw/6/
It dynamically calculates the width of img-sub-container and also re-calculates it if the window size changes.
For a pure CSS solution, you need to know the width of img-sub-container (pixels, percentage...).
Unlike height, the width expands to left and right as much as possible in block level elements.
If you make img-sub-container an inline element, let's say by display:inline-block;, you still need width to be set in order for margin: 0px auto; to work and center it.
Since you don't know how much width you will need, you have to dynamically calculate and set it.
If you know the width of your images and the number of images per row, then you can set the width of your container and center it horizontally with margin: 0 auto like in fiddle while floating the container of your images to avoid the whitespace (4px gap) between each image due to inline-block. You don't need the .sub container anymore but if you remove it you then need a clearfix on your container element because it only contains floats and have no other elements in the flow: updated fiddle
Or without floats, you need to remove the whitespace, by example by writing </div><div> (better remove whitespace in HTML code then trying to negate its effect in CSS, it's far more robust)
Or you can center with text-align the container and set the width of the .sub like in this other fiddle
How do I align a <div> which contains an image (or flash) vertically with CSS. Height and width are dynamic.
This is a pure CSS2 solution for horizontally and vertically centering without known sizes of either container nor child. No hacks are involved. I discovered it for this answer and I also demonstrated it in this answer.
The solution is based on vertical-align: middle in conjunction with line-height: 0, which parent has a fixed line-height.
The HTML:
<span id="center">
<span id="wrap">
<img src="http://lorempixum.com/300/250/abstract" alt="" />
</span>
</span>
And the CSS:
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
#center {
position: relative;
display: block;
top: 50%;
margin-top: -1000px;
height: 2000px;
text-align: center;
line-height: 2000px;
}
#wrap {
line-height: 0;
}
#wrap img {
vertical-align: middle;
}
Tested on Win7 in IE8, IE9, Opera 11.51, Safari 5.0.5, FF 6.0, Chrome 13.0.
The only caveat is IE7, for which the two innermost elements have to declared at one line, as demonstrated in this fiddle:
<span id="center">
<span id="wrap"><img src="http://lorempixum.com/300/250/abstract" alt="" /></span>
</span>
Note that the span's are also required for IE7. In every other browser, the span's may be div's.
You can do this by using inline-blocks, one with height: 100% (and same heights for HTML and BODY) and vertical-align: middle.
Example 1: http://jsfiddle.net/kizu/TQX9b/ (a lot of content, so it's full width)
Example 2: http://jsfiddle.net/kizu/TQX9b/2/ (an image with any size)
In this example I use spans, so It would work in IE without hacks, if you'd like to use divs, don't forget to add in Conditional Comments for IE .helper, .content { display: inline; zoom: 1; }, so inline-blocks would work for block elements.
In addition to the other answers here, the CSS3 flexible box model will, amongst other things, allow you to achieve this.
You only need a single container element. Everything inside it will be laid out according to the flexible box model rules.
<div class="container">
<img src="/logo.png"/>
</div>
The CSS is pretty simple, actually:
.container {
display: box;
box-orient: horizontal;
box-pack: center;
box-align: center;
}
I've omitted vendor-prefixed rules for brevity.
Here's a demo in which the img is always in the centre of the page: http://jsfiddle.net/zn8bm/
Note that Flexbox is a fledgling specification, and is only currently implemented in Safari, Chrome and Firefox 4+.
I would recommend this solution by Bruno: http://www.brunildo.org/test/img_center.html
However, I ran into a problem w/ his solution w/r/t webkit. It appears that webkit was rendering a small space at the top of the div if the empty span was allowed to be there. So, for my solution I only add the empty span if I detect the browser to be IE (If someone figures out how to get rid of the space, let me know!) So, my solution ends up being:
HTML:
<div class="outerdiv">
<img src="..." />
</div>
CSS:
.outerdiv {
display: table-cell;
width: 200px;
height: 150px;
text-align: center;
vertical-align: middle;
}
.ie_vertical_align * {
vertical-align: middle;
}
.ie_vertical_align span {
display: inline-block;
height: 150px;
width: 0;
}
And if I detect the browser to be IE I add an empty span element before the img tag and a css style so it looks like:
<div class="outerdiv ie_vertical_align">
<span></span>
<img src="..." />
</div>
Here's a JSFiddle with this code.
Dušan Janovský, Czech web developer, has published a cross-browser solution for this some time ago. Read http://www.jakpsatweb.cz/css/css-vertical-center-solution.html
If you don't care about IE7 and below, you don't have to use multiple nested divs. If you have a div that you want to align vertically, that div is within some container (even if the container is your <body>). Therefore, you can specify display: table-cell and vertical-align: middle on the container, and then your div will be vertically centered.
However, if you do care about IE7 and below, you will need an additional container to make it work (yes, via a hack).
Take a look at this fiddle. It displays correctly in IE6-9 and other major browsers. #container2 is present solely for IE7 and below, so if you don't care about them, you can remove it as well as the IE-specific conditional styles.
Set the image as background of the div and align it center
try the 50% padding trick:
<html>
<body style="width:50%; height: 50%;">
<div style="display:block; display:inline-block; layout-grid:line;
text-align:center; vertical-align:bottom;
padding: 50% 0 50% 0">test</div>
</body>
</html>
This is possible if you know the height of the image or flash object to be centered. You don't need to know the container's height/width, but you do need to know the contained height/width.
It's possible using float, clear and negative margins. Example: www.laurenackley.com homepage.
html
<div id='container'><!-- container can be BODY -->
<div id='vertical-center'> </div>
<div id='contained-with-known-height'>
<p>stuff</p>
</div>
</div>
css
#vertical-center{
height:50%;
width:1px;
float:left;
margin-bottom:-50px;/** 1/2 of inner div's known height **/
}
#contained-with-known-height{
height:100px;
clear:left;
margin:0 auto;/** horizontal center **/
width:700px;
text-align:left;
}
#container{/** or body **/
text-align:center;
/** width and height unknown **/
}
If you don't know the inner elements width/height. You are out of luck with <div>. BUT -- table cells (<td>) do support vertical-align:middle; If you can't get it done with the div stuff above, go with a table inside the container, and put the div you are centering inside a td with vertical-align middle.