How to style nested ID-elements in CSS/SASS - html

What is the correct way to style a nested element with an ID?
example.html
<div id="content">
<ul id="list">
<li>Just a minimal example</li>
</ul>
</div>
style.sass
#content
background: white;
#list
list-style-type: none;
padding: 10px 15px;
With this it is easier to read the SASS file, as it is obvious, that #list is a child of #content.
But I think the browser has to check for two things, isn't it? First find the #content and then find the #list element.
So should I use?
#content
background: white;
#list
list-style-type: none;
padding: 10px 15px;

I recommend to not nest id selectors as you gain performance. Of course this will be of no matter on small CSS files.
A well used way to "show" the relation between to classes in the CSS output, is to indent child classes like this, but also often the CSS is minified and not human friendly, so it all kind of also depends on who's gonna read it.
#content {
background: white;
}
#list {
list-style-type: none;
padding: 10px 15px;
}

Both are fine. Spacing have no effects in css/sass/less/scss code.

Related

CSS selector optimization

I was looking into ways to optimize css performance and was wondering if their is an existing tool that converts complicated selectors to more simplistic ones.
The tool would look at all css rules and create unique single-pathed selectors that would contain all the proper attributes. It would than looked at every dom node and search for any css matches, and if something is found it would add the simplified selector to the node. The css that is rendered only contains the simplified versions and the html would still have the original classes/ids so the existing setup wouldn't break.
An exaggerated example of what I mean:
#original {
padding: 5px;
background: blue;
}
#original .nav {
font-size: 24px;
}
#original .nav ul {
background: black;
}
#original .nav ul li {
list-style-type: none;
}
#original .nav ul li a {
text-decoration: none;
color: green;
}
#simplified {
padding: 5px;
background: blue;
}
._ranClass1 {
font-size: 24px;
}
._ranClass2 {
background: black;
}
._ranClass3 {
list-style-type: none;
}
._ranClass4 {
text-decoration: none;
color: green;
}
<div id="original">
<h1>Original CSS</h1>
<div class="nav">
<ul class="_ranClass2">
<li>Link 1
</li>
<li>Link 1
</li>
<li>Link 1
</li>
</ul>
</div>
</div>
<div id="simplified">
<h1>Simplified CSS</h1>
<div class="nav _ranClass1">
<ul class="_ranClass2">
<li class="_ranClass3">Link 1
</li>
<li class="_ranClass3">Link 1
</li>
<li class="_ranClass3">Link 1
</li>
</ul>
</div>
</div>
Of course this would require heavy tweaking and may cause more headaches than good, but was wondering if something like this exists.
EDIT:
I am not looking at a way to write more convenient CSS, SASS/SCSS exists for that reason. I am looking for a way to optimize CSS in terms of the browser.
EX: take the original selector
#original .nav ul li a {
text-decoration: none;
color: green;
}
simplified too
._ranClass4 {
text-decoration: none;
color: green;
}
Instead of the browser looking at every 'a' node, then checking to make sure the parents match, it just matches if the node has class ._ranClass4
I would avoid what you're doing in your example. Your selectors should not be too wordy, but it's also nice for them to have some level of description so you know what their intended purpose is.
You may want to read into BEM and other CSS methodologies that can help organize and speed up writing your CSS.
You're also probably looking for something like CSSO or another gulp/grunt task. CSSO has a feature you expressly desired, to parse your markup and remove useless selectors from your CSS. Be wary, if you have DOM modifiers in some JS scripts, you might run into issues where CSSO removes these selectors from your CSS because, at the time the task was run, they didn't exist in your markup.
Here is a good article on other methods of CSS optimization.

Why are my pipes fuzzy?

