4

Wondering if anybody can help with a css problem I'm having.. see this jsbin: http://jsbin.com/uviyat/2/edit

Notice ‘Longer Wording Example’ – how can I get the triangle arrow indicator to scale vertically to dynamically fill the selected blue area height? (The triangle is generated in the last css rule..)

I’m stumped! Anybody got any ideas?

Thanks in advance..

EDIT - since Zoltans's answer, I've had a go with Jquery here: http://jsbin.com/uviyat/12/edit Not sure if its the best way to do it? Where does the value '16' come from?

1
  • The value 16 is the default font size in most browser. If you, for example, set font-size: 20px on your body - you'll have to change your jQuery to 20 as well Commented Aug 16, 2012 at 1:11

3 Answers 3

5

You can't auto stretch the triangle. The simplest way to accomplish what you want is, probably, to define a small subclass for taller menu items - http://jsbin.com/uviyat/3/edit

<li class="selected tall"><a href="#">Longer  Wording Example</a></li>

<style>
.filters .selected.tall:after {
  margin-top: -36px;
  border-width: 20px 0 20px 7px;
}
</style>

...

UPDATE

Alternatively you can use the CSS3 background-size: cover on the :after pseudo-element. But in that case you have to create an image of the triangle and set it as a background. Here is a DEMO

li {
    width: 100px;
    border: 1px solid #eee;
    margin: 3px;
    position: relative;
}

li:after {
    content: ' ';
    display: block;
    position: absolute;
    right: -20px;
    width: 20px;
    top: 0;
    bottom: 0;
    background: url(http://lorempixel.com/20/20) no-repeat;
    background-size: cover;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Cheers Zoltan.. the words in the panel will be generated dynamically by database content so I have no way of knowing for sure which ones will be 'tall'. I'm thinking now the only way would be to use jquery to detect if the <li> dimensions then apply the tall class? Thanks again for help..
@matt_50 updated the answer with another solution, however that requires an image. On the other side there is no JS height detection or similar stuff :)
Thanks for the suggestion, I hadn't though of that :) I think I'll go for JQuery solution - the arrow indicators are not required for the panel to work but just enhance it a little so using JQuery seems to fit ok.. Cheers for your help.
2

http://jsbin.com/hefavo/1/edit

Hey I stumbled upon this question trying to do something similar. Check out my solution. It isn't perfect because you can't change the angle of the arrow (border widths can't be a percentage) which means the arrow will always stick out a certain distance.

For example, if you try a three-line-height thing it will look weird. However, to adjust for that, you can simply set the "margin-left" on the before and after pseudo elements to 15px.

How it works: Each li element has a before pseudo element which is the lower half of the arrow as a css triangle that extends to 500 x 1000. The after pseudo element is the top half. The triangles are then positioned to the right side (not exactly... see below) of the menu item, with the margin-left setting controlling how much it sticks out.

.filters .selected:before {
  position:absolute;
  height: 0;
  top: 50%;
  // transform:scaleY(-1);
  max-width: 300%;
  border-right: 500px solid #3aa5de;
  border-bottom: 1000px solid transparent;
  content: "";
  left: 50%;
  border-radius:0;
  margin-left: 10px;
  transform: scaleX(-1) translateX(100%);
}

.filters .selected:after {
  position:absolute;
  height: 0;
  top: 50%;
  transform:scaleY(-1) scaleX(-1) translateY(100%)     translateX(100%);
  max-width: 300%;
  border-radius:0;
  border-right: 500px solid #3aa5de;
  border-bottom: 1000px solid transparent;
  content: "";
  left: 50%;
  margin-left: 10px;
}

The li element itself is used to mask off the parts of the triangles we don't need. Since the triangles stick out past the previous "100%", I set the li element width to 200%, set the pseudo element positions at 50%, and set the a element (the menu item) to 50% width.

.filters li{
  overflow:hidden;
  width: 200%;
  position:relative;
}
.filters li a{
  width:50%;
  position:relative;
  z-index: 1;
}

edit: Added in relevant bits of css

Comments

2

Now you can use clip-path with polygon and make it really with dynamic height:

clip-path: polygon(0% 0%, 100% 50%, 0% 100%);
background: #3aa5de;

Demo: https://jsbin.com/kikalufoma/2/edit?html,css,output

1 Comment

This is the superior answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.