Responsive CSS improvement issue - css

I started to write a mobile version in css and I am asking you which is the better way:
In the html to write a div which has a class desktop and another div which has a class mobile. And build everthing from zero. For instance:
<div class="container-fluid bg-1 desktop1">
<div class="container">
<div class="col-xs-5 despre-noi-text first-section">
<h2>asdfsdfdf</h2>
<p class="despre-paragraph">
adsdadd
</p>
</div>
<div class="col-xs-7 despre-noi-img second-section"></div>
</div>
</div>
<div class="container-fluid mobile1">
<div class="container">
<div class ="row mobile-row">
<div class="col-xs-12 mobile1-img"></div>
</div>
<div class ="row mobile-row">
<div class="col-xs-12 mobile1-text">
<h2>asdfsdffdfsfsdf</h2>
<p class="mobile1-despre-paragraph">
asdfdfdfd
</p>
<p class="mobile1-despre-paragraph2">saddfsdfsdfsdfd</p>
</div>
</div>
</div>
</div>
And after that I will check with media queries on the mobile resolution which classes will be hidden and which will be not hidden.
#media only screen and (max-width : 480px) {
.desktop1 { display:none; }
.mobile1 { display:block; }
}
OR to overwrite all of the classes in media queries ?

Definitely use media queries to override the default properties. It's generally a good principle to keep your code DRY and easily maintainable. Having two versions of a block of HTML means unnecessary duplication (meaning more code needs to be loaded to the browser) and more work in future maintenance.
It's not a performance issue to use the queries to override the styles -- CSS is built to cascade. Don't feel bad about taking advantage of it (unless you're cascading with little reason and adding unnecessary specification).
Short answer: Save yourself the stress. Don't duplicate the HTML.

Related

Bootstrap switch between class when in tablet or phone viewport

I have this div:
<div class="col-lg-6 col-md-6 col-sm-6">
<p class="btn-toolbar pull-right">Some Content</p>
</div>
I want to know if its possible when the page is in tablet mode (e.g. col-md-6) I want to change the paragraph class instead of pull-right I want to set to pull-left.
Is it possible?
Yes, you will want to use media queries in your css to set the rules differently. If you want the same effect for col-lg-6 you only need to define it in the media query for col-md-6
Keep in mind you only need to define col-sm-6 in your HTML, because it is mobile first the larger sizes will follow suit. You only need to specify the larger values when you want it to change
Yes, but the only way I can see you doing it without messing with media queries is by basically copying all your HTML and applying different classes to each "set" of code you have.
For the HTML that is to appear on a phone, you may want
<div class="col-lg-6 col-md-6 col-sm-6 visible-xs">
<p class="btn-toolbar pull-right">
Some Content
</p>
</div>
For tablets?
<div class="col-lg-6 col-md-6 col-sm-6 visible-md">
<p class="btn-toolbar pull-left">
Some Content
</p>
</div>
Probably not super-efficient but this way you'd be able to have absolute control over every detail of any "version" of your site loaded on a given device.
You could override the pull-right on tablet or above screen sizes, surely?
This avoids splitting the content across two divs as previously stated. I agree, the code splitting nullifies Bootstrap's use, and adds redundant code that could become pretty unmanageable as the content scaled over time.
#media all and (min-width: 768px) and (max-width: 1200px) {
p.btn-toolbar.pull-right {
float: left !important;
}
}

Bootstrap 3 - Remove guttering

Is it possible to remove the padding from one particular grid within Boostrap 3 -
I need to layout images responsively but the design requires no gaps between columns.
Bootstrap 3 introduced row-no-gutters in v3.4.0
https://getbootstrap.com/docs/3.4/css/#grid-remove-gutters
Yep you can do it by creating a custom style sheet and adding a additional css selector to the col class. [http://www.bootply.com/FtnGzu0dea][1]
/* CSS used here will be applied after bootstrap.css */
.thumbnails {
padding: 0;
}
<div class="wrapper">
<div class="container">
<div class="col-md-3 thumbnails">
<div class="thumbnail"><img src="http://placehold.it/350x150"></div>
</div>
<div class="col-md-3 thumbnails">
<div class="thumbnail"><img src="http://placehold.it/350x150"></div>
</div>
<div class="col-md-3 thumbnails">
<div class="thumbnail"><img src="http://placehold.it/350x150"></div>
</div>
<div class="col-md-3 thumbnails">
<div class="thumbnail"><img src="http://placehold.it/350x150"></div>
</div>
</div>
</div>
[1]: http://www.bootp
ly.com/FtnGzu0dea
My suggestion is to add a class for removing the padding at a certain media query width. Here is a test case that uses a header image that should respect the padding at all but the small size. At that point it has no padding and fits the full width of the viewport. I highly recommend using #screen-xs-max if you are compiling LESS source files. It avoids the one pixel jump for media queries that use max-width.
http://jsfiddle.net/jmarikle/htmn5Lov/
CSS
#media (max-width: 767px) { /* replaced with #screen-xs-max if using LESS */
.sm-no-padding [class*=col-] {
padding: 0;
}
}
HTML
<div class="row sm-no-padding">
<div class="col-sm-12">
<img class="img-responsive" src="//placehold.it/2000x1000"/>
Image and/or content in a row where we remove the padding for small screens
</div>
</div>
If you want more granular control with columns rather than at the row level, just apply the class to the columns and change your selector to [class*=col-].sm-no-padding
You can also create a new CSS class and add the following code into your stylesheet.
Custom CSS:
.no-padding > [class*='col-'] {
padding-right:0;
padding-left:0;
}
new CSS to use into your HTML div
.no-padding

