Dynamic Tiled Display - css

I'm a bit of a CSS noob and I was hoping someone here would have the patience to point out the error of my ways.
Basically, I'm creating a mobile web platform and I'm designing a concept "landing page" which will consist of four equally sized rectangular (square on some resolutions) tiles (inspiration drawn from here: http://tinyurl.com/beartss).
Obviously with this application being mobile orientated I've been avoiding fixed widths and heights but can't quite get the same layout as seen in the image I linked. My HTML is laid out as follows:
<div class="page-container">
<div class="tile-1"></div>
<div class="tile-2"></div>
<div class="tile-3"></div>
<div class="tile-4"></div>
</div>
And the current CSS I'm using is...
html, body, .container
{
height: 100%;
min-height: 100%;
}
.page-container
{
margin: 0 auto;
border: 1px solid black;
height: 99%;
min-height: 99%;
width: 99%;
}
.tile-1
{
border: 1px solid black;
height: 48%;
width: 48%;
}
.tile-2
{
border: 1px solid black;
height: 48%;
width: 48%;
}
.tile-3
{
border: 1px solid black;
height: 48%;
width: 48%;
}
.tile-4
{
border: 1px solid black;
height: 48%;
width: 48%;
}
This isn't even remotely near what I'm trying to achieve, and I've come by a rumour that percentage based height is never a good idea, either way, the above CSS gives me this: http://i.imgur.com/nXbcHze.png
Any help would be appreciated, I'm sure I've just missed something with the height.

Normally, block level elements won't appear on the same line as another block level element. So, you need to either float them or change their display to something like inline-block.
http://jsfiddle.net/kyyjg/
You will find that mixing px on your borders with percentages for your dimensions to cause your elements to not take up the right amount of space because of how the box-model works. You might find that adding box-sizing: border-box helpful.
If you're interested in another approach, here's how one might do it using flexbox:
http://jsfiddle.net/LJMdx/4/
html, body {
height: 100%;
}
.page-container {
min-height: 100%;
background: red;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 1%;
}
.page-container div {
-webkit-box-sizing: border-box;
box-sizing: border-box;
-webkit-flex: 1 1 48%;
flex: 1 1 48%;
margin: 1%; /* optional */
border: 1px solid;
}
If you don't want the gaps between the tiles, drop the 1% margin and padding: http://jsfiddle.net/LJMdx/3/
http://caniuse.com/#feat=flexbox

Try float:left. Demo -> is that the solution that your looking for?.
Added a min-width on each the tiles so that the template is the same on any resolution.

Related

Child of Full Screen Container is Trimmed If Taller Than Parent [duplicate]

This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
Closed 4 years ago.
I must be forgetting something fundamental with my vertically and horizontally centered flexbox.
The container is within a parent with vertical scroll, and when the container becomes too tall, it grows beyond the parent top, clipping the content. The bottom stays put.
Try adjusting the height of the view or adding more lines to see it in action.
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
* {
box-sizing: border-box;
}
#wrapper {
background: grey;
height: 100%;
width: 100%;
max-height: 100%;
display: flex;
overflow-y: auto;
align-items: center;
justify-content: center;
}
#box {
margin: 30px 0;
background: white;
border: 1px solid #dfdfdf;
}
<div id="wrapper">
<div id="box">
First line
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br> Last linje
</div>
</div>
How do I keep it from getting clipped? Additionally I'm trying to have a 30px margin above and below the container.
Thanks!
You forgot nothing but you simply need to understand what is happening. First you made your wrapper to be 100% height of screen and then you made the box to be centred vertically and horizontally. When the box has a big height you will have something like this:
Now, when you add overflow-y: auto you will create a scroll that will start from the top of the wrapper until the bottom overflowed content. So it will be like this:
That's why you are able to scroll to the bottom to see the bottom part and not able to see the top part.
To avoid this, use margin:auto to center your element and in this case we will have two situations:
When box-height < wrapper-height we will have the space spread equally on each side because of the margin:auto thus your element will be centred like expected.
When box-height > wrapper-height we will have the normal behavior and your element will overflow and his top edge will stick to the top edge of the wrapper.
You may also notice the same can happen horizontally that's why I will use margin to center on both directions.
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
* {
box-sizing: border-box;
}
#wrapper {
background: grey;
height: 100%;
width: 100%;
max-height: 100%;
padding:30px 0;
display: flex;
overflow-y: auto;
}
#box {
margin: auto;
background: white;
border: 1px solid #dfdfdf;
}
<div id="wrapper">
<div id="box">
First line
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br> Last linje
</div>
</div>
I think what you want is to make your flex item (#box) have a height and set it's overflow, not the flex container. Also, to add your 30px above and below I would remove the margin from the box and instead add padding to the container.
So, updated styles would look like this:
#wrapper {
background: grey;
height: 100%;
width: 100%;
max-height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 30px 0; /*added*/
}
#box {
background: white;
border: 1px solid #dfdfdf;
overflow-y: auto; /*added*/
height: 100%; /*added*/
}
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
* {
box-sizing: border-box;
}
#wrapper {
background: grey;
height: 100%;
width: 100%;
max-height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 30px 0;
}
#box {
background: white;
border: 1px solid #dfdfdf;
overflow-y: auto;
height: 100%;
}
<div id="wrapper">
<div id="box">
First line
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br> Last linje
</div>
</div>
I think you set the top margin in the box class which extends the height of the container. You can maybe set it to padding instead of margin. Hope this helps. Thanks.

