Improve performance of CSS class switch - css

I have a list of items that can be displayed in "grid or list" mode.
This is implemented in HTML this way :
<!-- List mode -->
<div class="items list">
<ul></ul>
</div>
<!-- Grid mode -->
<div class="items grid">
<ul></ul>
</div>
When the user clicks a button, I just switch between the grid/list CSS classes using jQuery. In my stylesheets I'm styling the .items.grid > ul / .items.list > ul, sometimes hiding sub elements in grid mode, something like :
.items.grid .hidden-grid {
display: none;
}
.items.grid ul li {
float: left;
display: inline-block;
width: 80px;
height: 80px;
}
The number of elements displayed in the list can vary, and is loaded via "infinite scroll" until there are remaining items.
This is working fairly good, but it starts being slow when the number of elements grows. I was expecting this to be instantaneous, but it blocks the browser.
What could I do to make it faster ?
The looks related to the browser having to render the elements again.
Could this be related to the CSS structure ?

This was actually related to CSS selectors and the way the browser parses them to render the page, or render elements again.
It is very logical when you know, but browsers evaluate CSS selectors from right to left, starting from the element they will finally have to style. Even CSS IDs don't make a big difference. This is different from the jQuery way of thinking.
Writing efficient CSS selectors
Optimize browser rendering
Why do browsers match CSS selectors from right to left?
So I replaced element selectors by classes selectors, remove deep selectors, and the difference is noticeable.
HTML
<div class="items">
<ul class="grid">
<li class="item>...</li>
</ul>
</div>
CSS
.grid .item {
...
}
.grid .hidden-grid {
display: none !important;
}
.list .item .description {
...
}

Related

What does "div.container" and mean in CSS

Currently tweaking a theme and have tried searching for an answer to this question to this! I'm not stuck - but more just want to know the answer out of curiosity.
I understand that
"#" means an id and
"." means a class.
I've also been reading on this post about how you can add specificity to your html/css through combination of elements/ids/classes ie:
a.fancy { color: red; } /*an element that has an anchor and a class = red.*/
However the code I am working on has the following elements that I don't understand:
div.footer {background-color: {{ settings.footer_color }};
Why would you specify "div.footer" as both the div and the class when simply using a "." would suffice? In my mind there would be no point when the class ".footer" could be used without a div?
Hope you can help me work this one out!
div.footer means the element must both BE a <div> and HAVE the class footer.
.footer would trigger for any element with class footer; for example, a <span class="footer".
div.footer means you are targeting only <div> elements with the class .footer.
<div class="footer">This is targeted.</div>
<p class="footer">This isn't targeted, as it isn't a div with the class .footer.</p>
div .footer, however, would target all elements with the class .footer that are descendants from <div> elements.
<div><p class="footer">This is targeted.</p></div>
<section><p class="footer">But this isn't targeted.</p></section>
With the new implementation of html5 <footer> is a legitimate tag just like <div> or <p>. As confusing as it may be the period . before the footer declaration constrains it to a class name instead of the tag.
So in your case: div.footer = <div> with class name footer = <div class="footer>.
There are numerous reasons why you may make such a declaration.
Sample html
<div>
<div class="footer">Footer only</footer>
<div>Div only</div>
<footer>Footer tag; DIFFERENT</footer>
</div>
Example Css
div {
border: 1px solid red;
}
.footer {
background: blue;
color: #fff; /* white font color */
}
Depending on what you want to do, let's use the specific div.footer examples to show what we can do.back
Inheritance
By inheritance, div.footer will inherit "3 properties" -> background, color and border from the div and .footer declarations.
Now you may want to override some of these properties so...
Overriding Property
Use something like div.footer { color: red; } this will override the white color.
Layout Insight
The beauty of css is that you can use declaration to give you "insight" on what the html markup will be laid out as.
Omitting properties I would write the css as follows:
#footer {}
#footer ul {}
#footer ul li {}
#footer p {}
#footer p a {}
The html:
<div id="footer">
<ul>
<li>List 1</li>
<li>LIst 2</li>
</ul>
<p>Hello! Copyright website company name.</p>
</div>
You could then reverse engineer the html through just css because of the descendent character use. This maximizes the power of "cascading".
--
NOow I hope some of this has given you some insight. A few other pointers are this:
Typically a webpage has only one footer. When there is only one of something use the # id selector ALWAYS.
Use classes to not only apply styles to multiple elements but to also provide "meaning to your markup" -> go back to the principle of "layout insight" to understand what I mean.
div.footer should could more simply be .footer Now, it may be necessary to include div just to say "I only want to apply this class to divs only" and in that case go for it. But defining all your declarations with div.someClasName is not all that valuable.
DO NOT use names of tags as classnames. div.div is very confusing - especially if you are programming for a while. Therefore, since <footer> is now a legit tag you shouldn't apply it as a classname. On the other hand "#footer" could be argued differently because it can only exist once in a webpage.
It's about specificity. div.footer is more specific (a div with that particular class) than .footer (any element with that class).
As to when to use one or the other, it really depends on the markup and CSS you are building.

Hiding all web page items except for single nested div

Suppose my web page has a struture like this:
<body>
<div id="fee">
<div id="fi">
<div id="actual_content">
<p>Content</p>
<div id="some_important_stuff">Blah</div>
<p>More content</p>
<span class="and_another_thing">Meh</span>
...
</div>
<div id="fo>
...
</div>
...
</div>
<div id="fum">
...
</div>
...
</div>
<div id="fazz">
...
</div>
...
</body>
I want to create a print CSS style that hides everything except for the contents of actual_content.
My first attempt was like this:
body * {
display: none; /* Hide everything first */
}
/* Show content div and all of its ancestors */
body > #fee {
display: block;
}
body > #fee > #fi {
display: block;
}
body > #fee > #fi > #actual_content {
display: block;
}
/* Unhide contents of #actual_content */
#actual_content * {
display: block; /* Not ideal */
}
However, since there's no "display: auto" or "display: default", I mess up the styles of actual_content's items when I try to unhide them. I also don't like hard coding the path to actual_content since it might change.
You probably want to use the visibility property. W3Schools describes the difference between the display and visibility properties: the visibility property affects the visibility of an element without affecting its structure, i.e. the space it would normally occupy on the page.
on the top level div set visibility:hidden, then on the div you want set visibility:visible
You'll need to go in and target everything that you don't want to show up individually by setting display:none. If you can change class names, etc, you should un-nest the actual_content <div>, then add classes like hide_div to the other <div>s so they're easy to turn off.
I know your tags show you want a CSS solution, but the PrintArea jQuery plugin is perfect for your needs:
PrintArea sends a specified dom element to the printer, maintaining
the original css styles applied to the element being printed.
http://plugins.jquery.com/project/PrintArea

