Bootstrap 2 Column Layout- Unequal Post size fix - css

I have created an app in ruby on rails and am using bootstrap ,i am using a 2 column layout ,the problem is the post sizes are unequal and an awkward gap ensues which i want to get rid of.
What my index page currently looks like:
What i want my index page to look like:
my index.html.erb
<div class="container">
<% #posts.each_slice(2) do |posts| %>
<div class="posts-wrapper row">
<% posts.each do |post| %>
<div class="col-lg-4 col-md-offset-1">
<%= post.body %>
</div>
<% end %>
</div>
<% end %>
</div>

Move .row out of the loop and it will be fixed
or try the following code this should also work
<div class="container">
<div class="posts-wrapper row">
<% #posts.each do |post| %>
<div class="col-lg-6">
<%= post.body %>
</div>
<% end %>
</div>
</div>

I would have used JQuery Masonry Library

Related

Rails - how can I display left and right layout for image and its content in every other row

I want to to loop through each post and display a left and right layout of image and its content in every other row
like this Theme
basically the html is:
<div class="container">
<div>
<div class="images"><img src="image1"></div>
<div class="images-content">content 1 here</div>
</div>
<div>
<div class="images images-right"><img src="image2"></div>
<div class="images-content images-content-right">content 2 here</div>
</div>
<div>
<div class="images"><img src="image3"></div>
<div class="images-content">content 3 here</div>
</div>
<div>
<div class="images images-right"><img src="image4"></div>
<div class="images-content images-content-right">content 4 here</div>
</div>
<div>
<div class="images"><img src="image5"></div>
<div class="images-content">content 5 here</div>
</div>
<div>
<div class="images images-right"><img src="image6"></div>
<div class="images-content images-content-right">content 6 here</div>
</div>
</div>
I have tried this cycle example
<% #posts.each do |post| %>
<div class="<%= cycle('images', 'images images-right') %>">
Image here
</div>
<% end %>
but the problem is how to add the respective content div classes which goes with the images
You can use with_index to add classes dynamically to your odd-indexed posts.
Also, please prefer using image_tag instead of using raw HTML to create <img> tag.
<div class="container">
<% #posts.each.with_index do |post, index| %>
<div class="images <%= 'images-right' if index.odd? %>"><%= image_tag post.image %></div>
<div class="images-content <%= 'images-content-right' if index.odd? %>"><%= post.content %></div>
<% end %>
<div>
It on what attributes your Post model has. Presumably it has content and image attributes?
<% #posts.each do |post| %>
<div>
<div class="<%= cycle('images', 'images images-right') %>">
<%= post.image %>
</div>
<div class="<%= cycle('images-content', 'images-content images-content-right') %>">
<%= post.content %>
</div>
</div>
<% end %>

Why is my bootstrap clearfix breaking in my Rails collection?