I am creating a sitemap, and for some reason on all browsers the different separation pipes have different fuzziness.
Chrome:
.header a {
color: black;
text-decoration: none;
}
.header li {
display: inline-block;
}
.header li:after {
content: "|";
margin: 5px;
}
<div class="header">
<ul>
<li>Mainpage</li>
<li>Handbook</li>
<li>About</li>
<li>Donate</li>
<li>Forum</li>
</ul>
</div>
Can somebody please help me fix this? It makes so sense.
Chrome and Firefox use different techniques for rendering fonts. That's why they look different (more or less smooth and fuzzy) in each browser. It is then also different on the several operating systems.
If you need it to look consistent every time, you should probably use an image or the CSS border attribute and similar. Another option is CSS text-rendering.
Semantically speaking the pipe | is not the way to go, because it has a different meaning than what you're trying to accomplish (in Unix terms: pipe'ing two commands together, but also has functions in Mathematical terms etc).
You're (mis)using it as a divider, which is a visual (style) element. chrki's solution to use a border would be best:
.header a {
color: black;
text-decoration: none;
}
.header li {
display: inline-block;
border-left: 1px solid black;
margin-left: 5px;
padding-left: 5px;
}
.header li:first-child {
border-left: 0;
margin-left: 0;
padding-left: 0;
}
<div class="header">
<ul>
<li>Mainpage</li>
<li>Handbook</li>
<li>About</li>
<li>Donate</li>
<li>Forum</li>
</ul>
</div>
ps: and I've thrown in a "first-child" to only let the divider appear between elements
ps2: the "Space between inline-block"-problem appears in this solution, an answer to that can be found here: A Space between Inline-Block List Items

Placing images in a row using CSS3 & best practises

Sorry, I'm really new to HTML5 and CSS3 and my searches haven't turned up anything to what I'm sure is a really basic thing. What I'm trying to do is create a row of clickable images / links for my website. Much like how stack overflow has there questions, tags users links above.
So far my css looks like the following:
a#header {
display:block;
margin: 0px auto;
padding: 0px 15px 0px 15px;
border: none;
background: url('img url') no-repeat bottom;
width: 50px;
height: 100px;
}
But this isn't doing what I'm after. It's only placing the image in the centre of the screen. Could someone please help me? Also, is there a best practise for doing something like this?
The margin:0 auto is what is putting it in the center of the screen. You will probably want to drop this, or put it on the container element rather than the individual boxes.
What you probably want for putting several boxes in a line is either float:left or display:inline-block. Either of these will work; they work differently, and there are things you need to know about both of them in order to get the layout working the way you want it, but I'll leave those extra details for you to do further research on.
It's worth noting that none of the code you quoted is specific to HTML5 or CSS3 -- it's all basic HTML/CSS syntax that has been around for a long time.
Since you didn't provide any markup, I'll use the stackoverflow example you cited:
<div class="nav mainnavs ">
<ul>
<li class="youarehere">Questions</li>
<li>Tags</li>
<li>Users</li>
<li>Badges</li>
<li>Unanswered</li>
</ul>
</div>
While you could use your own divs to do this markup, this is the most semantic and concise way of representing a navigation list.
To style this list the way you want, you only need to apply the following styles:
.nav ul {
list-style-type: none;
}
.nav li {
display: block;
float: left;
}
.nav a {
display: block;
padding: 6px 12px;
/* Any other styles to disable text decoration, etc. */
}
Then just position the .nav container where ever you want on the page.
If you're lazy like me, you can put a few <a> tags in a <header> or <nav>, and use display: inline-block.
http://jsbin.com/ivevey/3/edit
HTML
<header>
<a href></a>
<a href></a>
<a href></a>
<a href></a>
<a href></a>
</header>
CSS
header {
text-align: center;
}
header > a { /* assuming a <header> contains your <a> tags */
display: inline-block; /* make sure every image/link is treated like text, ltr */
width: 15px; /* width/height or padding. either works */
height: 15px;
background-color: red; /* This should work for a 15px x 15px image instead */
}
Just be careful of the space between the links. Those are whitespace characters. I generally use header {font-size: 0;} to clear that up.
Ideally, I'd have a structure where there's a <ul> in a <nav>, since it is a list of navigation links, after all.
Maybe something like this?
http://jsfiddle.net/MRayW/6/
<nav>
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
<li>g</li>
</ul>
</nav>
a[id^='header_'] {
border: none;
background: url('xxx.jpg') no-repeat bottom;
width: 50px;
height: 50px;
text-align:center;
color:red;
list-style:none;
float:left;
margin:5px;
}
ul {
padding:0px;
margin:0px;
background-color:#EDEDED;
list-style:none;
background: none repeat scroll 0 0 red;
height: 60px;
margin: auto;
width: 420px;
}
nav {
margin:0 auto
width:500px;
}

