inline block grid system - css won't apply to dynamically created element - javascript

I have a inline -block grid system, I want to do something like add re-order the element and add it back to the grid. The js part is ok, how ever when the element added back, it won't apply the css. I made a simple case to show you the error
Open the link and try clicking show error button you will see the element mess up
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<style>
#grid{
text-align: justify;
font-size: 0.1px;
}
#grid .item{
display: inline-block;
background: #eee;
width: 23%;
height: 100px;
margin-bottom: 2.5%;
}
#grid:after{
content: '';
display: inline-block;
width: 100%;
}
#grid .placeholder{
display: inline-block;
width: 23%;
}
</style>
<script>
$(function(){
$('button').click(function(){
var item = $('#grid').children('.item');
item.prependTo('#grid');
});
});
</script>
<div id="grid">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
</div>
<button>show the error</button>
</body>
</html>
https://jsfiddle.net/6ap0ksy8/2/
Screen shots

You have a whitespace problem!
When you run your script, it will 'refresh' the HTML without whitespace.
You should remove all whitespaces so it will look like the errored version. After that, you have to set a margin to the left and right, so that it always looks good.
Your code (with Javascript):
#grid{
text-align: justify;
font-size: 0.1px;
}
#grid .item{
display: inline-block;
background: #eee;
width: 23%;
height: 100px;
margin-bottom: 2.5%;
}
#grid:after{
content: '';
display: inline-block;
width: 100%;
}
#grid .placeholder{
display: inline-block;
width: 23%;
}
<div id="grid">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
</div>
Without whitespace, using margin + Javascript:
$(function(){
$('button').click(function(){
var item = $('#grid').children('.item');
item.prependTo('#grid');
});
});
#grid{
text-align: justify;
font-size: 0.1px;
}
#grid .item{
display: inline-block;
background: #eee;
width: 23%;
height: 100px;
margin-bottom: 2.5%;
/*added margin*/
margin-left: 5px;
margin-right: 5px;
}
#grid:after{
content: '';
display: inline-block;
width: 100%;
}
#grid .placeholder{
display: inline-block;
width: 23%;
/*added margin*/
margin-left: 5px;
margin-right: 5px;
}
<div id="grid">
<div class="item"></div><--
--><div class="item"></div><--
--><div class="item"></div><--
--><div class="item"></div><--
--><div class="item"></div><--
--><div class="item"></div><--
--><div class="placeholder"></div><--
--><div class="placeholder"></div>
</div>
<button>show the error</button>
Obviously, the best solution is to actually fix your CSS to avoid this kind of ugly 'hack'.

$(function(){
$('button').click(function(){
var item = $('#grid').children('.item');
item.prependTo('#grid');
$('.item').after(" "); // add white space
});
});
the white space added will compensate for the white space trimmed by jquery

Related

Need help in implementing dynamic grid layout

Please refer this fiddle here to understand the problem I'm trying to explain. I want such a layout wherein divs will utilize all the available space. There are 8 divs here which are resizable. When I minimize divs A and B, an empty space is seen below these divs. I want divs D and E to occupy that empty space.
How can I achieve this? There are some jQuery plugins available like gridstack out there but their resizing feature is somewhat different. Without using any available jQuery plugin, is it possible to achieve mentioned effect? If you have any useful resources please share. Thanks in advance.
Edit
One solution could be to have 3 columns in .container but this solution might not work if div is resized horizontally.
Change your div structure to the following I think that will help you.
$(document).ready(function() {
$('.tile').resizable({
handles: 'e, s, se',
containment: '.container'
});
});
.tile
{
height: 180px;
width: 100%;
float: left;
background-color: rgb(232, 232, 232);
border: 1px solid red;
margin: 0% 0% 3% 0%;
min-height: 20px;
max-height: 360px;
max-width: 540px;
min-width: 180px;
text-align: centre
}
.verticalspace{
width:180px;
float:left;
margin: 0% 0% 0% 1%;
}
.container{
overflow: hidden
}
<div class="container">
<div class= "verticalspace">
<div class="tile">A</div>
<div class="tile">E</div>
</div>
<div class= "verticalspace">
<div class="tile">B</div>
<div class="tile">F</div>
</div>
<div class= "verticalspace">
<div class="tile">C</div>
<div class="tile">G</div>
</div>
<div class= "verticalspace">
<div class="tile">D</div>
<div class="tile">H</div>
</div>
</div>
this kind of structure will stay close even if somediv above it is collapsed also
You could try a 3 col solution (And use javascript to properly order the items in each column):
.col {
background: whitesmoke;
width: 165px;
float: left;
}
.item {
height: 150px;
width: 150px;
margin: auto;
background: grey;
margin-top: 15px;
}
.custom {
height: 265px;
}
.custom2 {
height: 30px;
}
<div class="container">
<div class="col">
<div class="item"></div>
<div class="item custom"></div>
<div class="item"></div>
</div>
<div class="col">
<div class="item"></div>
<div class="item custom2"></div>
<div class="item"></div>
</div>
<div class="col">
<div class="item custom2"></div>
<div class="item"></div>
<div class="item custom"></div>
</div>
</div>