Border set in vmin unit causes gap

DESCRIPTION
I have a weird bug where the border causes a small gap between the content and the border itself when set using vmin units.
REPRODUCIBLE SNIPPET
resize the window to see it, as it only happens on some device viewports
body {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
}
.container {
display: flex;
width: 80%;
height: 80%;
border-right: 1vmin solid red;
}
.content {
display: flex;
width: 100%;
height: 100%;
background-color: black;
}
<div class="container">
<div class="content" />
</div>
PREMISES
I'm setting border with vmin unit to keep it consistent between any screen resolution
Elements should keep current structure (border on parent, background on child)
Both elements should have display: flex
PROBLEM
I suspect the problem stands on how the vmin value is being rounded into pixels, creating that additional pixel which can be seen in similar scenarios (where a child with the background highlights the gap).
WHAT I TRIED
By having display: tables instead of flex fixes the extra px, but this can't be an option as flex is needed
vw / vh or any viewport unit generate the same issue
SOLUTION
A solution for having a flexible border could be to simply set the .container:after with a width in percentage, height to 100% and a background-color instead of the border. This solution works perfectly fine, but it's not a scalable solution in case we require more than just a single border side (e.g. border-right).
CONCLUSION
So premised all this, is there perhaps some trick that can be applied directly to the border (or its element) to get around it?
I'm not concerned about finding the first solution that works; As presented, a solution exists already, so the question is based out of mere curiosity for writing better code.
Try to use box-shadow instead.
body {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
}
.container {
display: flex;
width: 80%;
height: 80%;
box-shadow: 1vmin 0 0 0 #f00;
}
.content {
display: flex;
width: 100%;
height: 100%;
background-color: black;
}
<div class="container">
<div class="content" />
</div>
box-shadow: 1vmin 0 0 0 #f00; for right border, box-shadow: 0 0 0 1vmin #f00; for full border.
EDIT:
Why the gap is disappear? I think it is because box-shadow is kind of background with some offset. So, the decimal pixel is on the end. I guess.
But keep in mind that it will act different as being said by #doğukan in the comment.
but box-shadow doesn't work like border. see the difference. with border: i.stack.imgur.com/gqgsD.png box-shadow: i.stack.imgur.com/2ZsrA.png if this is not a problem, box-shadow works fine.
Just set a background to .container?
body {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
}
.container {
display: flex;
width: 80%;
height: 80%;
background-color: black;
border-right: 1vmin solid red;
border-left: 1vmin solid green;
border-top: 1vmin solid blue;
border-bottom: 1vmin solid orange;
}
.content {
display: flex;
width: 100%;
height: 100%;
background-color: black;
}
<div class="container">
<div class="content" />
</div>