Vertical gap between Bootstrap columns

I'm trying to create a layout in Bootstrap that shows three blocks on a larger screen and two blocks on a smaller screen (the breakpoint occurs between sm and md).
<div class="row">
<div class="container">
<div class="col-xs-6 col-md-4">A - 50</div>
<div class="col-xs-6 col-md-4">B - 100</div>
<div class="col-xs-6 col-md-4">C - 75</div>
</div>
</div>
See CodePen example
This however results in an unwanted vertical gap between block A and C.
As I see it I have a few possible options to remove the vertical gap, but perhaps there is a better solution:
Duplicate the html and use visible-sm and visible-md to show the wanted layout. On sm it would have a two column layout with the first column containing both A and C.
Disadvantage: The block content also needs to get duplicated, which might contain a lot of html
Use JavaScript to move the block to the correct column (perhaps jQuery Masonry).
Disadvantage: I would rather have a CSS only solution
Take a look at flexbox, css columns and css grid.
Disadvantage: Browser support isn't there
Imperfect untested solution at http://codepen.io/elliz/pen/fvpLl. Key points:
At small widths
break B out of flow
make container smaller
HTML
<div class="container">
<!-- note: sm -> container 50% -->
<div class="row col-xs-6 col-md-12">
<!-- note: sm -> div = 100% of container which is 50% -->
<div class="col-xs-12 col-md-4 h50">A - 50</div>
<div class="col-xs-12 col-md-4 h100">B - 100</div>
<div class="col-xs-12 col-md-4 h75">C - 75</div>
</div>
</div>
CSS Fragment
/* xs and sm */
#media ( max-width: 991px) {
.h100 {
position: absolute !important; /* better to do with specificity, but quick ugly hack */
margin-left:93%;
}
}
Spacing is not perfect, but gives you a starting point for your experiments.
Note: this can be implemented using FlexBox and Grid (when it is ready) far easier - and the latest alpha version of Bootstrap does support flexbox.
I realize you said you'd prefer a css only solution, but in my opinion what you are trying to accomplish is not what the bootstrap devs had in mind when they designed their grid system. I would use javascript to stick that sucker where you need it:
jQuery/html/css solution
I changed your columns to be containers (I called em buckets)
HTML
<div class="row">
<div class="container">
<div id="leftBucket" class="col-xs-6 col-md-4">
<div id="A" class="h50">A - 50</div>
</div>
<div id="middleBucket" class="col-xs-6 col-md-4">
<div id="B" class="h100">B - 100</div>
</div>
<div id="rightBucket" class="hidden-sm col-md-4">
<div id="C" class="h75">C - 75</div>
</div>
</div>
</div>
<div id="hiddenDiv"></div>
Then I "borrowed" an approach to watching for media queries from the link in the comment below
JS
// stolen from: http://www.fourfront.us/blog/jquery-window-width-and-media-queries
$(window).resize(function(){
if ($("#hiddenDiv").css("float") == "none" ){
// small screen!
$('#C').appendTo('#leftBucket');
} else {
//not a small screen :P
$('#C').appendTo('#rightBucket');
}
});
And added some rules for the hidden div (that I use to watch screen width)
CSS
#hiddenDiv {float:left;}
#media only screen and (max-width: 992px){
#hiddenDiv {float:none;}
}
ps. it's good to see people using hand drawn doodles to get their ideas across, that's how I like to break it down for people also :D
I found a clever way of doing this. Rearrange the order. Put C before B and then use push and pull to swap the order
<div class="row">
<div class="container">
<div class="col-xs-6 col-md-4">A - 50</div>
<div class="col-xs-6 col-md-4 col-md-push-4 ">C - 75</div>
<div class="col-xs-6 col- col-md-4 col-md-pull-4">B- 100</div>
</div>
</div>
I have created a fiddle with a wrapping div added with a fixed width.
For 320 screen size, reduced the wrapper width and also changed float of the B div to float: right
Fiddle here - http://jsfiddle.net/afelixj/2q785vp5/2/

