Same width tabs based on largest content side by side - css

So the conditions that I would like to achieve is
Width of each tab is based on the label
All tabs are the same size as the longest tab (with longest label)
As such the tab group should not be fixed or take up 100% of parent. Should be based on longest tab.
The layout of the tabs are side by side.
This is my progress so far (not same width as largest): https://jsfiddle.net/cyhwx7z0/5/
I have tried this solution but the layout is not side by side. https://jsfiddle.net/alexkwa/L9oy6hbp/1/
HTML
<div class="wrapper">
<ul class="tab-group">
<li class="single-tab">Tab 1</li>
<li class="single-tab">Tab 2</li>
<li class="single-tab">Very Long Tab Name</li>
<li class="single-tab active">Tab 4</li>
<li class="single-tab">Tab 5</li>
</ul>
</div>
SCSS
$active-color: #262933;
$inactive-color: #B3B4B8;
$inactive-font-color: #8B8C8F;
$border-thickness: 1px;
$border-radius: 3px;
body {
background: #fff;
padding: 20px;
font-family: Helvetica;
}
.wrapper {
display: inline-block;
}
.tab-group {
display: flex;
flex-direction: column;
list-style: none;
}
.single-tab {
background-color: #fff;
border: $border-thickness solid $inactive-color;
border-right: 0;
border-sizing: border-box;
color: $inactive-font-color;
cursor: normal;
font-size: 14px;
padding: 9px 21px;
margin: 0;
margin-left: -6px;
user-select: none;
display: flex;
justify-content: center;
flex-direction: column;
text-align: center;
}
.single-tab:first-child {
border-radius: $border-radius 0 0 $border-radius;
}
.single-tab:last-child {
border-radius: 0 $border-radius $border-radius 0;
border-right: $border-thickness solid $inactive-color;
}
.single-tab.active {
background-color: $active-color;
border: $border-thickness solid $active-color;
color: #fff;
}
.single-tab.active + .single-tab {
border-left: 0;
}
.single-tab:last-child.active {
border-left: 0;
}
Any ideas?

Try this
.tab-group {
display: flex; // instead of inline flex
... all other styles
}
.single-tab {
flex: 1; // makes your tabs of same width
... all other styles
}
Here's the working fiddle - https://jsfiddle.net/flexdinesh/xuc6amcu/2/
If you require the parent to not take up the full width, you have to define it manually, say 60%. Example fiddle - https://jsfiddle.net/flexdinesh/xuc6amcu/3/

Related

Align item left, or right if no room left in window

How can you display an item per default in its "normal" position (preferably over any following items), like this:
div {
border: 1px solid black;
}
ul {
display: flex;
padding: 0;
list-style: none;
width: 250px;
border: 1px solid black;
}
li {
display: flex;
position: relative;
}
.item {
padding: 0.4em;
background-color: #f99;
}
.dropdown {
position: absolute;
left: 100%;
z-index: 1;
padding: 0.4em;
opacity: 0.7;
background-color: #2f6f44;
}
<ul>
<li>
<div class="item">First</div>
</li>
<li>
<div class="item">Second</div>
<div class="dropdown">Dropdown</div>
</li>
<li>
<div class="item">Third</div>
</li>
<li>
<div class="item">Fourth</div>
</li>
</ul>
but if the window becomes too small (represented by the ul here), it sticks to the right:
div {
border: 1px solid black;
}
ul {
display: flex;
position: relative;
padding: 0;
list-style: none;
width: 150px;
border: 1px solid black;
}
li {
display: flex;
}
.item {
padding: 0.4em;
background-color: #f99;
}
.dropdown {
position: absolute;
right: 0;
z-index: 1;
padding: 0.4em;
opacity: 0.7;
background-color: #2f6f44;
}
<ul>
<li>
<div class="item">First</div>
</li>
<li>
<div class="item">Second</div>
<div class="dropdown">Dropdown</div>
</li>
<li>
<div class="item">Third</div>
</li>
<li>
<div class="item">Fourth</div>
</li>
</ul>
In other words, if (this.left + this.width > totalWidth) stick right else stay left.
I can either get one or the other behaviour (like above), but not so that it switches seamlessly between the two.
The simplest solution is to compute the element width and the window width and position it using JavaScript, but bugs/edge cases easily slip in, so I'm trying to look for a complete CSS solution.
Any number of containers/wrappers are welcome. One solution I tried looking at was wrapping all the "following" elements (Third and Fourth in the examples above) in a separate li with Dropdown. That way a flex element can take up the space between the previous element (Second) and the edge of the container, but then Dropdown can't go any further left than Second (if the container gets too small).
The elements are dynamic in width based upon changing content.

Give an optimal flexbox width but allow shrink when parent has no more room