Center div vertically without overflowing when content is larger [duplicate]

This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
Closed 4 years ago.
I must be forgetting something fundamental with my vertically and horizontally centered flexbox.
The container is within a parent with vertical scroll, and when the container becomes too tall, it grows beyond the parent top, clipping the content. The bottom stays put.
Try adjusting the height of the view or adding more lines to see it in action.
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
* {
box-sizing: border-box;
}
#wrapper {
background: grey;
height: 100%;
width: 100%;
max-height: 100%;
display: flex;
overflow-y: auto;
align-items: center;
justify-content: center;
}
#box {
margin: 30px 0;
background: white;
border: 1px solid #dfdfdf;
}
<div id="wrapper">
<div id="box">
First line
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br> Last linje
</div>
</div>
How do I keep it from getting clipped? Additionally I'm trying to have a 30px margin above and below the container.
Thanks!
You forgot nothing but you simply need to understand what is happening. First you made your wrapper to be 100% height of screen and then you made the box to be centred vertically and horizontally. When the box has a big height you will have something like this:
Now, when you add overflow-y: auto you will create a scroll that will start from the top of the wrapper until the bottom overflowed content. So it will be like this:
That's why you are able to scroll to the bottom to see the bottom part and not able to see the top part.
To avoid this, use margin:auto to center your element and in this case we will have two situations:
When box-height < wrapper-height we will have the space spread equally on each side because of the margin:auto thus your element will be centred like expected.
When box-height > wrapper-height we will have the normal behavior and your element will overflow and his top edge will stick to the top edge of the wrapper.
You may also notice the same can happen horizontally that's why I will use margin to center on both directions.
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
* {
box-sizing: border-box;
}
#wrapper {
background: grey;
height: 100%;
width: 100%;
max-height: 100%;
padding:30px 0;
display: flex;
overflow-y: auto;
}
#box {
margin: auto;
background: white;
border: 1px solid #dfdfdf;
}
<div id="wrapper">
<div id="box">
First line
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br> Last linje
</div>
</div>
I think what you want is to make your flex item (#box) have a height and set it's overflow, not the flex container. Also, to add your 30px above and below I would remove the margin from the box and instead add padding to the container.
So, updated styles would look like this:
#wrapper {
background: grey;
height: 100%;
width: 100%;
max-height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 30px 0; /*added*/
}
#box {
background: white;
border: 1px solid #dfdfdf;
overflow-y: auto; /*added*/
height: 100%; /*added*/
}
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
* {
box-sizing: border-box;
}
#wrapper {
background: grey;
height: 100%;
width: 100%;
max-height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 30px 0;
}
#box {
background: white;
border: 1px solid #dfdfdf;
overflow-y: auto;
height: 100%;
}
<div id="wrapper">
<div id="box">
First line
<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br>line<br> Last linje
</div>
</div>
I think you set the top margin in the box class which extends the height of the container. You can maybe set it to padding instead of margin. Hope this helps. Thanks.

When using "height: 100vh" for the container, vertical scrollbar appears