Order of DIVs on mobile with ZURB Foundation (Push/Pull)

Quick question involving foundation. If I want divs to go in order 1 then 2 on desktop and 2 then 1 on mobile, how would I accomplish this using Zurb?
<div class="row">
<div class="three columns">
</div>
<div class="nine columns">
</div>
</div>
Thanks so much for the help!
This can definitely be done. In your code you should order the div's based on how you would display it on the mobile, i.e. 2 then 1. For displaying it properly on larger screens you can override the default styling of the div's.
For testing purposes you can try:
<div class="row">
<div class="nine columns" style="float:right;">
</div>
<div class="three columns" style="float:left;">
</div>
</div>
While the above solution will work, I suggest not using inline styling. I would rather override using custom classes and/or #media tags.
Using those the code would be:
For the HTML:
<div class="row">
<div class="nine columns pull-right">
</div>
<div class="three columns pull-left">
</div>
</div>
For the CSS/Stylesheet:
#media only screen and (min-width: 768px) {
.pull-left {float: left !important;}
.pull-right {float: right !important;}
}
Not sure you can do this strictly with css, but with javascript you can add the pull-x classes when applicable.
theory:
Place the columns in the order you want for the mobile device, or small screens rather. Then in document.ready, check whether show-for-small is visibile or not, if not, you are on a larger screen and can apply push|pull classes to your columns of choice.
pseudo code, assuming you know push/pull technique:
// do this if not on small screen
if ( $('.show-on-small').css('display') == 'none' ) {
// pull or push the columns as needed
$('.myColumnsToPull-two').addClass('pull-two');
} else {
// might be a good idea to revert above change
}

Embedding Bootstrap class properties into another class

I'm using Bootstrap to set up my site layout and have something like:
<div class="row-fluid">
<div class="span3">
</div>
<div class="span9">
</div>
</div>
That works fine. However, I'm slightly bothered by the fact that this is defining the presentation in the markup and to make it easier to make future changes, I'd like to add another layer of indirection. I'd like to add my own class that defines the semantics and then include the Bootstrap class that defines the layout presentation. For example:
<div class="main-block">
<div class="side-bar">
</div>
<div class="content-area">
</div>
</div>
and my corresponding less file...
#import "twitter/bootstrap";
.main-block { .row-fluid }
.side-bar { .span3 }
.content-area { .span9 }
The less documentation states that you can "embed all the properties of a class into another class by simply including the class name as one of its properties" so it looks like it should work, but I am getting an error:
.row-fluid is undefined
Is there something that I am missing? Or is there a better way to go about this? This is in a rails 3.2 project using the less-rails-bootstrap gem if that makes any difference.
It's a little bit more complicated. What you're referring to is essentially what "mixins" are all about. First, let's resolve the error. From the little I see my bet is that you are trying to compile a "custom".less file and that you did not #import the variables.less and mixins.less files at the top of the page. Is that correct? If so, see if that gets the code to compile as expected.
However, once you get the code to compile you'll see that you have a new problem. In this particular case, by attempting to use a name other than .span you will lose any styling that is applied by the attribute selectors in the grid mixin, namely [class*="span"]. Compiled, it looks like this:
[class*="span"] { float: left; margin-left: 20px; }
.row-fluid [class*="span"] {}
.row-fluid [class*="span"]:first-child { margin-left: 0; }
So in this case the attribute selectors apply their styles to any class that starts with "span".
Here are a couple of options that might be better for you:
1) Adding the word "span" before your custom class names should work
<div class="row main-block">
<div class="span-side-bar">
</div>
<div class="span-content-area">
</div>
</div>
2) And using multiple classes will work, but only if you don't apply any styling to the custom classes that would negate any styles in the native grid classes:
<div class="row main-block">
<div class="span3 side-bar">
</div>
<div class="span9 content-area">
</div>
</div>
3) My recommendation is to live with the little bit of extra markup required to maintain the default Bootstrap grid system. Renaming sounds great now, but if you have any desire to merge in future updates, the one mixin I'd leave alone is the grid.
<div class="row">
<div class="span3">
<div class="side-bar">
</div>
</div>
<div class="span9">
<div class="content-area">
</div>
</div>
</div>

Resources