I've got an issue on my webpage that involves margins popping up next to flexboxes when the site is viewed on mobile. I've distilled the issue down to some pretty simple code.
HTML Code
<html>
<head>
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="container">
<!-- When you remove this period, issue goes away -->
.
<div class="smallboxes">
<div class="smallbox1">
</div>
<div class="smallbox2">
</div>
</div>
<div class="bigbox">
</div>
</div>
</body>
</html>
CSS code
.container {
display: flex;
height: 100px;
}
.bigbox {
flex: 2;
background-color: #6e6e6e;
display: flex;
}
.smallboxes {
flex: 1;
display: flex;
flex-direction: column;
}
.smallbox1 {
flex: 2;
background-color: #6e6e6e;
}
.smallbox2 {
flex: 1;
}
When you run the code in Chrome, right-click, click "Inspect", view as IPad Pro in horizontal mode and change the view to 75% or 125%. You'll see a white line between the two boxes. This is showing up on my Note 5 as well. There should be no line between the two grey boxes.
As I mention in the code, when you remove the period, the issue goes away.
Thanks a ton for the help!
P.S. I'm new to SO and can't seem to figure out how insert the "run codepen on this code" button. I'm including a link to the codepen version of this as well.
http://codepen.io/jasonhoward64/pen/XMpYXJ
edit: new answer based on comments of author
I've been playing with your Codepen and the problem is because of the use of "Flex: 1". Flex creates the needed space inside your "container". if you give ".bigBox" flex:2; and ".smallBoxes" flex:1; it will divide ".container" into 3 parts where bigBox will take up 2. When you add an item inside the container without giving it a flex-value, it will try to calculate the needed space.
Try placing the dot inside a span or div (or other element) and give it a flex-value. This will solve your problem.
.container {
display: flex;
height: 100px;
background: red
}
.bigbox {
flex: 5;
background-color: #6e6e6e;
display: flex;
}
.testBox {
background: yellow;
flex: 1;
}
.smallboxes {
flex: 3;
display: flex;
flex-direction: column;
}
.smallbox1 {
flex: 2;
background-color: #6e6e6e;
}
.smallbox2 {
flex: 1
}
<html>
<head>
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="container">
<!-- When you remove this period, issue goes away --> <span class="testBox">test</span>
<div class="smallboxes">
<div class="smallbox1">
</div>
<div class="smallbox2">
</div>
</div>
<div class="bigbox">
</div>
</div>
</body>
</html>
You're code works, but when you add margin of 0 to the body, it breaks again. Do you know why?
body {
margin: 0;
}
.container {
display: flex;
height: 100px;
background: red
}
.bigbox {
flex: 5;
background-color: #6e6e6e;
display: flex;
}
.testBox {
background: yellow;
flex: 1;
}
.smallboxes {
flex: 3;
display: flex;
flex-direction: column;
}
.smallbox1 {
flex: 2;
background-color: #6e6e6e;
}
.smallbox2 {
flex: 1
}
<html>
<head>
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="container">
<!-- When you remove this period, issue goes away --> <span class="testBox">test</span>
<div class="smallboxes">
<div class="smallbox1">
</div>
<div class="smallbox2">
</div>
</div>
<div class="bigbox">
</div>
</div>
</body>
</html>
Related
I'm trying to make a base layout with a left-side menu, right-side content and a top header that scrolls with the page. The content on the right side should also scroll with the main scrollbar.
My (for me unsolvable) problem starts, when I want the left side to be full size (height 100%) because in some cases i want to subtract the header from this.
With this example (https://jsfiddle.net/5q42xvwu/) it is easier to explain. I just want to have the text "TOP SIDER" and "BOTTOM SIDER" always on the screen regardless of whether the header is on the screen or not. So the left side should change the size depending on whether the header is on visible.
I don't know if and how this is possible with CSS. I already know that it is easily possible with JS.
I hope someone can help me with this problem, I already wasted several hours with this. Thank you :)
Here the code (in the fiddle):
<html>
<head>
<style>
body {
margin: 0;
padding: 0;
}
.header {
background-color: red;
}
.main {
background-color: green;
display: flex;
flex-direction: row;
}
.sider {
width: 200px;
background-color: cornflowerblue;
height: 100vh; /* I think here is the problem */
position: sticky;
top:0;
align-self: flex-start;
}
.inner-sider {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
</style>
</head>
<body>
<div class="header">Header</div>
<div class="main">
<div class="sider">
<div class="inner-sider">
<div>TOP SIDER</div>
<div>BOTTOM SIDER</div>
</div>
</div>
<div class="content">
MAIN CONTENT
<!-- SIMULATE A LAGE CONTENT PAGE-->
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br>
END OF MAIN CONTENT
</div>
</div>
</body>
</html>
Edit to further clarify:
The two inner <div> are only there to represent the top and the lower part of the "Inner Sider". In the real example instead of the ".inner-sider" there should be a full hight menu.
Added classes and sticky positioning to top and bottom siders. Hope it does not break your content layout!
body {
margin: 0;
padding: 0;
}
.header {
background-color: red;
}
.main {
background-color: green;
display: flex;
flex-direction: row;
}
.sider {
width: 200px;
background-color: cornflowerblue;
height: 100vh; /* I think here is the problem */
position: sticky;
top: 0;
align-self: flex-start;
}
.inner-sider {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
/* new styles below: */
.inner-top {
position: sticky;
top: 0;
}
.inner-bottom {
position: sticky;
bottom: 0;
}
<html>
<head>
</head>
<body>
<div class="header">Header</div>
<div class="main">
<div class="sider">
<div class="inner-sider">
<div class="inner-top">TOP SIDER</div>
<div class="inner-bottom">BOTTOM SIDER</div>
</div>
</div>
<div class="content">
MAIN CONTENT
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br>END OF MAIN CONTENT
</div>
</div>
</body>
</html>
I am trying to achieve a layout with multiple elements of different height stacked on mobile screens and some elements forming a sidebar for desktop, roughly looking like this:
My first idea was to achieve it via CSS grid, defining one row with two columns and then assigning the grid-area depending on the class (orange vs gray):
Codepen
.layout {
display: grid;
max-width: 860px;
margin: 0 auto;
gap: 20px;
}
#media(min-width: 860px) {
.layout {
grid-template-areas: 'main sidebar';
grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: main;
}
Problem: as multiple sidebar elements now occupy the same grid cell, they overlap instead of just flow on top of each other. I've been trying to wrap my head around alternative solutions for a few days now, but I couldn't find any so far that did not involve reordering the dom with JavaScript. Am I missing the obvious?
EDIT
Flexbox as stated in the answers does not solve this problem (if the position of elements within the list would be known upfront maybe, but this is not the case). Some elements go in the sidebar, some go in the main bar while having a fixed order in the mobile layout.
Use Flexbox, then you can easily do this.
Refer following code,
.layout {
display: flex;
flex-wrap: wrap;
max-width: 860px;
margin: 0 auto;
gap: 20px;
}
set correct order of div (containers) as you need, (the following code is sample one)
<div id="main">
<div style="background-color:coral;" id="myRedDIV"></div>
<div style="background-color:lightblue;" id="myBlueDIV"></div>
<div style="background-color:lightgreen;" id="myGreenDIV"></div>
<div style="background-color:pink;" id="myPinkDIV"></div>
</div>
#main {
width: 100%;
height: 150px;
border: 1px solid #c3c3c3;
display: flex;
flex-wrap: wrap;
}
#main div {
width: 70px;
height: 70px;
}
/* Standard syntax */
div#myRedDIV {order: 1;}
div#myBlueDIV {order: 4;}
div#myGreenDIV {order: 3;}
div#myPinkDIV {order: 2;}
Refer following links for more about Order in Flexbox
Link1 --> About Flexbox Order
Link2 --> About Flexbox Order
Why don't you try with flexbox. you can do it using display:flex, for more about the flex refer below sample.
<!DOCTYPE html>
<html>
<head>
<style>
.flex-container {
display: flex;
flex-wrap: nowrap;
background-color: DodgerBlue;
}
.flex-container > div {
background-color: #f1f1f1;
width: 100px;
margin: 10px;
text-align: center;
line-height: 75px;
font-size: 30px;
}
</style>
</head>
<body>
<h1>Flexible Boxes</h1>
<div class="flex-container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
<p>Try to resize the browser window.</p>
<p>A container with "flex-wrap: nowrap;" will never wrap its items.</p>
<p><strong>Note:</strong> Flexbox is not supported in Internet Explorer 10 or earlier versions.</p>
</body>
</html>
This might not be the answer to your question! (cause I've changed the grid layout into FlexBox)
In this example I'm changing flex-direction via screen breakouts.
More Information on CSS Flex box Direction
Code:
* {
border: 1px solid coral;
padding: 12px;
margin: 12px;
}
.layout {
display: flex;
flex-direction: column;
align-items: center;
}
.layout>* {
display: flex;
flex-direction: row;
}
.sidebar {
background-color: yellow;
}
.content {
background-color: grey;
}
#media(max-width: 860px) {
.layout {
display: flex;
flex-direction: column;
align-items: center;
}
.layout>* {
display: flex;
flex-direction: column;
}
.sidebar {
background-color: yellow;
}
.content {
background-color: grey;
}
.content {
background-color: green;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="layout">
<div>
<div class="content big">
Here's some text
</div>
<div class="sidebar small">
Sidebar Item
</div>
</div>
<div>
<div class="content big">
More Text
</div>
<div class="sidebar small">
another sidebar Item
</div>
</div>
</div>
</body>
</html>
My page starts to change zoom and layout gets slightly messed up when I have a hardcoded width on items located in a Flexbox container (make a very narrow Chrome Devtools responsive window). The problem starts when I make my viewing area narrower than the 300px. Unfortunately, you can't see this problem when running this inside an iframe on jsfiddle - it has to be ran "on it's own", my html block needs to be THE top html block.
Here's the jsfiddle for reference still:
https://jsfiddle.net/elijahww/9e1u7ptr/
<html><head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#productShowcaseContainer {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
}
.contentContainer {
display: flex;
flex: 1;
}
#productShowcaseTitle {
height: 100px;
background-color: antiquewhite;
}
#productShowcaseThumbnailContainer {
flex: 1;
background-color: darkseagreen;
}
</style>
</head>
<body style="margin: 0;">
<div id="productShowcaseContainer">
<div id="productShowcaseTitle"></div>
<div class="contentContainer">
<div id="productShowcaseThumbnailContainer" style="padding: 10px;">
<input style="width:300px;">
</div>
</div>
</div>
</body></html>
I don't know how to make this work.
here is a gif:
This might be happening because you have hard-coded width of input field as 300px and trying to zoom screen width beyond this.
If you really want to have responsive layout then you should be using flex-layout properly and set flex-basis, flex-grow and flex-shrink property of each layout element.
These properties are responsible for handling responsive behaviour of flex-elements.
To Read more about flex layout follow this link Flex tutorial
One option is to give some parent container overflow-x: auto
body {
background-color: #3d5d6a;
}
#container {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
}
.main-content-container {
display: flex;
flex: 1;
}
#top-header-container {
padding: 10px;
height: 100px;
background-color: antiquewhite;
/*align-content: stretch;*/
display: flex;
justify-content: stretch;
}
#main-content-inner {
flex: 1;
background-color: darkseagreen;
}
.responsive-table {
overflow-x: auto;
}
<html><head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body style="margin: 0;">
<div id="container">
<div id="top-header-container">
<div class="responsive-table">
<input style="width:400px;" value="hard coded to 400px">
</div>
</div>
<div class="main-content-container">
<div id="main-content-inner" style="padding: 10px;">
test
</div>
</div>
</div>
</body></html>
I want to create following layout, where a header (green) spans the full width of the screen and is made up of two elements:
a picture (pink), that is top-left aligned, and has the height of the next element
a text block (red), that is top-right aligned. It made of two stacked elements: a text div (yellow) and a button. The width button equals the text width.
The expected output is this:
My code is the following:
.header{
background-color: green;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.flex-element{
display: inline-block;
}
.picture_container{
background-color: pink
}
.picture{
height: 100%;
}
.text_container{
background-color: red
}
.text{
background-color: yellow;
}
<div class="header">
<div class="flex-element picture_container">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/55/Tux_Enhanced.svg/154px-Tux_Enhanced.svg.png" alt="" class="picture">
</div>
<div class="flex-element text_container">
<div class="text">
AAAAAAAAAA <br>
BBB
</div>
<button type="button" name="button" style="width: 100%">foo</button>
</div>
</div>
and gives following output:
The problem is that there is no "space-between" the pink and the red block, and they are not top aligned. I know I could work around it using css grid, yet I'd like to know why it isn't working.
Question: How to make justify-content: space-between have any effect?
This might be a browser issue. Indeed, I am using Firefox Developer Edition 63.0b14 as a browser.
A hack was then to add display: -moz-box; in the .header css definition. It is strange, though, as "Prefixed property values (such as -moz-box) are no longer needed for flexbox to work in major browsers." (see Michael_B's comment). A less hacky solution would hence be still appreciated.
Full code:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>test</title>
<style media="screen">
.header{
background-color: green;
display: -moz-box;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.flex-element{
display: inline-block;
}
.picture_container{
background-color: pink
}
.picture{
height: 100%;
}
.text_container{
background-color: red
}
.text{
background-color: yellow;
}
</style>
</head>
<body>
<div class="header">
<div class="flex-element picture_container">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/55/Tux_Enhanced.svg/154px-Tux_Enhanced.svg.png" alt="" class="picture">
</div>
<div class="flex-element text_container">
<div class="text">
AAAAAAAAAA <br>
BBB
</div>
<button type="button" name="button" style="width: 100%">foo</button>
</div>
</div>
</body>
</html>
Please try below code
<style>
.header {
padding: 10px;
}
.picture {
width: auto;
}
.text_container {
margin: auto 0;
}
.picture_container {
display: block;
}
</style>
I'm new to HTML5 and CSS3 and developing my first site/app for college. Ideally I need it to display on mobile phone image (which I haven't yet mastered) but for now all I'm trying to do it show flexible box working. As you will see text wraps when I adjust window size but logo remains unchanged. It was suggested that I could set image as background to a div which would adjust according to window size but not sure how to do this.
!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<!-- CSS -->
<link rel="stylesheet" href="preposting.css">
<title>Title goes here</title>
</head>
<body>
<div id="container">
<header id="top_header">
<div id="logo">
<img class="logo_image" src="logo.gif" alt="" />
</div>
<div id="welcome">
<h1>Text wraps when I adjust window size but image doesn't. It was suggested that I should set image as background to div and that way it would adjust but not sure how to do this.</h1>
</div>
</header>
</div>
</body>
</html>
#container
{
text-align:left;
border: 10px solid black;
margin: 20px auto;
display:-webkit-box;
-webkit-box-orient: vertical;
-webkit-box-flex: 1;
}
#top_header
{
border:30px solid green;
padding:20px;
background:yellow;
display:-webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-flex: 1;
}
#img.logo_image {
width: 100%;
position: absolute;
top: 0;
left: 0;
}
I see that you are using the old flexible box model: -webkit-box;
the new one is basically only called flex; You would type: display: -webkit-flex;
They have great examples of it here: http://www.w3.org/TR/css3-flexbox/
css:
#main { display: flex; }
#main > article { flex:1; order: 2; }
#main > nav { width: 200px; order: 1; }
#main > aside { width: 200px; order: 3; }
#media all and (max-width: 600px) {
/* Too narrow to support three columns */
#main { flex-flow: column; }
#main > article, #main > nav, #main > aside {
/* Return them to document order */
order: 0; width: auto;
}
}