How to wrap more than one div around a div

I have a div (Slideshow) and I want to wrap around it small divs (Items). The Slideshow div will be static and the Items will be rendered automatically using a Repeater Control.
I made this image to better illustrate what I need to achieve.
I saw this Question and I thought I could use the same logic, let the Repeater items get rendered normally and then change the markup using JavaScript and use some sort of a CSS Grid layout to style the first 4 items for example on the left and the right and the rest will be beneath them but I'm not sure how to do it plus if there's a more simple solution I thought it could be cleaner than using the concept I saw in the question I referred.
Update1: Changed the picture to show the exact desired output
You could generate a Masonary layout. This plug in may be helpful, https://github.com/desandro/masonry
You could do this with bootstrap columns as well. For the first row, with the slideshow, you have 3 columns. The outer left and right columns will have 2 nested rows. http://getbootstrap.com/examples/grid/. This is what Im most familiar with so I'll show you how I would implement a solution for the first row and how to implement a second row with 4 columns.
<div class="row">
<!-- Outer Left Column -->
<div class="col-xs-4">
<div class="row">
<div class="col-xs-12">
Item
</div>
</div>
<div class="row">
<div class="col-xs-12">
Item
</div>
</div>
</div>
<div class="col-xs-12">
Slide Show
</div>
<!-- Outer Right Column -->
<div class="col-xs-4">
<div class="row">
<div class="col-xs-12">
Item
</div>
</div>
<div class="row">
<div class="col-xs-12">
Item
</div>
</div>
</div>
</div>
<!-- Row With Four Items -->
<div class="row">
<div class="col-xs-3">
Item
</div>
<div class="col-xs-3">
Item
</div>
<div class="col-xs-3">
Item
</div>
<div class="col-xs-3">
Item
</div>
</div>
Checkout the angular material layout system as well. This will be harder to implement though because it requires Angular. https://material.angularjs.org/latest/#/layout/grid
Check this solution out and see if you can adopt it to your project: http://jsfiddle.net/1b0hoked/.
HTML:
<div id = "wrapper">
<div id = "slideshow"></div>
</div>
CSS:
*, :before, :after {
margin: 0;
padding: 0;
border: 0;
box-sizing: border-box;
}
body {
padding: 10px;
}
#wrapper {
counter-reset: item-counter;
text-align: right;
margin: 0 auto;
display: table;
outline: 1px solid gray;
position: relative;
}
#slideshow {
width: 210px;
height: 210px;
line-height: 210px;
text-align: center;
border: 2px solid red;
position: absolute;
top: 5px;
left: 50%;
margin-left: -105px;
}
#slideshow:before {
content: "Slide Show";
vertical-align: middle;
font: bold 16px/1 Sans-Serif;
color: red;
}
.item {
height: 100px;
width: 100px;
text-align: center;
line-height: 96px;
border: 2px solid #aaa;
}
.item:before {
counter-increment: item-counter;
content: "item " counter(item-counter);
vertical-align: middle;
font: bold 12px/1 Sans-Serif;
color: #aaa;
}
.item {
float: left;
margin: 5px;
}
.item:nth-of-type(4n + 1) {
clear: left;
}
.item:nth-of-type(3) {
float: right;
margin-top: -105px;
}
.item:nth-of-type(4) {
float: right;
clear: right;
margin-left: -105px;
}
.item:nth-of-type(2) {
clear: left;
}
JS/jQuery:
$(function() {
var numToAdd = 50;
while(--numToAdd >= 0) {
$("</p>").addClass("item").appendTo("#wrapper");
}
});

Centralising nested Divs which have onclick elements