I am a student working on my final project. Below you will see two screen-shots of my application. The first is the normal desktop view, where everything is rendered correctly. As you begin to resize the view-port smaller, the position of items becomes uneven as you can see in the second screen shot.
Am I using the clearfix incorrectly for Bootstrap? I attempted to place the clearfix underneath each vehicle but then realized from checking the Bootstrap documentation that the clearflix class must wrap around said items. Below is my code:
vehicles/index.html.erb
<div class="row">
<!-- Side Column -->
<div class="col-sm-3">
<h3 class="item-category">Make: </h3>
<ul class="side-menu">
<%= form_tag filter_vehicles_path do |f| %>
<% Vehicle.makes.each do |make| %>
<li>
<%= display_chosen_check_box_tag(make, params[:makes], "makes[]") -%>
<%= make -%>
</li>
<% end %>
<h3 class="item-category">Year: </h3>
<% Vehicle.year_ranges.each do |range| %>
<li>
<%= display_chosen_check_box_tag(range, params[:years], "years[]") -%>
<%= range -%>
</li>
<% end %>
<li><%= submit_tag "Filter" %></li>
<% end %>
</ul>
</div>
<!-- Body Column -->
<div class="col-sm-9">
<div class="row">
<div class="clearfix">
<% #vehicles.each do |vehicle| %>
<div class="col-sm-6 bottom">
<h3 class="item-title"><%= link_to "#{vehicle.make} #{vehicle.model}", vehicle %></h3>
<%= image_tag(vehicle.primary_image.image_url, class: "img-responsive") if vehicle.primary_image %>
<p class="index-info"><%= vehicle.user.name %>'s <%= vehicle.year %> <%= vehicle.make %> <%= vehicle.model %></p>
<%= link_to "View Details", vehicle, class: "item-more" %>
</div>
<% end %>
</div>
</div>
</div>
</div>
the loop in question
<!-- Body Column -->
<div class="col-sm-9">
<div class="row">
<div class="clearfix">
<% #vehicles.each do |vehicle| %>
<div class="col-sm-6 bottom">
<h3 class="item-title"><%= link_to "#{vehicle.make} #{vehicle.model}", vehicle %></h3>
<%= image_tag(vehicle.primary_image.image_url, class: "img-responsive") if vehicle.primary_image %>
<p class="index-info"><%= vehicle.user.name %>'s <%= vehicle.year %> <%= vehicle.make %> <%= vehicle.model %></p>
<%= link_to "View Details", vehicle, class: "item-more" %>
</div>
<% end %>
</div>
</div>
</div>
Regards.
No need to add too much of javascript and and clearfix and all. We just need to have tweak in css.
You just need to add min-height to items. Everything will be solved. I have created a fiddle for you.
In fiddle:
Demo1 is your scenerio and demo2 is the fixed scenerio.
try resizing the viewport to see the effect on demo1 and demo 2.
https://jsfiddle.net/Anuj_Kumar/sc17mzkp/1/
If still your problem is not solved just let me know i will solve that too.
Thanks
You need to set your body code with following structure for your resolve issue. You will need to add clearfix class after every 2 item.
<div class="col-sm-9">
<div class="row">
<div class="item-layout">
<div class="item">Your content</div>
<div class="item">Your content</div>
<span class="clearfix visible-lg-block"></span>
<div class="item">Your content</div>
<div class="item">Your content</div>
<span class="clearfix visible-lg-block"></span>
<div class="item">Your content</div>
<div class="item">Your content</div>
<span class="clearfix visible-lg-block"></span>
<div class="item">Your content</div>
<div class="item">Your content</div>
<span class="clearfix visible-lg-block"></span>
</div>
</div>
</div>
According to your code, You have set 2 column(2 item) in per row. So, You will need to add clearfix class after every 2 item. but, Here, Your code is dynamic with loop. So, Here, You will need to add clearfix class dynamic every 2 item. So, You will add dynamic clearfix class with jquery according screen view.
Try following instruction with your code.
First of all, add item-layout class in your main item div. also, add item class in your loop div. following example.
<!-- Body Column -->
<div class="col-sm-9">
<div class="row">
<div class="item-layout">
<% #vehicles.each do |vehicle| %>
<div class="col-sm-6 bottom item">
<h3 class="item-title"><%= link_to "#{vehicle.make} #{vehicle.model}", vehicle %></h3>
<%= image_tag(vehicle.primary_image.image_url, class: "img-responsive") if vehicle.primary_image %>
<p class="index-info"><%= vehicle.user.name %>'s <%= vehicle.year %> <%= vehicle.make %> <%= vehicle.model %></p>
<%= link_to "View Details", vehicle, class: "item-more" %>
</div>
<% end %>
</div>
</div>
</div>
also, add following jquery for add dynamic <span class="clearfix visible-lg-block"></span> for clearfix.
<script type="text/javascript">
$(document).ready(function(){
$screensize = $(window).width();
if ($screensize > 1199) {
$(".item-layout > .clearfix").remove();
$('.item-layout .item:nth-child(2n)').after('<span class="clearfix visible-lg-block"></span>');
}
if ($screensize < 1199) {
$(".item-layout > .clearfix").remove();
$('.item-layout .item:nth-child(2n)').after('<span class="clearfix visible-lg-block visible-md-block"></span>');
}
if ($screensize < 991) {
$(".item-layout > .clearfix").remove();
$('.item-layout .item:nth-child(2n)').after('<span class="clearfix visible-lg-block visible-sm-block"></span>');
}
$( window ).resize(function() {
$screensize = $(window).width();
if ($screensize > 1199) {
$(".item-layout > .clearfix").remove();
$('.item-layout .item:nth-child(2n)').after('<span class="clearfix visible-lg-block"></span>');
}
if ($screensize < 1199) {
$(".item-layout > .clearfix").remove();
$('.item-layout .item:nth-child(2n)').after('<span class="clearfix visible-lg-block visible-md-block"></span>');
}
if ($screensize < 991) {
$(".item-layout > .clearfix").remove();
$('.item-layout .item:nth-child(2n)').after('<span class="clearfix visible-lg-block visible-sm-block"></span>');
}
if ($screensize < 767) {
$(".item-layout > .clearfix").remove();
}
});
});
</script>
<!-- Body Column -->
<div class="col-sm-9">
<div class="row">
<div class="clearfix">
<% #vehicles.each do |vehicle| %>
<div class="col-sm-6 bottom" style="display: -webkit-flex;display: flex;">
<h3 class="item-title"><%= link_to "#{vehicle.make} #{vehicle.model}", vehicle %></h3>
<%= image_tag(vehicle.primary_image.image_url, class: "img-responsive") if vehicle.primary_image %>
<p class="index-info"><%= vehicle.user.name %>'s <%= vehicle.year %> <%= vehicle.make %> <%= vehicle.model %></p>
<%= link_to "View Details", vehicle, class: "item-more" %>
</div>
<% end %>
</div>
</div>
</div>
add this style="display: -webkit-flex;display: flex;".
The problem is that your object heights are uneven. You're looking for a grid-style substitute given that you have an expectation to have these items reflow on resize.
I'd recommend using a CSS Flexbox layout on your collection container.
display: flex;
flex-wrap: wrap;
Here's a demonstration.
The other problem (as HarnishDesign noted) is that your use of the clearfix is incorrect. It puts everything after on a whole new line because it's using the clear: both rule. Read up on the clear rule here.
Edit 1
It's worth noting that the Flexbox properties are not standardized yet, but there is wide support for them.