Show / hide div on click with CSS

I have a menu and three hidden divs that show up depending on what option the user selects. I would like to show / hide them on click using only CSS. I have it working with jquery right now but I want it to be accessible with js disabled. Somebody here provided this code for someone else but it only works with div:hover or div:active, when I change it to div:visited it doesn't work. Would I need to add something or perhaps this isn't the right way to do it? I appreciate any help :)
The thing is my client wants this particular divs to slide/fade when the menu is selected, but I still want them to display correctly with javascript turned off. Maybe z-index could do the trick...?
For a CSS-only solution, try using the checkbox hack. Basically, the idea is to use a checkbox and assign different styles based on whether the box is checked or not used the :checked pseudo selector. The checkbox can be hidden, if need be, by attaching it to a label.
link to dabblet (not mine): http://dabblet.com/gist/1506530
link to CSS Tricks article: http://css-tricks.com/the-checkbox-hack/
This can be achieved by attaching a "tabindex" to an element. This will make that element "clickable". You can then use :focus to select your hidden div as follows...
.clicker {
width:100px;
height:100px;
background-color:blue;
outline:none;
cursor:pointer;
}
.hiddendiv{
display:none;
height:200px;
background-color:green;
}
.clicker:focus + .hiddendiv{
display:block;
}
<html>
<head>
</head>
<body>
<div>
<div class="clicker" tabindex="1">Click me</div>
<div class="hiddendiv"></div>
</div>
</body>
</html>
The + selector will select the nearest element AFTER the "clicker" div. You can use other selectors but I believe there is no current way to select an element that is not a sibling or child.
Although a bit unstandard, a possible solution is to contain the content you want to show/hide inside the <a> so it can be reachable through CSS:
http://jsfiddle.net/Jdrdh/2/
a .hidden {
visibility: hidden;
}
a:visited .hidden {
visibility: visible;
}
<div id="container">
<a href="#">
A
<div class="hidden">hidden content</div>
</a>
</div>
Fiddle to your heart's content
HTML
<div>
<a tabindex="1" class="testA">Test A</a> | <a tabindex="2" class="testB">Test B</a>
<div class="hiddendiv" id="testA">1</div>
<div class="hiddendiv" id="testB">2</div>
</div>
CSS
.hiddendiv {display: none; }
.testA:focus ~ #testA {display: block; }
.testB:focus ~ #testB {display: block; }
Benefits
You can put your menu links horizontally = one after the other in HTML code, and then you can put all the content one after another in the HTML code, after the menu.
In other words - other solutions offer an accordion approach where you click a link and the content appears immediately after the link. The next link then appears after that content.
With this approach you don't get the accordion effect. Rather, all links remain in a fixed position and clicking any link simply updates the displayed content. There is also no limitation on content height.
How it works
In your HTML, you first have a DIV. Everything else sits inside this DIV. This is important - it means every element in your solution (in this case, A for links, and DIV for content), is a sibling to every other element.
Secondly, the anchor tags (A) have a tabindex property. This makes them clickable and therefore they can get focus. We need that for the CSS to work. These could equally be DIVs but I like using A for links - and they'll be styled like my other anchors.
Third, each menu item has a unique class name. This is so that in the CSS we can identify each menu item individually.
Fourth, every content item is a DIV, and has the class="hiddendiv". However each each content item has a unique id.
In your CSS, we set all .hiddendiv elements to display:none; - that is, we hide them all.
Secondly, for each menu item we have a line of CSS. This means if you add more menu items (ie. and more hidden content), you will have to update your CSS, yes.
Third, the CSS is saying that when .testA gets focus (.testA:focus) then the corresponding DIV, identified by ID (#testA) should be displayed.
Last, when I just said "the corresponding DIV", the trick here is the tilde character (~) - this selector will select a sibling element, and it does not have to be the very next element, that matches the selector which, in this case, is the unique ID value (#testA).
It is this tilde that makes this solution different than others offered and this lets you simply update some "display panel" with different content, based on clicking one of those links, and you are not as constrained when it comes to where/how you organise your HTML. All you need, though, is to ensure your hidden DIVs are contained within the same parent element as your clickable links.
Season to taste.
In 2022 you can do this with just HTML by using the details element. A summary or label must be provided using the summary element. details is supported by all major browsers.
<details>
<summary>Click Here for more info</summary>
Here is the extra info you were looking for.
</details>
HTML
<input type="text" value="CLICK TO SHOW CONTENT">
<div id="content">
and the content will show.
</div>
CSS
#content {
display: none;
}
input[type="text"]{
color: transparent;
text-shadow: 0 0 0 #000;
padding: 6px 12px;
width: 150px;
cursor: pointer;
}
input[type="text"]:focus{
outline: none;
}
input:focus + div#content {
display: block;
}
<input type="text" value="CLICK TO SHOW CONTENT">
<div id="content">
and the content will show.
</div>
A little hack-ish but it works. Note that the label tag can be placed any where. The key parts are:
The css input:checked+div selects the div immediately next to/after the input
The label for said checkbox (or hey leave out the label and just have the checkbox)
display:none hides stuff
Code:
<head>
<style>
#sidebar {height:100%; background:blue; width:200px; clear:none; float:left;}
#content {height:100%; background:green; width:400px; clear:none; float:left;}
label {background:yellow;float:left;}
input{display:none;}
input:checked+#sidebar{display:none;}
</style>
</head>
<body>
<div>
<label for="hider">Hide</label>
<input type="checkbox" id="hider">
<div id="sidebar">foo</div>
<div id="content">hello</div>
</div>
</body>
EDIT: Sorry could have read the question better.
One could also use css3 elements to create the slide/fade effect. I am not familiar enough with them to be much help with that aspect but they do exist. Browser support is iffy though.
You could combine the above effect with javascript to use fancy transitions and still have a fall back. jquery has a css method to override the above and slide and fade for transitions.
Tilda(~) mean some sibling after; not next sibling like plus(+).
[key="value"] is an attribute selector.
Radio buttons must have same name
To string tabs together one could use:
<html>
<head>
<style>
input[value="1"]:checked ~ div[id="1"]{
display:none;
}
input[value="2"]:checked ~ div[id="2"]{
display:none;
}
</style>
</head>
<body>
<input type="radio" name="hider" value="1">
<input type="radio" name="hider" value="2">
<div id="1">div 1</div>
<div id="2">div 2</div>
</body>
</html>
You could do this with the CSS3 :target selector.
menu:hover block {
visibility: visible;
}
block:target {
visibility:hidden;
}
You're going to have to either use JS or write a function/method in whatever non-markup language you're using to do this. For instance you could write something that will save the status to a cookie or session variable then check for it on page load. If you want to do it without reloading the page then JS is going to be your only option.
if 'focus' works for you (i.e. stay visible while element has focus after click) then see this existing SO answer:
Hide Show content-list with only CSS, no javascript used
You can find <div> by id, look at it's style.display property and toggle it from none to block and vice versa.
function showDiv(Div) {
var x = document.getElementById(Div);
if(x.style.display=="none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
<div id="welcomeDiv" style="display:none;" class="answer_list">WELCOME</div>
<input type="button" name="answer" value="Show Div" onclick="showDiv('welcomeDiv')" />
With this method, when you click on Nav Dropdown elements it will NOT disappear, unlike plain :focus solution.
key is:
tabindex in parent element
parentDiv:focus-within hiddenDiv { display: block;}
it will work with both: display and visibility css;
HTML code:
<div className="DevNavBar dbb">
{/* MAKE SURE TO ADD TABINDEX TO PARENT ELEMENT, OTHERWISE FAILS */}
<div className="DevNavBar_Item1 drr" tabIndex="0">
item1
<div className="DevNavBar_Item1_HiddenMenu dgg">
<ul>
<li>blah1</li>
<li>blah2</li>
</ul>
</div>
</div>
</div>
CSS code:
.DevNavBar {
padding: 40px;
}
.DevNavBar_Item1 {
padding: 20px;
width: fit-content;
cursor: pointer;
position: relative;
}
.DevNavBar_Item1:hover {
color: red;
}
.DevNavBar_Item1_HiddenMenu {
display: none;
position: absolute;
padding: 10px;
background-color: white;
z-index: 10;
left: 0;
top: 70px;
}
.DevNavBar_Item1:focus {
color: red; // this is so that when Nav Item is opened, color stays red
}
.DevNavBar_Item1:focus-within .DevNavBar_Item1_HiddenMenu {
display: block;
color: black; // this is to remove Bubbling, otherwise it will be RED, like the hover effect
}
Here is Video Demo I created on my youtube channel (note: this is my youtube channel, so I am affiliated to that channel), the link is for 'show and tell' purposes: https://youtu.be/QMqcZjmghf4
CSS does not have an onlclick event handler. You have to use Javascript.
See more info here on CSS Pseudo-classes: http://www.w3schools.com/css/css_pseudo_classes.asp
a:link {color:#FF0000;} /* unvisited link - link is untouched */
a:visited {color:#00FF00;} /* visited link - user has already been to this page */
a:hover {color:#FF00FF;} /* mouse over link - user is hovering over the link with the mouse or has selected it with the keyboard */
a:active {color:#0000FF;} /* selected link - the user has clicked the link and the browser is loading the new page */

CSS Page-Break Not Working in all Browsers

I'm having trouble getting this working in most browsers, except for IE (it even works correctly in IE6) and Opera.
Firefox separates the divs correctly but only prints the first page.
Chrome and Safari only applies the page break to the last div.
How can I get this working across all browsers correctly?
The HTML:
<div id="leftNav">
<ul>
<!--links etc-->
</ul>
</div>
<div id="mainBody">
<div id="container">
<div class="pageBreak">
<!--content-->
</div>
<div class="pageBreak">
<!--content-->
</div>
<div class="pageBreak">
<!--content-->
</div>
</div>
</div>
The divs with the IDs #leftNav and #mainBody are are set to float:left, so they display nicely.
I only want to print the .pageBreak classes, hiding the #leftNav and the rest of the #mainBody with CSS.
The CSS:
#media print
{
#leftNav
{
display:none;
}
#mainBody
{
border:none;
margin:none;
padding:none;
}
}
Parent elements can not have float on them.
Setting float:none on all parent elements makes page-break-before:always work correctly.
Other things that can break page-break are:
using page-break inside tables
floating elements
inline-block elements
block elements with borders
For the sake of completion, and for the benefit of others who are having the same problem, I just want to add that I also had to add overflow: visible to the body tag in order for FireFox to obey the page breaks and even to print more than just the first page.
I've found that Twitter Bootstrap classes add a bunch of stuff to the page which has made it difficult to get page-breaks working. Firefox worked right away, but I've had to follow various suggestions to get it to work in Chrome and, finally, IE (11).
I followed the suggestions here and elsewhere. The only property I "discovered" that I haven't seen yet mentioned is "box-sizing". Bootstrap can set this property to "box-sizing: border-box", which broke IE. An IE-friendly setting is "box-sizing: content-box". I was led to this by the caveat about "block elements with borders" made by Richard Parnaby-King https://stackoverflow.com/a/5314590/3397752.
It looks like it's a bit of an arms race to discover the next property that might break page-breaks.
This is the setting that worked for me (Chrome, FF, IE 11). Basically, it tries to override all the problematic settings on all divs on the printed page. Of course, this might also break your formatting, and that would mean that you'll have to find another way to set up the page.
#media print {
div { float: none !important; position: static !important; display: inline;
box-sizing: content-box !important;
}
}
There is a solution if the parent has float . For the element to which you applied the page-break, make the element overflow:hidden. Thats all. It worked for me.
<div style='float:left'>
<p style='overflow:hidden;page-break-before:always;'></p>
</div>
Although this is not prominently documented, it should be noted that the page-break properties cannot be applied to table elements. If you have any elements that have a display: table; or display:table-cell; applied to them (common in many templates under the clearfix class) then contained elements will ignore the page-break rules. Just cancel out the the rule in your print stylesheet and you should be OK (after the floats have also been removed, of course).
Here is an example of how to do this for the popular clearfix problem.
.clearfix:before, .clearfix:after{
display: block!important;
}
The other place I have run into this is when the template declared the entire page (usually called main or main wrapper) with display:inline-block;
If the section is inside of an inline-block, it will not work so keep your eyes open for those as well. Changing or overwriting display:inline-block; with display:block should work.
I had a position: absolute; in the div printing that caused this not to work.
Make sure the parent element has display:block; rather than display: flex;. This helped me fix the issue
"Firefox versions up to and including 3.5 don’t support the avoid, left, or right values."
IE support is also partial
you can achieve what needed by :page-break-before:always; which is supported in all browsers
"but only print the first page" : I don't think it is css related , I suppose it's sth on print window of browser :)
what's your code?
like this?:
<style>
#media print
{
table {page-break-after:always}
}
#media print
{
table {page-break-before:always}
}
</style>

How to get alternate colors div with pure css and with IE 7 support?

This is HTML.
<div class="container">
<div> background of this i need in white </div>
<div> background of this i need in red </div>
<div> background of this i need in white </div>
<div> background of this i need in red </div>
</div>
I want to select alternate div without adding class or id .
Is it possible with CSS only (no Javascript) with IE 7 support
IE7 doesn't support the selector you would require, which is :nth-child().
Generally you would use
.container div:nth-child(even) {
background: red;
}
IE7 does not support it, unfortunately.
You will need to use JavaScript, or add a class to every odd or even row (perhaps using a server side language).
can't we select every second div inside <div class="container"> [with the CSS2 selectors introduced by IE7]?
Well kind of, with the adjacency selector:
.container div { background: white; }
.container div+div { background: red; }
.container div+div+div { background: white; }
.container div+div+div+div { background: red; }
But that means writing out a rule (of increasingly unwieldy length) for each child. The above covers the example markup with four children, so it's manageable for short, fixed-number-of-children elements, but impractical for elements with a large or unlimited number of children.
This cannot be done.
Use in-line style tags, like,
the following works in IE 7
not tested for others.
<div style="background-color:#ffff00" > Hello YOU div</div>
div:nth-child(odd) { background-color:#ffffff; }
div:nth-child(even) { background-color:#ff0000; }
but i don't know (and can't test) if this works in IE7 - if not, you'll have to use different classes for the divs.

Resources