I have 2 rows, one which needs two images and the other which needs to show information if those images are clicked.
I'm having an issue centralising the images and text within the row div.
<div id="container">
<!-- Image row -->
<div class="row">
<div class="col-md-6">
<div id="badbutton"></div>
</div>
<div class="col-md-6">
<div id="goodbutton"></div>
</div>
</div>
<!-- Text Row -->
<div class="row">
<div class="col-md-6">
<div id="bad" style="display:none;">
<p>Oh no! We'd appreciate it if you'd share your experience with us so we can improve in the future. Just click below to get started.</p>
<p> FORM HERE </p>
</div>
</div>
<div class="col-md-6">
<div id="good" style="display:none;">
<p>Fantastic! Please share your experience with the world on of these popular websites. Just make a selection below to get started.</p>
<ol>
<li>Click here to review us on Google+ Reviews</li>
<li>Click here to review us on Facebook</li>
</ol>
</div>
</div>
</div>
</div>
What's happening is the col-md-6 takes up 45% of the row div but the buttons inside aren't centralising themselves.
Here is the CSS:
.row {
margin: 0 auto;
}
.col-md-6 {
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
.col-md-6 {
width: 45%;
}
#good,
#bad {
width: 50%;
}
Here is the outcome:
Try using display:table-* it will make your elements behavior like a table.
.row {
margin: 0 auto;
display: table-row;
}
.col-md-6 {
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
display: table-cell;
text-align: center;
vertical-align: middle;
}
Give style "text-align:center" to the "col-md-6" div. And display: inline-block to #goodbutton and #badbutton.
Just for example
#badbutton, #goodbutton {
height: 50px;
width: 50px;
display: inline-block;
background: #444;
vertical-align: middle;
}
Sample fiddle here
http://jsfiddle.net/Lw27ofb1/

DIV's reorder by themselves upon expand - how do I keep the same order?

I've got a grid of items that upon click expand to show a table below it. It works fine, but it reorders the DIV's positions as per my illustration below.
I need them to keep their respective position in their "columns".
Here's the illustration to make it clear:
And here is my HTML code:
<div
class="item-component"
ng-controller="CollapseCtrl"
ng-repeat="component in components.components | filter : components.filterByFilter | filter : searchText"
>
<div class="component-wrapper" ng-click="isCollapsed = !isCollapsed">
Item - click to expand
</div>
<div class="codes-wrapper" collapse="isCollapsed">
<table class="table table-striped table-condensed">
Expanded content here
</table>
</div>
</div>
And here is the .item-component class:
.item-component {
width: 33.33333333333333%;
float: left;
padding-left: 15px;
}
How would I achieve the "expected result" in my illustration?
Use display:inline-block instead of float:left on your .item-component
Living Demo
.item-component {
width: 33.33333333333333%;
display: inline-block;
padding-left: 15px;
}
Or, you can take a look at BootStrap and do it by using the :before element maintaning the float:left as you had it before.
You would also need to wrap each row:
.col{
float:left;
width: 32.33%;
min-height: 50px;
background: #ccc;
padding: 20px;
box-sizing: border-box;
}
.row{
display:block;
}
/* This do the trick */
.row:before{
content: " ";
display: table;
box-sizing: border-box;
clear: both;
}
Living example
Update
If you don't want the gap you will have to look for another HTML markup. You will have to print first each column with each rows.
This is the needed html markup:
<div class="col">
<div class="row" id="demo">1</div>
<div class="row">4</div>
<div class="row">7</div>
</div>
<div class="col">
<div class="row">2</div>
<div class="row">5</div>
<div class="row">8</div>
</div>
<div class="col">
<div class="row">3</div>
<div class="row">6</div>
<div class="row">9</div>
</div>
And the needed css:
.col{
float:left;
width: 32.33%;
}
.row{
display:block;
padding: 20px;
box-sizing: border-box;
background: #ccc;
min-height: 50px;
}
#demo{
height: 150px;
background: red;
}
Living demo
You can do it in the following way.
HTML:
<div class="container">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<br class="clear" />
<div class="col">4</div>
<div class="col">5</div>
<div class="col">6</div>
<br class="clear" />
<div class="col">7</div>
<div class="col">8</div>
<div class="col">9</div>
<div>
CSS:
.col {
float: left;
width: 100px;
min-height: 100px;
background: #ccc;
padding: 20px;
margin: 10px;
cursor: pointer;
}
.col:hover {
background: yellow;
}
JS:
$('.col').click(function() {
if ($(this).is('.clicked')) {
$(this).removeClass('clicked');
} else {
$(this).addClass('clicked')
}
});
Live demo: http://jsfiddle.net/S7r3D/1/
ETA: the problem with this solution is that it moves entire row down. I don't really see how to nicely achieve what you want...You could try to overflow the other divs, but it depends on your needs. Is such solution acceptable?
ETA2: actually I made it perfect I think! Have a look here: http://jsfiddle.net/S7r3D/3/
The crucial change was rearranging divs and putting them in columns instead.
HTML:
<div class="container">
<div class="fleft">
<div class="col">1</div>
<div class="col">4</div>
<div class="col">7</div>
</div>
<div class="fleft">
<div class="col">2</div>
<div class="col">5</div>
<div class="col">8</div>
</div>
<div class="fleft">
<div class="col">3</div>
<div class="col">6</div>
<div class="col">9</div>
</div>
<div>
CSS:
.col {
clear: both;
width: 100px;
min-height: 100px;
background: #ccc;
padding: 20px;
margin: 10px;
cursor: pointer;
}
.col:hover {
background: yellow;
}
.col.clicked {
height: 300px;
background-color: red;
}
.fleft
{
float: left;
}
JS: /* same as above */
Create three container divs, and afterwards, put {1, 4, 7} into div1, {2, 5, 8} into div2, and {3, 6, 9} into div3.
Otherwise you will have it very difficult to control their positioning.