Foundation Text Grid

I'm trying to create a grid with text, not images, similar to the 'content section' in the Zurb template: http://foundation.zurb.com/templates/orbit.html
I would like to create three blocks of text on each row.
I am able to create this, but the problem that arises is that sometimes in my data there is only one or two blocks of text for a row.
For example, if a product is missing it's location, is there a way to move ingredients to take the place of location, or if category and location are missing to move ingredients to the place of category?
I'm using Ruby on Rails and Foundation 5.
Thanks!
<div class="row">
<div class="large-4 columns">
<% unless #product.category.nil? %>
<div class="product-heading">Product Category</div>
<div class="product-value">
<%= #product.category %>
</div>
<% end %>
</div>
<div class="large-4 columns">
<% unless #product.location.nil? %>
<div class="product-heading">Product Location</div>
<div class="product-value">
<%= #product.location.sort.join(", ") %>
</div>
<% end %>
</div>
<div class="large-4 columns">
<% unless #product.ingredients.nil? %>
<div class="product-heading">Product Ingredients</div>
<div class="product-value">
<%= #product.ingredients.sort.join(", ") %>
</div>
<% end %>
</div>
</div>
HTML generated from Max Williams' suggestion.
<div class="row">
<div class="large-4 columns">
<div class="product-heading">Product Category</div>
<div class="product-value">Food </div>
</div>
<div class="large-4 columns">
<div class="product-heading">Product Ingredients</div>
<div class="product-value">Flour, Sugar </div>
</div>
</div>
Javascript to try and remove empty li tag
<script>$('li, p')
.filter(function() {
return $.trim($(this).text()) === '' && $(this).children().length == 0
})
.remove();
</script>
The key is to look for repeated elements, and abstract them out, for example by using a loop. eg
<% product_cells = [["Category", #product.category], ["Location", #product.location_string], ["Ingredients", #product.ingredients_string]] %>
<div class="row">
<% product_cells.each do |title, data| %>
<% unless data.blank? %>
<div class="large-4 columns">
<div class="product-heading">Product <%= title %></div>
<div class="product-value"><%= data %> </div>
</div>
<% end %>
<% end %>
</div>
Note that i've put the test in a different place, so the whole large-4 div is skipped if the data is blank.
This sort of thing #product.location.sort.join(", ") should usually be replaced with a method in the Product model, eg
#in Product
def location_string
self.location.reject(&:blank?).sort.join(", ")
end
def ingredients_string
self.ingredients.reject(&:blank?).sort.join(", ")
end
then you could change the above code to
<% product_cells = [["Category", #product.category], ["Location", #product.location_string], ["Ingredients", #product.ingredients_string]] %>
EDIT: changed string methods to cope with nils
EDIT2: changed my original answer to use the model methods i added.

How to make a full-width jumbotron?

If you look at the twitter-bootstrap website their jumbotron touches their nav-header. That's what I'm trying to replicate.
I added it to the top of my valuations index like so:
<div class="jumbotron">
<div class="container">
<h1>Values <small>subjective, put here whatever inspires you. </small></h1>
</div>
</div>
I also tried it without the container even though bootstrap says,
"To make the jumbotron full width, and without rounded corners, place it outside all .containers and instead add a .container within."
Is it because my application.html.erb is broken down into columns and so the jumbotron will only expand to the width of the col-md-9?
<body>
<%= render 'layouts/header' %>
<% flash.each do |name, msg| %>
<%= content_tag(:div, msg, class: "alert alert-info") %>
<% end %>
<div class="container-fluid">
<div class="container">
<div class="col-md-9">
<%= yield %>
</div>
<div class="col-md-3">
<% if current_user.present? %>
<%= render 'layouts/sidebar' %>
<% end %>
</div>
</div>
I tried putting in its own partial but then there was padding between the nav-header and the jumbotron that I don't want. Like I said I want it like the bootstrap site. The other problem with a partial is I'd need a lot of them because I want to change the words in the jumbotron depending on the page.
How can we do it like bootstap?
Thanks for your time!
Yes, it's because whatever is rendered in the <%= yield%> gets wrapped in col-md-9. You can either:
close col-md-9 in views where you want to have the full-width jumbotron, and re-open it again in the footer.
don't use col-md-9 in application.rb if most of your views need to be expanding to full width.
EDIT:
To avoid repetition, you can paste the jumbotron styling in between your layouts/header and container-fluid, and use a variable for populating it with page-specific text. Here is what I mean:
<%= render 'layouts/header' %>
<% flash.each do |name, msg| %>
<%= content_tag(:div, msg, class: "alert alert-info") %>
<% end %>
<div class="jumbotron">
<p class="text-center">
<%= #jumbotext %> <!-- this variable should be assigned in your controller action-->
</p>
</div>
<div class="container-fluid">
<div class="container"> <!-- check this too. not sure why you have two containers-->
<div class="col-md-9">
...

How can I make this a horizontal list?

Right now my users are displaying vertically. I would like them to display horizontally side by side. I know this is a very simple to do however, I am having a hard time getting it to be how I would like. Thank you in advance.
User/Index
<div class="page-header">
<center><strong><h1> All Users </h1></strong></center>
</div>
<% #users.each do |user| %>
<div class="user horizontal-align col-md-2">
<%= link_to image_tag(user.avatar.url(:thumb)), user %>
<br><%= link_to user.name, user %></br>
<% if current_user.admin %>
<%= link_to "Delete", user, method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
<% end %>
</div>
<div class="center">
<%= will_paginate #users, renderer: BootstrapPagination::Rails %>
</div>
User CSS
.user {
width: 200px;
display: inline-block;
}
Try the following:
Isolate .user from the .col-x-x containers. The col containers should be used for layout only. Styling the .user element is overriding the BS3 layout styles.
Remove any width definitions in your CSS for .user. Allow width to fall.
Wrap nested columns with .row
jsFiddle: http://jsfiddle.net/zktfu52t/2/
EX:
<div class="col-md-offset-4 col-md-8 col-lg-8 col-lg-offset-4">
<div class="row">
<% #users.each do |user| %>
<div class="horizontal-align col-md-2">
<div class="user">
<%= link_to image_tag(user.avatar.url(:thumb)), user %>
<br><%= link_to user.name, user %></br>
<% if current_user.admin %>
<%= link_to "Delete", user, method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
<% end %>
</div>
</div>
try this
<div class="col-md-offset-4 col-md-8 col-lg-8 col-lg-offset-4">
<% #users.each do |user| %>
<div class="user col-md-2 col-lg-2 text-center">
<%= link_to image_tag(user.avatar.url(:thumb)), user %>
<p><%= link_to user.name, user %></p>
<% if current_user.admin %>
<%= link_to "Delete", user, method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
<% end %>
</div>
With this css
.user{
margin:0.2%;
display:block;
}
This will give you 5 across on medium and large screens and vertical stacks on small and extra small screens. A Quick jsFiddle for you.
Also you have unclosed div tags here:
<div class="panel panel-default">
<div class="panel-heading center">
First things first: stop using the center tag. It's deprecated and unreliable. Use CSS for your styling needs.
To get your users displayed horizontally, you need to wrap all of the user details (links, in this case) in some sort of element. A div is probably best. Then you need to set those elements to display: inline-block.

Resources