every time I start to code a new responsive page I come up with this question so I thought I ask you guys about it: "is it normal to break readability when adding responsiveness to pages?"
I think you'll better understand with an example: I have 2 big columns in a 12 columns grid system so I set 2 divs with class .grid-6 and in the css .grid-6 {width:50%}. In the tablet layout the graphic designer has placed three columns so i change the width of those columns to 33% but now I have a div with class grid-6 (which suggests 50% width) and an actual column width of 33%.
So when I start working on responsiveness it all just feels like "hacks".. I though about adding different classes for tablets and phones or other devices (<div class="grid-6 tablet-grid-4 phone-grid-3">) but that just doesn't feel right.
the problem appears when you receive a graphic design that has different amount of columns for each breakpoint..I mean, you can't change the column count in the html, amirite?
Consider using Cascade Framework.
A grid element in Cascade framework is either
One of the following HTML elements : section, main, article, header, footer, aside or nav (these elements are polyfilled with the HTMLshiv for old IE in case you need it).
A div element with a 'col' class (can be used in old IE without a polyfill).
To add a width to a grid element, you add a class of the format 'width-XofY', where Y can be 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16 or 24 and X can be any value lower than X.
More concretely, here are some examples of valid classes you can use in Cascade Framework : 'width-1of2' (width : 50%), 'width-3of4' (width : 25%), 'width-2of5' (width : 40%), 'width-2of5' (width : 40%), 'width-2of7' (width:28.5714286%) and 'width-13of16' (width:81.25%)
Additional to these classes, you can also use the classes 'width-fit' and 'width-fill' that respectively fit to content and fill whatever remains of your 100% width. Or, you could just define your own classes and IDs and just add a custom width for those classes to do things the 'semantic' way.
If your build includes the responsiveness module (which is the case for the recommended builds), the width of all grid elements automatic resets to 100% on mobile. You can use classes like 'mobile-width-3of16', 'phone-width-3of7' or 'tablet-width-2of4' to customize the layout for different width ranges and the classes 'desktop-hidden', 'mobile-hidden', 'phone-hidden' or 'tablet-hidden' to hide content for a specific screen with range.
However, this still may lead to stuff like <div class='col width-1of4 tablet-1of3 phone-1of2'> </div> in some cases. In those cases, going semantic is a better approach. More concretely, do something like <div class='col custom_class'> </div> or <section class='custom_class'> </section> and then set the width for each breakpoint yourself in your custom CSS.
I'm a little lost but I believe your talking about mobile browsers correct? If so #media is your solution.
html,body{
min-height:100%;
}
.grid-6 {
width:33%;
min-height:100%;
margin:0px;
display:inline-block;
}
The above will create a column grid similar to the one you have explained. I think? lol
Converting these to one column for mobile browsers is easy. Think of #media as a condition. Basically I've written 'if device width <= 480px' which is relative to an iPhone 4gs and below screen.
#media only screen and (device-width:480px){
.grid-6{
width:100%;
display:block;
}
}
All other styles that are not declared within the #media condition are inherited from the class' above. hope this helped
First of all it is better to name a class after its function rather than its physical appearance... for example navigationContainer is a better name than leftContainer, as navigationContainer can exist anywhere on the page.
As far as adapting for different layouts, screen sizes and orientations etc. you will want to make use of the media attribute (or the #media declaration) which will allow you to apply class definitions only to devices and screens meeting certain criteria. Herein lies the benefit of naming classes after function. If you name a class after it's function (like mainContentGrid, then you can redefine the class as many times as you like in all your different media stylesheets. Because in principle only one sheet will be applied depending on the viewing context, your styles will always be appropriate for the viewing context. This eliminates the multiple class problem that you have and cleans up your code.
If you want a more precise opinion, please post some code and I'd be happy to give you my thoughts.
The number of columns should stay consistent across all browser sizes; only their width and padding should change. It is however common to reset all columns to 100% width when in mobile, but otherwise they should only shrink, not be dropped entirely. I'd suggest going back to the designer or rejigging your grid to have a multiple that all responses adhere to.
Flexbox is your solution, but it's not time yet.
If you don't care that much about semantics, it's a perfect solution you describe using tablet-grid-4. Grids in definition using sizing in their class names aren't semantic. You can also name it like desktop-main desktop-aside tablet-main tablet-aside and so on. But I always fall short my self in practice. What do you name three even cols in tablet. It's not main, it's not aside. They are cols each of one third :) It's very hard not to speak of layout in html when the whole containers are their for layout.
Regards
Try the Dead Simple Grid. Rather than hard-coding the grid layout classes like
<div class="grid-6 tablet-grid-4 phone-grid-3"></div>
you assign an abstract classes like
<div class="col left"></div>
<div class="col right"></div>
and then assign the width to these classes for the different screen sizes
.left, .right { width: 100%; }
#media only screen and (min-width: 54em) {
.left, .right { width: 50%; }
}
This example targets small screens by default (e.g. smartphones) having left and right fill the entire width of their container (which can be another column since nesting is supported!) and displaying the two elements underneath each other. When the screen is large enough though, the two columns will be displayed next to each other.
Dead Simple Grid is very simple (the entire css code is 250 bytes!) but surprisingly powerful.
Related
I've been struggling to find a way to build this layout. All elements have unknown heights except for the social elements. The related and latest elements are optional.
I'd like to do it without resorting to JS or duplicating elements but I'm actually not sure if it's even possible.
Mobile and tablet are very easily handled with flexbox and the "order" property. I thought I could handle the desktop layout by reverting to floats but since the element heights are unknown this isn't guaranteed ( i.e. the latest and/or related elements might float over to the left if the body copy is short ).
Any ideas? Or should I just suck it up and dynamically add a sidebar to the DOM with JS for the desktop breakpoint?
Edit: Note the order of the elements! If I place the desktop sidebar elements in a container I can no longer re-order them on mobile/tablet with flexbox. Also, I don't believe grid-layout applies since the desktop layout does not follow a grid pattern.
Two-dimensional page layout like this is what CSS Grid was designed for. Flexbox is more suitable to arrange items in one dimension (although a second dimension will easily follow when nesting or wrapping). As others have mentioned, this layout should be totally accomplishable with CSS only.
One approach using CSS Grid is having three template area definitions that change on each breakpoint, as demonstrated here.
Part of the HTML and SCSS for that:
<div class="grid">
<div class="area social"></div>
<div class="area body-social"></div>
<div class="area categories"></div>
<div class="area related-latest"></div>
</div>
.area {
&.social { grid-area: social; }
&.body-social { grid-area: body-social; }
&.categories { grid-area: categories; }
&.related-latest { grid-area: related-latest; }
}
#media (min-width: 64em) {
.grid {
grid-template-areas:
"body-social social"
"body-social categories"
"body-social related-latest";
}
}
I took the liberty of combining some of your sections into areas, as I’m unaware whether the visual design would disallow it. You might have to manage some additional gutters if it does. Also note that the right column in the wide layout is currently only sized to the length of the text inside, which will probably not hold with real content. There will be more use cases I haven’t addressed, but if anything my example can be a starting point for you to work from.
A slightly different approach would be to define grid-template-columns and grid-template-rows for each breakpoint, and configure the correct grid-columns and grid-rows for each area or section. This would imply some more explicit sizing, which has pros and cons in itself.
Furthermore, you would need to think about which layout you want to present to people using a browser without support for CSS Grid.
To learn more about modern layout techniques in CSS, I recommend checking out the articles and videos by Rachel Andrews and Jen Simmons.
Let me know if you have additional questions or remarks.
Is there any way to change the class of a grid container in Semantic UI using media queries or does the solution lie in writing your own Javascript that adds or removes classes to your HTML?
I realize that I didn't quite phrase the quite question properly so I'm going to update it to reflect that. It was exactly about media queries vs JavaScript with regards to Semantic UI.
My problem is this: Let's say I have a stackable grid container with two columns that have classes .four.wide.column and .twelve.wide.column. By default when the window size of the browser is 1000px the text inside the columns is left aligned. However I would like to centre align the text inside the columns when the window is resized to a smaller mobile size of 767 px.
At first I thought of realigning the text inside the columns on media queries however it occurred to me that that would defeat the purpose of Semantic UI because with this solution the class names wouldn't look or behave as described. The normally left aligned column is now centre aligned but the class isn't called centre aligned. What happens if the class was centre aligned and is now left aligned but the name is the same?
Then I wondered if it was possible to add and remove classes using media queries but that doesn't seem to be possible. The one solution that I found that keeps the Semantic UI is to use JavaScript to add and remove classes however I wanted to avoid using JavaScript as a solution.
It depends on what exactly you want to trigger the text-align change. If you want the alignment to change at a specific viewport width, I would recommend using css #media queries instead of a resize listener. For a window resize you'll also want to debounce or throttle your resize event for performance. Depending on how you do that you might experience a momentary flash of unexpected alignment. You don't have to do that with a media query and the change will be immediate.
.ui.grid .column {
text-align: left;
}
#media only screen and (max-width: 600px) {
.ui.grid .column {
text-align: right;
}
}
This is very similar to Bootstrap 3 fluid grid layout issues? and Bootstrap responsiveness view but the options for masonry and isotope, while attractive, aren't an option as I must retain ordering for the elements.
From the linked questions, I've moved a fair bit of the way forward using the clearfix class application as can be seen at http://bootply.com/103688. The clearfix divs are left unindented so they stand out more.
I also found that undesirable results will occur if, as is my case, I am only using some of the column sizes (xs, md, lg). This necessitates that the clearfix also specify the visible-sm or, when the viewport reaches the "small" size, the clearfix is no longer visible, and problematic stacking recurs.
Applying them is simple enough, as this is a real-world fizzbuzz problem, but it seems anti-DRY. Is there a cleaner way for me to do this, with less repetition of the clearfix tags? Some means of having the browser (CSS) compute where the clearfix should be applied?
You can use an manual approach of creating rows according with the number of elements per breaking point. For example:
If you have a row with 2 elements only:
#media(max-width: #screen-tablet){
// create rows (clearfix)
.col-xs-6:nth-of-type(odd){ clear:left; }
}
or if your rows contains 4 elements
#media(min-width: #screen-tablet) and (max-width: #screen-desktop){
// create rows (clearfix)
.col-sm-4:nth-of-type(3n+1){ clear:left; }
}
etc..
I looked at some css rsponsive grids. I'm currently trying Unsemantic.
I don't really understand how it can manage various resolutions like 400, 768, 1024, while we can only use two kind of classes : grid-XX and mobile-grid-XX.
Unsemantic CSS files contain media queries regarding all the resolutions I mentioned above, but I don't understand how I can use them.
For example, if I have two columns on my main page
I would like them to be 50% wide each on 1024px or more, 70% and 30% wide between 640 and 1024px, and 100% wide on 400px and less.
Is it possible?
Do you know any responsive grid system that could be easier to understand and use?
I'm not sure how to do this with Unsemantic. However, I have used Susy to do this exact thing before.
Try Cascade Framework.
Cascade Framework's grid system does exactly what you want. Out of the box, Cascade Framework's grid system supports 60%/40%, 25%/75%, 33.33%/66.66%, 20%/20%/20%/20%/20%, 43.75%/31.25%/25%, 30%/30%/40% and far more combinations. In fact, you can even use combinations like 42.8571429%/{fill to 100%}, {fit content}/{fill to 100%} or {fit content}/30%/{fill to 100%}.
A grid element in Cascade framework is either
One of the following HTML elements : section, main, article, header, footer, aside or nav (these elements are polyfilled with the HTMLshiv for old IE in case you need it).
A div element with a 'col' class (can be used in old IE without a polyfill).
To add a width to a grid element, you add a class of the format 'width-XofY', where Y can be 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16 or 24 and X can be any value lower than X.
More concretely, here are some examples of valid classes you can use in Cascade Framework : 'width-1of2' (width : 50%), 'width-3of4' (width : 25%), 'width-2of5' (width : 40%), 'width-2of5' (width : 40%), 'width-2of7' (width:28.5714286%) and 'width-13of16' (width:81.25%)
Additional to these classes, you can also use the classes 'width-fit' and 'width-fill' that respectively fit to content and fill whatever remains of your 100% width. Or, you could just define your own classes and IDs and just add a custom width for those classes to do things the 'semantic' way.
If your build includes the responsiveness module, the width of all grid elements automatic resets to 100% on mobile. You can use classes like 'mobile-width-3of16', 'phone-width-3of7' or 'tablet-width-2of4' to customize the layout for different width ranges and the classes 'desktop-hidden', 'mobile-hidden', 'phone-hidden' or 'tablet-hidden' to hide content for a specific screen with range.
Note that the current version of Cascade Framework is written in pure CSS. That means there is no way (yet) to configure the breakpoints that distinguish between desktop, tablet and phone by just changing a single variable. You can, however, do a copy-replace of these breakpoints with your own custom breakpoints in the source code if you are dissatisfied with the default breakpoints.
See also http://jslegers.github.io/cascadeframework/grid.html and http://jslegers.github.io/responsiveness/ .
I'm using the 960 Smart Grid to design a website. It's a mobile first grid system, and I'm having a bit of trouble. In order for the grid system to work, the padding-left element cannot change or it breaks, except in the default layout when everything is a single column.
I needed to adjust the padding for an element in the mobile view, which screws up the element when it's larger than the single-column view width (so greater than 768 px). I need to change the padding back to what the original smart-grid style sheet says, but I'm not sure how to do that.
I'm fairly new to this, I don't have the site live at the moment but I can share any code needed. I'm adjusting the padding on a paragraph element, set inside of a div element.
<div id="intro" class="columns twelve" class="row">
<p id="tagline" class="columns eight offset-two">Sample Text.</p>
</div>
Essentially, I need to set a 6% padding for the paragraph element in the mobile view. Once it reaches a minimu width of 768 pixels, I need to eliminate the 6% padding because it breaks the offset-two portion of the tag. The offset is achieved in the smart grid style sheet using a padding-left value based upon the screen size. I'd like to switch back to the default padding from the smart grid style sheet for all of the media queries, if possible. You can check out the basic grid documentation on the site I linked to at the beginning of the question.
Thanks for the help.
I'm not sure if I understood your problem, but it looks like you just need to overwrite the padding for when the browser is less than 768 pixels.
To do this, you just need to add, at the end of your main css (or in a new one, but called after the other one):
#media screen and (max-width: 768px) {
.columns.eight.offset-two {
padding: 6%;
}
}
This means that this style will only be applied if the browser is smaller than 768px, and once it gets bigger, it will bring back the 'default' padding for your element. You don't need to specify the padding again for bigger resolutions,l because the second the browser gets past the number, it completely forgets about the media query (it's like it doesn't exist anymore). The only thing you need to keep in mind is, unless you set another smaller media query after this one, it will apply the 6% to all smaller sizes.
It's important that you keep your media queries at the end, because css is read from top to bottom, and the last style read will be the last applied.