I want the content to take the full height of the browser window, but not beyond.
When using 100vh as the container height, I can see the vertical scrollbar appearing.
.container {
height: 100vh;
border: 3px solid lightsteelblue;
border-radius: 10px;
}
What could be the issue?
EDIT:
more detailed code:
CSS
html, body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
.container {
height: 100vh;
margin: 0px;
padding: 0px;
}
.page_content {
height: 85vh;
width: 95vw;
border: 3px solid lightsteelblue;
border-radius: 10px;
overflow-y: auto;
margin: 0 auto;
}
.footer {
height: 14vh;
width: 95vw;
margin: 0px auto;
padding: 0px;
}
HTML
<html>
<body>
<div class="container">
<div class="page_content">
...
</div>
<div class="footer">
...
</div>
</div>
</body>
</html>
By default body and html are assigned to margin or padding to some pixels. Try using following code.
1vh = 1% of veiwport height
100vh = 100% of height.
So never calculate height - 3px. like this
body,html {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
The issue is that you have a border with it, and like padding, you have to add it to your height.
Either you use this :
.container {
height: calc(100vh - 3px);
}
Or this :
.container {
height: 100vh;
border: 3px;
box-sizing: border-box;
}
There is a user agent stylesheet that gets added to any web document, it's nothing but default set of style that each browser applies to the documents being viewed, however these rules have the a very lower precedence order.
Of course the author can over ride these rules, and they do very often.
As of today, google chrome, adds 8px margin to your document if not added or over written by the author.
So let's consider you added a div in your entire HTML document called .container in your case.
You may try doing something like this.
body {
margin: 0;
height: 100vh;
}
.container {
height: 100%;
//if you want to add border to this container,
border: 1px solid cyan;
box-sizing: border-box;
}
Further if you have any other divs inside the container, they would take advantage of .container class 100vh value. You can assign 70% height to .page-content and 30% height to .footer div.
.page-content {
height: 70%
border: 1px solid aquablue;
box-sizing: border-box;
}
.footer {
height: 30%;
}
use
body{
margin :0px;
}
and
.container {
height: 100vh;
border: 3px;
box-sizing: border-box;
}
body {
margin: 0;
}
.container {
height: 100vh;
border: 3px solid lightsteelblue;
border-radius: 10px;
box-sizing: border-box;
}
This did the trick. See and test it here: https://jsfiddle.net/ddan/jsenLgre/
Came across same scenario, some auto margins in browser causesthe vertical scroll bar to appear. Very simple workaround I came across is to use 99vh instead of 100vh
.container {
height: 99vh;
border: 3px;
box-sizing: border-box;
}
I tend to encounter this problem alot my solution is a bit unorthodox but here it is
body{
height: 80vh;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
If you write this at the beginning of your codes, your problem will be fixed.
u can remove the scroll bar by overflow-y:hidden; and u should use calc function to remove ur header height example height: 100vh;
calc(100vh -20px) if ur header is 20px height. so u get the 100vh !

Distribute evenly vertically without flexbox

I am trying to make my site IE9 compatible but I am using flex boxes in lots of places so I need an alternate method for evenly spacing child elements.
My design is responsive so I need the same effect as flexbox where I can evenly space elements but I am not sure how to do it.
Here is a snippet to show how I am using flexbox in my layout.
#container{
width: 500px;
height: 700px;
border: 1px solid #000;
padding: 10px;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.ele1, .ele2, .ele3{
flex: 0 0 auto;
}
.ele1{
height: 200px;
background-color: red;
}
.ele2{
height: 50px;
background-color: blue;
}
.ele3{
height: 100px;
background-color: green;
}
<div id="container">
<div class="ele1"></div>
<div class="ele2"></div>
<div class="ele3"></div>
</div>
How do I do this without flexbox?
You could use Masonry which is a pure JavaScript (it also supports jQuery), as there are no CSS equivalent, if you do/can not use flexbox.
Use margin-top and margin-bottom in percentages. The distribution is roughly dependant upon how tall each box is. I estimated that there's a total of 10% vertical space inside the container that comprises of padding and borders. That leaves 90% to distribute between the inside walls of the container and between themselves.
#container{
width: 500px;
height: 700px;
border: 1px solid #000;
padding: 10px;
/*display: flex;
flex-direction: column;
justify-content: space-around;*/
}
.ele1, .ele2, .ele3{
/*flex: 0 0 auto;*/
}
.ele1{
height: 200px;
background-color: red;
margin: 10% 0 15%;
}
.ele2{
height: 50px;
background-color: blue;
margin: 25% 0 15%;
}
.ele3{
height: 100px;
background-color: green;
margin: 25% 0 0;
}
<div id="container">
<div class="ele1"></div>
<div class="ele2"></div>
<div class="ele3"></div>
</div>
I discovered a flex box polyfil https://github.com/10up/flexibility

Resources