What element is preventing my width attribute being applied to my tabs?

I'm completely new to HTML, CSS and Javascript but drawing on previous knowledge of typical programming from Java and C along with numerous tutorials and google searches I've been piecing together a very rough image of how this all works.
Now something that is driving me crazy is I recently added a tabbed content box into my website, one that is on the main page that allows you to select one of 4 different paragraphs by clicking on the appropriate tab. I pulled it off of a tutorial and have a basic understanding of how its working.. but for some reason I cannon get it to let me adjust the width of each of these tabs..
Here is the html for the tabs:
<div id="feature-tabs">
<ul id="tabs">
<li>What We Do</li>
<li>What Makes Us Different</li>
<li>Our Background</li>
<li>Why We Do It</li>
</ul>
</div>`
And here is the associated CSS that styles it.
#feature-tabs {
height: 16px;
width: 150px;
}
ul#tabs {
list-style-type: none;
margin: 0 0 2 0;
}
ul#tabs li {
float: left;
}
ul#tabs li a {
color: #42454a;
background-color: #dedbde;
border: 1px solid #c9c3ba;
border-bottom: none;
text-decoration: none;
width: 150px;
}
ul#tabs li a:hover {
background-color: #f1f0ee;
}
ul#tabs li a.selected {
color: #000;
background-color: #f1f0ee;
font-weight: bold;
}
I need this very much so for the look I'm going for but I simply cannot find out why no matter where I put width: ___px; it just won't apply.
I am wondering if there is something I'm doing which prevents width from being an applicable trait or what have you.
Thanks in advance.
Try adding this style:
ul#tabs li a {
// ..
display: block;
}
DEMO
This happens because a is an inline element by default. Inline elements don't react to height/width.
Does height and width not apply to span?
The Width Propertyw3
Add the following rule to your link :
ul#tabs li a { display: inline-block; }

Weird margin in a list

I'm trying to style a menu, but I keep running into this weird margin that's appearing in both FF4 and IE.
This is the only affecting css:
#header ul
{
display: inline;
}
#header ul li
{
list-style-type: none;
background: #000;
display: inline;
margin: 0;
padding: 0;
}
#header ul li a
{
color: #fff;
text-decoration: none;
display: inline-block;
width: 100px;
text-align: center;
}
And this is the HTML:
<div id="header">
<ul id="toplinks">
<li>Hello</li>
<li>Herp</li>
<li>Derp</li>
</ul>
</div>
As you can see, there's a margin appearing on both sides, and I'd like it so it would have no margin (or maybe 1px would be okay)...
That's no moon...i mean...margin.
What you're seeing is the white space between your elements. Inline-block treats the elements as inline, except they have heights, widths, margins, paddings, etc. What happens is the newline + spacing you've given your html elements for nice indentation is being displayed as a space between the elements.
inline-block is also not cross-browser consistent. I'd suggest using display:block; with floats.
Edit to add suggestion:
If you want nice indents, but want to avoid extra white-space (as in all XML data ever), use what I call the "fishy notation"
Instead of:
<div id="header">
<ul id="toplinks">
<li>Hello</li>
<li>Herp</li>
<li>Derp</li>
</ul>
Use:
<div id="header"
><ul id="toplinks"
><li>Hello</li
><li>Herp</li
><li>Derp</li
></ul
></div>
White space contained by elements is preserved, but white space within elements is not.
Time to whip out that CSS Reset! I first include this, and then start designing. It makes it much easier, as most HTML will look identical cross-browser.
But to fix your problem, I would check if there is a stray border property somewhere. I've had rogue borders before, and they drove me mad. To kill it (for now), try this:
border-style: none;
If we had the complete CSS (don't worry, we don't steal it), I could actually fiddle with it and give you a fully functional answer.
change your CSS to
#header ul
{
display: inline;
}
#header ul li
{
float:left;
background: #000;
margin-left: 1px;;
padding: 0;
}
#header ul li a
{
color: #fff;
text-decoration: none;
display: inline-block;
width: 100px;
text-align: center;
}