This is what is wrong with that approach
<li><a href="/experts/">Expert<br>Advice</a></li>
Just add that line in your code and see what happens.
Now do the same with my example:
<a href="/experts/">Expert<br>Advice</a>
This is what is wrong with that approach
<li><a href="/experts/">Expert<br>Advice</a></li>
Just add that line in your code and see what happens.
Now do the same with my example:
<a href="/experts/">Expert<br>Advice</a>
I knew there would be something
With my example, changing the anchors to display: inline-block;
, width: 100%;
and height: 100%;
enables them to fill the list element, which looks a bit better, but the text is aligned to the top rather than nicely in the middle.
That still wonât work as you canât base 100% height on a table-cell. It works in chrome (when it shouldnât) but wonât work in Firefox or IE.
There is a fix and you would need to set the display:table element to height:1px and then set the list item display:table-cell to height:100% and then you will get the full height in IE and Firefox as well.
Of course you lose the vertical alignment and to achieve that you would need to nest another element inside the anchor and set that to display:table-cell and the anchor to display;table.
Which is why I prefer my minimalist version
It is 2015, why isnât CSS more flexible and intuitive? So people donât have to do dirty tricks?
CSS is now more flexible and intuitive than it has ever been - provided that you ignore old browsers. It is because people insist on using antiquated browsers that are six or more years old (two or three lifetimes ago in web terms) that there are these issues.
I agree, especially with flexbox, but its still not great. Say I want a child element to scale according to a parent element, why canât isnât this kind of flexibility available?:
.childElement1 {
width: 60%h; /* 60% of the height of the parent element*/
height: 20%w + 30px; /* 20% of the width plus 30 pixels */
}
And why canât I tell an element to just fill itâs parent?
Just a couple of simple examples.
Canât calc() do some of those things?
This seems to do the job using an unordered list in the nav. It is almost the same as before but has a little bit of javascript to do what css canât. I think it is ok considering CSS canât do it and if javascript is off, the menu is still perfectly usable, but just looks a little odd.
PaulOBâs example is more elegant but if you think an unordered list should be used with anchors in a nav block, then this should be of help. (Only tested in Chrome and Firefox, but uses simple code).
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
.bigBox{
border:1px solid red;
padding:10px;
}
.nav ul {
display:table;
border-collapse:collapse;
width:75%;
margin:auto;
}
.nav li {
position: relative;
display: table-cell;
vertical-align: middle;
text-align:center;
border:1px solid #666;
padding: 0;
margin:0;
background-color: green;
}
.nav a {
background:red;
display: block;
color:#fff;
padding-top: 5px;
padding-bottom: 5px;
padding-left: 2px;
padding-right: 2px;
text-decoration:none;
vertical-align: middle;
margin: 0;
}
.nav a:hover{background:blue}
@media screen and (max-width:500px){
.nav li{display:block;}
}
</style>
</head>
<body>
<div class="bigBox">
<nav class="nav">
<ul>
<li><a href="/index.html"><span>Home</span></a></li>
<li><a href="/features/">Features</a></li>
<li><a href="/experts/">Experts</a></li>
<li><a href="/quiz/">Quiz</a></li>
<li><a href="/projects/">Projects</a></li>
<li><a href="/horoscopes/">Horoscopes bla bla bla</a></li>
</ul>
</nav>
</div>
<script>
var navAnchors = document.getElementsByTagName("nav")[0].getElementsByTagName("a");
var startPad = []; // store original values
// grows anchor hight to fit a tables cell height
function growAnchors() {
// restore original values if they have been established
for (var i=0, il=navAnchors.length; i<il; i+=1) {
if (!!startPad[i]) {
navAnchors[i].style.paddingTop = startPad[i][0];
navAnchors[i].style.paddingBottom = startPad[i][1];
}
}
// determine optimal padding
var rowHeight = navAnchors[0].parentNode.clientHeight;
for (var i=0, il=navAnchors.length; i<il; i+=1) {
var navAnchor = navAnchors[i];
var pad = 0;
// make sure we establish original padding
if (!startPad[i]) {
navAnchor.style.paddingTop = pad + "px";
navAnchor.style.paddingBottom = pad + "px";
}
// work out optimal padding
while (rowHeight > navAnchor.clientHeight && pad < 500) {
pad += 1;
navAnchor.style.paddingTop = pad + "px";
// cater for an odd height
if (rowHeight > navAnchor.clientHeight) {
navAnchor.style.paddingBottom = pad + "px";
}
}
// record original optimal padding
if (!startPad[i]) {
startPad[i] = [navAnchor.style.paddingTop, navAnchor.style.paddingBottom];
}
}
}
growAnchors();
window.onresize = function() {
growAnchors();
}
</script>
</body>
</html>
As far as I am aware, you canât use calc() to choose to use a percentage of the height or width, but you can add 30px for example.
IMO you should be able to scale something as a percentage of:
Yes you can use calc() with percentages.
e.g.
width: calc(100% - 3em);
You can use it for height also but the height must be based on a parent that has height defined and not auto or content height. If the parent has a percentage height then that parentâs parent must also have a height defined and so on all the way back up the tree.
Yes thatâs always possible.
Thatâs only possible when you follow the rules I set out in the first reply to calc().
Height is one of the most misunderstood properties and I have been giving this answer since about 2002 as everybody always asks the question at some stage.
If you give an element a height then that element is fixed in height. Itâs content can never grow beyond the height you set.
So imagine that height worked as you expected and you give a child 100% height (even though its parents height is not defined). You now have a circular reference (which CSS hates) as the height of the inner element is dependent on the height of the parent which will only have a height once the inner element is in place and holds content. The effect would be that your childâs height would be zero because the parents height is zero until you place content inside. Itâs a circular reference that canât be resolved for that case. It makes no sense anyway as there would be no need for the height unless you were trying to match the height of some other unrelated element.
Now if your parent has a height of 500px (height:500px) and you set the child to height:100% (which will work) then whatever content you put inside the child must fit inside that height:100% which will always be 500px. Thatâs fine until you enlarge the text or add more content.
There are other examples where having height defined is bad for the layout.
What most people mean when they want height:100% to work is that they want to match the height of perhaps of one column to another and assume that they can do this by basing the elements height on the height of the parent that holds both columns. In this case height:100% would be useful and indeed if you place an absolute element into that context it can keep track with a relatively positioned parents height (although it would be no good for adding content.)
For equal columns there are many tricks but the best way is the display:table/table-cell approach although that comes with a few caveats when trying to style or position.
Height when use in tables (and display:table etc) or table-cells is treated as a minimum which means that it can always grow should content require it and the reason that cells can base their height on the tables height (otherwise tables wouldnât work).
All in all height is quite a complicated subject but I agree there are times when it would be useful to simply specify 100% and make the element fill the available space. The reason this is not available is because of the circular references needed to make this work and because most likely it would harm more than it cures.
Flexbox addresses most of this problems but in my mind adds to much complexity to the problem. Most times I try to use flexbox to do something I come back to display:table because it does what I want in a more robust way.
We have vh units now which will do this although again this throws up more queries. Iâve seen this a hundred times now and someone has an element half way down the page and they give it 100% height (or 100vh) and expect the element to reach the bottom of the viewport when in reality what they really want is for the element to stretch from where it is until it reaches the bottom. What they end up with is an element that goes 100% from where it is which means it finished way below the fold.
It would be nice for height to act in different ways but when you look at the specifics there isnât really one way for the same property to do it all. It could be better but understanding how it works does help us to do the things we want even if sometimes itâs not as easy as it should be.
Nice answer.
I canât shake the feeling that CSS could be made more flexible and intuitive though. Iâm tempted to have a go by using JavaScript to process some CSS based markup to size and position elements in a similar way to described above, just to see if it can be done. I donât have time though
Hi Paul,
That hover/click area can fill the anchor by giving it an overflowing padding that is then clipped by its parent, the list-item. E.g. your code:
[code]
Untitled Document .bigBox{ border:1px solid red; padding:10px; } .nav{ display:table; border-collapse:collapse; width:75%; margin:auto; } .nav li{ display:table-cell; border:1px solid #666; overflow:hidden; vertical-align:middle; text-align:center; } .nav a{ display:block; margin:-100px; padding:105px 102px; background:red; color:#fff; text-decoration:none; } .nav a:hover{background:blue} @media screen and (max-width:500px){ .nav li{display:block;} } [/code] Finally made it back, sort of. :)Erik, is that really you? I thought something catastrophic had happened to you. Welcome back indeed:)
Yes I often forget about the excessive padding negative margin trick due to itâs problem with fragment identifiers but that wonât be an issue in this case so your demo will work well
This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.