I have a wrapper div with flexbox on it, containing two other divs:
The right hand div has 3 other divs in it, one is a search bar
Is there a way I can use flexbox to say fill all the space available, unless the parent is being forced to shrink?
This is my CSS
.header-nav {
background: $storm;
.container {
display: flex;
justify-content: space-between;
}
.logo {
display: block;
}
a {
color: #fff;
text-decoration: none;
}
.is-search {
display: flex;
align-items: center;
background:yellow;
}
}
.header-nav-profile {
display: flex;
}
.block-menu,
.inline-menu {
display: flex;
margin: 0;
padding: 0;
li {
list-style: none;
}
}
.inline-menu {
display: flex;
align-items: center;
a {
padding: 2px 12px 2px 10px;
}
}
.block-menu {
border-left: 1px solid $grey;
border-right: 1px solid $grey;
a {
display:block;
padding: 25px;
box-sizing: border-box;
}
li + li a,
.is-search {
border-left: 1px solid $grey;
}
.is-search {
padding-left: 18px;
padding-right: 18px;
// flex-basis: 280px;
}
}
And HTML
<div class="header-nav">
<div class="container">
<div class="header-nav-profile">
<a href="/">
<img src="http://placehold.it/80x80" alt="Logo" class="logo">
</a>
<ul class="inline-menu">
<li>
Name
</li>
<li class="has-icon">
Add bookmark
</li>
<li>
View bookmark
</li>
</ul>
</div>
<ul class="block-menu">
<li>
Dashboard
</li>
<li>
Period
</li>
<li>
Filters
</li>
<li class="is-search">
<div class="search">
<input type="text" placeholder="Search">
<span class="submit"></span>
</div>
</li>
</ul>
</div>
</div>
I have a link to a demo if you want to try it out:
https://codepen.io/EightArmsHQ/pen/dmZxRv?editors=1100
I'd like the search bar to have a good length (longer than the other two items in its div) then as the width gets smaller only then does it start shrinking.
Modify your block menu class like this:
.block-menu {
border-left: 1px solid grey;
border-right: 1px solid grey;
flex-grow:1;
justify-content:flex-end
}
Basically you can use flex-grow to take up the available space and then justify-content:flex-end to move them to the right (end of) the container.
Here is a codepen
Try using max-width: pixel amount; and max-height: pixel amount;.
It that doesn’t work, it’s possible with #media tags.
.selector {
width: normal width;
}
#media (max-width: 800px) {
.selector {
width: percent amount; /* Width when window is thinner than 800px */
}
}

Enable navigation list items to have a height of 100% of the parent flex container

I am trying to figure out how to force my <li> items within my flexbox navigation bar to take up 100% of the height of the header.
The goal is to have an active class to display a blue bar when the user hovers over the item. I have mocked up my simple example here: https://codepen.io/anon/pen/jZzeqL
I have tried to mess with the align-items, but everything I do seems to break the center horizontal alignment.
/* header styles */
.header {
grid-area: header;
background-color: #444;
color: #fff;
align-items: center;
display: flex;
margin: 0 2em;
}
#logo {
font-weight: 300;
font-size: 160%;
}
#logo, nav {
flex: 1;
}
nav ul {
display: flex;
list-style: none;
justify-content: flex-end;
font-size: 110%;
}
nav li {
font-size: 14px;
padding: 0px 10px;
}
nav li span.active {
border-bottom: 3px solid #00A2D3;
}
nav li > .username {
font-weight: 400;
padding-right: 3px;
}
<header class="header">
<div id="logo">Dashboard</div>
<nav>
<ul role=navigation>
<li><span class="far-li"><i class="far fa-bell"></i></span></li>
<li><span class="fas-li"><i class="fas fa-cog"></i></span></li>
<li><span class="username active">test-email#gmail.com</span><span class="fas-li"><i class="fas fa-caret-down"></i></span></li>
</ul>
</nav>
</header>

I want to reposition a image that is within a div tag without moving the entire div tag

I am making a horizontal navigation bar with a image in it, the nav bar has four links in total one of which is a image link, however the image link doesn't line up with the rest of the links on the nav bar i want to drop it down by a pixel or 2, but every time i try and reposition that image it brings the rest of the links in the div tag with it.
{ position: absolute; } and { position: relative; } puts the image link on top of the other links
http://i.imgur.com/v7Cg9kJ.jpg how it looks normally.
http://i.imgur.com/abaIdwE.jpg with absolute positioning.
Try the following:
li {
display: inline-block;
margin: 0 5px 0 0;
}
#apps {
vertical-align: middle;
}
DEMO
SNIPPET
#top-navbar {
float: right;
display: block;
padding: 10px;
word-spacing: 5px;
text-align: center;
font-family: Arial;
font-size: 13pt;
position: relative;
}
#signin {
background-color: #4387FD;
color: white;
width: 120px;
text-align: center;
padding: 5px;
text-decoration: none;
word-spacing: 1px;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
li {
display: inline-block;
margin: 0 5px 0 0;
}
#apps {
vertical-align: middle;
}
a {
text-decoration: none;
}
<div id="top-navbar">
<ul>
<li>Gmail</li>
<li>Images</li>
<li>
<a href="https://www.google.com/intl/en/options/">
<img id="apps" src="https://lh3.ggpht.com/ExOY2XlSbdfFFE3BZ5l44wBQEU5JVsVrertIIdjPy93yfDfomhKx0waLXA9Hhv5qvg-b3aaq=w22" />
</a>
</li>
<li>
<a id="signin" href="https://accounts.google.com/ServiceLogin?hl=en&passive=true&continue=https://www.google.com/webhp%3Fhl%3Den">Sign In</a>
</li>
</ul>
</div>

Re-alignment of panels CSS

I have 4 panels in my page. At a time (depending on certain conditions) either 1,2,3 or all 4 panels are displayed. I want the panels to re-align themselves so that there is no empty space for the panels which are not present.
How can I do this?
EDIT: If all panels are visible then it will look like this :
http://ibin.co/1zrkoFfExnRZ
If suppose Pannel 3 is hidden it will look like this :
http://ibin.co/1zrkcO4vTjHW
.container {
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row;
justify-content: space-around;
padding: 0;
margin: 0;
list-style: none;
}
.rowitem {
background: #ff0000;
padding: 2px;
width: 50%;
height: 50px;
margin-top: 6px;
line-height: 50px;
text-align: center;
font-weight: bold;
border: 1px solid #fff;
}
<ul class="container">
<li class="rowitem">01</li>
<li class="rowitem">02</li>
<li class="rowitem">03</li>
<li class="rowitem">04</li>
</ul>

Resources