placing divs in same line

I have 2 divs. One with N number of squares and another div with 1 square. I want that all squares should be inlined. i.e., the squares of div of "section-loaded" come in 3 lines and half of 4th line, one after the other, then the square of "section-toload" should come in the same 4th line and not down below. Here is the fiddle -
http://jsfiddle.net/UPA4V/
<div class="fix_width650px">
<div class="section-loaded">
<div class = "square"></div>
<div class = "square"></div>
<div class = "square"></div>
<div class = "square"></div>
.
.
.
</div>
<div class="section-toload">
<div class = "square"></div>
</div>
</div>
CSS-
.square{
width: 150px;
height: 150px;
padding: 5px;
text-align: center;
display: inline-block;
position: relative;
}
.section-loaded{
display: inline-block;
float: left;
}
.section-toload{
display: inline-block;
float: left;
position: relative;
overflow: hidden;
}
It would work if you instead setting sections as float, set squares as float.
only css you need:
.square{
width: 150px;
height: 150px;
float:left;
}
try this.
Live demo here
HTML
<div class="fix_width650px">
<div class="section-loaded">
<div class = "square"></div>
<div class = "square"></div>
<div class = "square"></div>
<div class = "square"></div>
</div>
<div class="section-toload">
<div class = "square sqgreen"></div>
<div class = "square sqgreen"></div>
<div class = "square sqgreen"></div>
</div>
</div>
CSS
.square{
width: 150px;
height: 150px;
padding: 5px !important;
text-align: center;
display: inline-block;
position: relative;
float:left;
border:2px dotted red;
margin:5px;
}
.sqgreen{
border:4px dotted green !important;
}
.fix_width650px
{
width:650px;
}
I don't think you can do that.
As 'setion-loaded' is taking more than 1 line, that means the width of this section becomes 100% and whatever the next is goes on new line i.e. 'section-toload' goes on new line.
What you can do is have all squares in one section and apply extra class 'loaded' if they are loaded and the class 'toload' of they are to be loaded.
<div class="section">
<div class="square loaded"></div>
<div class="square loaded"></div>
<div class="square loaded"></div>
<div class="square loaded"></div>
...
...
...
<div class="square toload"></div>
</div>
CSS -
.square {
float: left;
width: 150px;
/** other styles **/
}
You can't, because the shape of the section-loaded box will always be rectangular, while you want to inject your section-toload square inside it, in an arbitrary position.
You can dot it with squares only, or if you need sections, encapsulate each square in one section, like this:
Live demo: http://jsfiddle.net/2QLmJ/
HTML
<div class="fix_width650px">
<div class="section loaded">
<div class = "square"></div>
</div>
<div class="section loaded">
<div class = "square"></div>
</div>
<div class="section loaded">
<div class = "square"></div>
</div>
<div class="section loaded">
<div class = "square"></div>
</div>
<div class="section toload">
<div class = "square"></div>
</div>
</div>
CSS
.square{
width: 150px;
height: 150px;
padding: 5px;
text-align: center;
border: 1px solid #000;
}
.toload .square{
border: 1px solid red;
}
.section{
margin: 5px;
display: inline-block;
float: left;
}
Remove float-left from both the divs and add display:table-cell and vertical-align:bottom
.section-loaded{
display: table-cell;
}
.section-toload{
display: table-cell;
position: relative;
overflow: hidden;
vertical-align:bottom
}
DEMO
if you want something like this .
.square
{
width: 150px;
height: 150px;
padding: 5px;
text-align: center;
float:left;
position: relative;
border:1px solid red;
}
.section-loaded{
display: block;
width:486px;
float: left;
}
.section-toload{
display: block;
float: left;
position:absolute;
overflow: hidden;
}
<div class="fix_width650px" style="height:326px;">
<div class="section-loaded">
<div class = "square">square1</div>
<div class = "square">square2</div>
<div class = "square">square3</div>
<div class = "square">square4</div>
</div>
</div>
<div class="section-toload" style="position :relative;">
<div class = "square">section-toload</div>
</div>

Categories