Lets say I have
<div class="cont">
<div class="single">1</div>
<div class="single">2</div>
<div class="single">3</div>
<div class="single">4</div>
<div class="single">5</div>
<div class="single">6</div>
<div class="single">7</div>
</div>
What I want to have is to plase the .single divs in 2 rows like bricks horizontaly from left to right this simple way: 1st div will be in left top corner, 2nd will be placed below 1st, 3rd will be placed next to 1st, 4th will be placed below 3rd and so on like:
1 3 5 7 9
2 4 6 8
All the divs has the same size.
I've tried with masonry.js and its working like a charm, but its way to complex solution for so simple task (simply solution is important).
fiddle playground
There is a CSS property that does exactly that
http://tinker.io/8ff59
.cont {
-webkit-columns: 5em;
-moz-columns: 5em;
columns: 5em; /* desired width of column */
}
http://caniuse.com/#feat=multicolumn
I had the very same problem and solved using the grid.
Here's the CSS you should add to your container:
.cont {
height: 220px;
background: red;
display: grid;
grid-template-rows: repeat(2, 100px);
gap: 10px;
grid-auto-flow: column;
grid-auto-columns: 100px;
}
I don't think you can do that with css with structure as you have.
This structure should help you to get your required layout:
<div class="a">
<div class="b">
<div class="c">1</div>
<div class="c">2</div>
</div>
<div class="b">
<div class="c">3</div>
<div class="c">4</div>
</div>
</div>
<style>
div.a div.b {float: left; width: 100px;}
</style>
For the sake of argument, let's say you can't change your document structure - you need to do this through layout definitions alone.
If you know how many items you will have, the easiest way to manage this would be CSS3 columns with inline-block elements. Your .singles are the inline-blocks, and .cont uses the 'columns' property to set 5 columns each wide enough to hold your singlets, whilst using max-height to force the inline-blocks onto new columns every two items. The singlets have a min-size large enough to stop multiple inline-blocks displaying on the same line.
You can see this effect as a jsfiddle here: http://jsfiddle.net/mwjJG/25/ :
.container {
height: 240px;
columns: 100px 5;
-webkit-columns: 100px 5;
-moz-columns: 100px 5;
}
.single {
display: inline-block;
height: 100px;
width: 100px;
}
Do be aware this won't work on IE<10 unless you can use some kind of JS-based shiv to add support for the columns property (CSS Pie may be able to do this).
I accomplished this with CSS here using this code: It's kind of hackish though.
I set three of the divs (the last three) to the class 'double'
.cont .single {
background: blue;
color: white;
width: 100px;
height: 100px;
margin: 10px;
float:left;
display: inline-block;
}
.cont .double {
background: blue;
color: white;
width: 100px;
height: 100px;
margin: 10px;
display:inline-block;
float:left;
}
div:nth-child(5) {
clear:left;
}
.cont {
height: 220px;
background: red;
}
Related
I hava a page with two columns. I would like to textarea height mimic left column height. Left column is short when webpage loads, but when user starts expanding various properties (checkboxes + dropdownmenus) it grows based on hidden divs. But my textarea is still small in right column and making it staticly bigger does not look good.
I want it to grow per left column height. Not sure how to achieve that.
EDIT:
Once height: 100%; was added to textarea it solved the issue with columns growth.
But I ran into another two issues.
Textarea in right column overlaps that column on page load. When I try to resize, it suddenly jumps to the column properly. Weird behavior.
here is the pic - textarea overlaps column
Left column context is not aligned properly with right. How I am going to align or justify context of both columns so they end up like this:
here is the pic - final look
My CSS:
body {
height: 100%;
position: relative;
background: #000000;
color: #66adff;
font-size: 105%;
font-family: serif, Arial, Helvetica
}
.column {
border: 5px solid #333;
}
.container{
display: flex;
}
.columnleft {
width: 45%;
padding: 10px;
display: table-cell;
}
.columnright {
width: 45%;
padding: 10px;
display: table-cell;
}
textarea.out {width: 100%; height: 100%; box-sizing: border-box;}
EDIT 2:
Issue 1 - I had text inside the column which pushed area down
Issue 2 - all was fixed with proper padding
Thanks all for replies.
I think you could do this without js, but use CSS Grid instead.
Example:
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr; // the width of each column
grid-template-rows: auto; // row height will auto-adjust to contents
}
<div class="grid-container">
<div class="column-left">
...some dynamic content
gets bigger and bigger and bigger and bigger and bigger
</div>
<div class="column-right">
might be empty or small or large
</div>
</div>
The grid row height will always adjust to the height of the largest content which will make both columns the same height.
Since you're using flex, the right column should be automatically adjusting to match the left column. It sounds like your issue is that the textarea is not expanding automatically to match its container (right column.)
If that's the case, try this simple fix - in your CSS, set textarea height to 100% to automatically fill its parent:
textarea {
height: 100%;
};
Here's an example answer:
Textarea to fill a parent container exactly, with padding
The reason your code wasn't working was because you didn't set the height to your textarea settting the height to 100% will always make it fit the maximum size of it's container (<div>) also i have added box-sizing: border-box; so that you can add padding to your columnright.
A better explanation about box-sizing can be found here (just won't explain here because i couldn't do better then this): https://css-tricks.com/box-sizing/
function f_anyEvent(){
var leftcolumnHeight = document.getElementById('columnleft').style.height.value;
if (document.getElementById('columnleft').style.height != document.getElementById('columnright').style.height)
document.getElementById('columnright').style.height = leftcolumnHeight.value;
}
document.getElementById('add').addEventListener('click', function() {
let columnleft = document.getElementById('columnleft');
columnleft.innerHTML += '<h1>a</h1>';
});
.row{
display: flex;
}
.column {
border: 1px solid #333;
}
.columnleft {
float: left;
width: 45%;
padding: 10px;
display: table-cell;
}
.columnright {
float: left;
width: 45%;
padding: 10px;
display: table-cell;
}
textarea {
width: 100%;
height: 100%;
box-sizing: border-box;
}
<div class="row">
<div id="columnleft" class="column columnleft">
</div>
<div id="columnright" class="column columnright">
<textarea></textarea>
</div>
</div>
<button id="add">
add
</button>
Every time you click add it will add an <h1> to your left column and your textarea will get the same height as columnleft.
Here's a basic demo of an interface similar to yours that uses display: grid on the parent container to automagically keep the two inner divs the same height. (Click on the blue details element to trigger a height change.)
It's wonderfully simple. (Thanks for inspiring me to finally learn how grid works.)
// The JavaScript isn't needed for the dynamic styling. (It just copies the text.)
const
left = document.getElementById("left"),
right = document.getElementById("right");
left.addEventListener("change", showOutput);
function showOutput(event){
right.innerHTML = this.querySelector("#reasons").value
}
div { max-width: 400px; border: 1px solid grey; }
details{ margin: 10px 5px; color: #0000DD; text-decoration: underline; }
/* This is where the magic happens */
#container { display: grid; grid-template-columns: 1fr 1fr; }
#left{ padding: 10px; }
#right { white-space: pre-wrap; }
<div id="container">
<div id="left">
<label> <input type="checkbox"/> I like pie </label>
<details>
<summary>Type your reasons here</summary> <textarea id="reasons"></textarea>
</details>
</div>
<div id="right"></div>
</div>
I have catalog of 6 picture. I am showing them in 1 row. On larger screens all 6 photos shows correctly, but when i change screen width to tablet size of mobile size, picture cuts in half.
The behaviour i want is that, show all 6 pictures on larger screen, but as soon as user window size, only picture which can be shown completely in that particular screen size show show, and other should get hide. Right now, I am using overflow: hidden and container of fixed size.
Below are some screenshots to show the issue,
The question is too general but I think this would be a sample for it.
add below styles to the div wraps images.
.wrapper {
display: flex;
flex-wrap: wrap;
overflow: hidden;
// the following styles are optional but you must specify width and height
width: 100%;
height: 320px;
padding: 20px;
}
and add these styles to images.
img {
height: 100%;
width: auto;
// optional
margin-right: 50px;
margin-top: 50px;
}
The wrapper styles make that images wrap in multiple lines if they expand the wrapper width and overflow: hidden makes that only single line shows
Use width:100% on img tag in html
OR
You can use it n your style-sheet like
img{
width:100%;
}
also try to use objectfit:contain if you img has some fixed height width
here is amir mahdi digbari expanded solution in action.
You can achieve the same with css grid but flexbox is good enough for this.
.img {
height: 200px;
width: 200px;
border: 1px solid red;
}
.wrapper {
display: flex;
overflow: hidden;
width: 100%;
height: 200px;
flex-wrap: wrap;
justify-content: space-around;
border: 2px solid blue;
}
.container {
width: 1250px;
max-width: 100%;
margin: auto;
}
<div class="container">
<div class="wrapper">
<div class="img">Img1</div>
<div class="img">Img2</div>
<div class="img">Img3</div>
<div class="img">Img4</div>
<div class="img">Img5</div>
<div class="img">Img6</div>
</div>
</div>
Happy coding!
I'm pretty new to web development and I'm working on something which requires two divs to always take up 100% of the viewport.
I have div A which is an interactive image that should be as big as possible and should take up the top part of the screen.
Then div B which contains either 1 or 2 buttons depending on what action is done on the interactive div A. Div B is at the bottom of the view.
Is there a clean way to make the size of A depend on the size that div B takes up dynamically? Like just the "remainder" of the viewport should be div A. I put an image below of what I'm attempting to achieve. The second image shows what would happen if some action is done in div A - for simplicity, we could say if some method potato() is called, we want div B to now contain two buttons.
I have tried doing a solution with:
position: fixed;
bottom: 0;
and Div B looks 90% right that way, but it doesn't resize Div A and I also don't want Div B "covering" anything in this way. I just want it to be the same level as Div A and sharing the space to get 100% of the viewport.
Any help would be greatly appreciated! I'd prefer to use plain CSS if possible. I'm doing some away team work and can't add much in the way of libraries or new dependencies to the project.
check on this fiddle https://jsfiddle.net/kt931frp/1/ the trick is using flex as suggested by the below answer.
<div class="wrapper">
<div class="part1"></div>
<div class="part2">
<div contenteditable="true"class="contenteditable">continue typing...</div>
</div>
</div>
body {
margin: 0;
}
.wrapper {
height: 100vh;
display: flex;
flex-direction: column;
}
.part1 {
background:#ffff00;
flex: 1 0 auto;
}
.part2 {
padding: 2em;
color: white;
background:#ff0000;
}
.contenteditable{
width:100%;
min-height:50px;
}
Actually, this is pretty easy using Flexbox and the flex property.
You can change the padding value to see how the top block reacts.
body {
margin: 0;
}
main {
height: 100vh;
display: flex;
flex-direction: column;
}
.top-part {
flex: 1 0 auto; /* This tells `top-part` to take the remaining place. */
background: violet;
}
.bottom-part {
padding: 2em;
color: white;
background: lightblue;
}
<main>
<section class="top-part"></section>
<section class="bottom-part">
Some text here
</section>
</main>
Bringing my 2 cents, you can also take advantage of display: table|table-row|table-cell to create this layout (see the MDN documentation on display property to know more).
The trick when using these properties, unless display: flex, is to tell the "actions" cell to measure 0.1px, which will force the cell to be the minimum possible. However, it does not crushes its inner content, allowing to dynamically adjust depending the content inside.
As cells are by default sharing spaces, this does the job for this kind of layout because the "Div A" is using the rest of the available space.
Check this JSFiddle or use the snippet code below to play with it. I annoted the properties you can tweak.
body {
margin: 0px;
}
.app {
width: 100vw;
height: 100vh;
display: table;
}
.main,
.actions {
display: table-row;
}
.main > div,
.actions > div {
display: table-cell;
vertical-align: middle;
text-align: center;
border-width: 10px; /* tweak this */
border-style: solid; /* tweak this */
}
.main > div {
border-color: purple; /* tweak this */
background-color: violet; /* tweak this */
}
.actions > div {
padding: 20px; /* tweak this */
border-color: blue; /* tweak this */
background-color: lightblue; /* tweak this */
height: 0.1px;
}
.button {
width: 200px; /* tweak this */
padding: 10px; /* tweak this */
}
<div class="app">
<main class="main">
<div>
Div A
</div>
</main>
<footer class="actions">
<div>
<div>
Div B - some text and 2 buttons
</div>
<div>
<button class="button">
Button 1
</button>
</div>
<div>
<button class="button">
Button 2
</button>
</div>
</div>
</footer>
</div>
Hope it help you getting inspiration.
I have a page that has 2 columns. The first column is a dynamic width. It contains a bunch of tabular data in tables. The 2nd column is a fixed width full of navigation stuff.
The 2 columns are divs with float left. I need to accomplish 2 things.
I need to center the 2 divs on the page. For example, if the first div is 600px wide as dictated by the data inside of it and the second div is a fixed 200px, the centering point is 400px.
I don't want the 2nd div to wrap down if the browser window is resized.
I'm thinking that I may have to nest the 2 divs inside of another div, set the parent div width using javascript, then center it.
I created this fiddle to help illustrate. http://jsfiddle.net/darthg8r/uhKdt/
Surround them with a div and set its style to:
width: ( whatever you need )
margin: 0 auto; // this centers the div
You can set the width dynamically with JavaScript if needed. As long as it's smaller than 100% of the surrounding container, it will stay centered.
You could achieve this with the following code:
HTML:
<div id="wrapper">
<div id="container">
<div id="variable">test</div>
<div id="fixed">test</div>
</div>
</div>
CSS:
#wrapper { overflow: hidden; }
#container {
float: left;
position: relative;
left: 50%; }
#container > div {
float: left;
position: relative;
right: 50%;
height: 300px; }
#variable {
background: red;
width: 300px; }
#fixed {
background: blue;
width: 200px; }
Preview: https://jsfiddle.net/Wexcode/mreLt/
You could also achieve this effect by wrapping the two elements in a container, setting them both to display: inline-block, and finally setting their container to have text-align: center.
The answer is a little more complicated than this, so let me know if you want to choose this route instead.
To make it so the elements don't fall to the next line, use inline-block.
<div id="container">
<div id="variable">
<p>test</p>
</div><div id="fixed">
<p>test</p>
</div>
</div>
CSS:
body { margin: 0; }
#container {
color: #fff;
text-align: center;
white-space: nowrap; }
#container > div {
height: 300px;
display: inline-block; }
#variable {
background: red;
width: 100px; }
#fixed {
background: blue;
width: 200px; }
Preview: https://jsfiddle.net/Wexcode/mreLt/2/
I have a container with a bunch of equally sized elements. The container has a width of 100% up to a certain px amount, so if a user shrinks their screen down, elements from the first row may be moved down to the second row to fit, and from the second row to the third row, etc.
I'd like the .spacer div to act as a pseudo margin so that the first element in the second row of divs, no matter what div it actually is, will be spaced 250px out from the left side of the container. I want that .spacer div to always remain at a fixed point relative to the container (right at the beginning of the second row) but also affect the position of the first div in that row. How can I accomplish this with CSS? Open to JS solutions as well.
Here's a Codepen that shows the situation I'm describing:
https://codepen.io/anon/pen/QMMyLj
Any ideas?
Not sure, but check if you are looking something like this:
.container {
background-color: black;
width: 80%;
max-width: 1800px;
min-height: 1000px;
padding: 10px 5px;
text-align: center;
margin: 0 auto;
}
.square {
display: inline-block;
height: 250px;
width: 250px;
background-color: white;
float: none;
margin-left: 5px;
margin-right: 5px;
margin-bottom: 20px;
text-align: center;
line-height: 250px
}
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
<div class="square">6</div>
<div class="square">7</div>
<div class="square">8</div>
<div class="square">9</div>
<div class="square">10</div>
<div class="square">11</div>
<div class="square">12</div>
<div class="square">13</div>
<div class="square">14</div>
<div class="square">15</div>
</div>
Here is a possible solution using css grid and variables. It uses css-grid to layout the red spacer, and javascript to update the number of columns required. (Note that they are only supported in modern browsers http://caniuse.com/css-grid/embed)
CSS
:root {
--colNum: 1;
}
.container {
display: grid;
justify-content: left;
grid-template-columns: repeat(var(--colNum), auto);
}
.square {
height: 250px;
width: 250px;
background-color: white;
}
.spacer {
background-color: red;
width: 250px;
grid-row: 2 / span 1;
grid-col: 1 / span 1;
}
JS
function setNoOfColumns(){
columns = Math.floor(window.innerWidth / 250);
document.documentElement.style.setProperty("--colNum", columns);
}
window.addEventListener("resize", function(){
setNoOfColumns();
});
setNoOfColumns();
Code: https://codepen.io/anon/pen/mMMPwO