HTML CSS Hamburger Dynamic Columns - html

I have written a Knockout binding for a MegaMenu which has a hamburger component
The hamburger contains a bunch of Categories and items within these Categories
The Categories act as a header and are bolded. They then display their items underneath indented slightly
Categories and Items are just strings retrieved from a database
The rules of the hamburger are as follows:-
Don't split a Category across columns
Use 3 columns first before scrolling. i.e Don't fill only two columns and have a scroll bar (vertical)
Even up the columns as much as possible
3 columns max
The hamburger has a max height restriction
Categories are to be ordered alphabetically -
An example of the ordering is a follows:-
Assume I have the following Categories (ignore the items within them as it is the categories that are ordered)
Dogs, Cars, Cats, Beds, Furniture, Hobbies, Homes, Gyms, Horses
and if these were split across 3 columns they would be rendered as follows
Col 1 Col 2 Col 3
----- ----- -----
Beds Dogs Hobbies
Cars Furniture Homes
Cats Gyms Horses
I am able to construct html lists as follows:-
<div>
<ul>
<li>Beds
<ul>
<li>Item 1</li>
<li>Item 2
</ul>
</li>
<li>Cars
<ul>
<li>Item 1</li>
</ul>
</li>
<li>Cats
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</li>
<li>Dogs
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</li>
</ul>
</div>
Can I use pure css to adjust it in the hamburger columns according to my rules?
That way I can avoid the messy looping etc that I am currently doing in my html

Your best bet is to use column layout with break-inside: avoid
From: https://css-tricks.com/almanac/properties/b/break-inside/
Fortunately, you can tell the browser to keep specific elements
together with break-inside.
-webkit-column-break-inside: avoid; /* Chrome, Safari, Opera */
page-break-inside: avoid; /* Firefox */
break-inside: avoid; /* IE 10+ */
I've made an example here
http://codepen.io/HerrSerker/pen/obgddJ
.outer {
-moz-columns: 3;
-webkit-columns: 3;
columns: 3;
display: block;
}
.outer > li {
display: block;
padding-top: 30px;
-webkit-column-break-inside: avoid;
/* Chrome, Safari, Opera */
page-break-inside: avoid;
/* Firefox */
break-inside: avoid;
/* IE 10+ */
}
.outer > li > span {
text-decoration: underline;
}
.inner {
width: 200px;
display: block;
text-decoration: none;
}
.inner > li {
display: block;
padding-left: 10px;
padding-top: 3px;
}
.wrapper {
width: 600px;
margin: 0 auto;
max-height: 400px;
overflow-y: auto;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
<div class="wrapper"><ul class="outer">
<li><span>Lorem ipsum dolor.</span>
<ul class="inner">
<li>Fuga, ratione blanditiis commodi.</li>
<li>Obcaecati dicta ut, pariatur!</li>
<li>Earum, illum sapiente enim.</li>
</ul>
</li>
<li><span>Vel, ratione cum!</span>
<ul class="inner">
<li>Lorem ipsum dolor sit.</li>
<li>Accusamus, odio ipsum nemo!</li>
<li>Molestiae unde natus odio.</li>
<li>Lorem ipsum dolor sit.</li>
<li>Corporis, tempora nisi minus.</li>
</ul>
</li>
<li><span>Aliquid, tenetur, similique.</span>
<ul class="inner">
<li>Lorem ipsum dolor sit.</li>
<li>Repellendus repellat placeat odit!</li>
</ul>
</li>
<li><span>Quibusdam, necessitatibus aliquid.</span>
<ul class="inner">
<li>Lorem ipsum dolor sit.</li>
<li>At nisi, quas veritatis!</li>
<li>Perferendis laudantium nesciunt dolor!</li>
<li>Distinctio quidem veniam impedit!</li>
</ul>
</li>
<li><span>Sed, quam, beatae.</span>
<ul class="inner">
<li>Lorem ipsum dolor sit.</li>
<li>Voluptates temporibus provident dolores.</li>
<li>Explicabo non minus ullam!</li>
<li>Tenetur, molestias, debitis. Voluptatum.</li>
<li>Quibusdam incidunt unde, laboriosam!</li>
<li>Fugiat perferendis eligendi, dignissimos.</li>
</ul>
</li>
<li><span>Lorem ipsum.</span>
<ul class="inner">
<li>Lorem ipsum dolor sit.</li>
<li>Perspiciatis, a dolore officia!</li>
</ul>
</li>
<li><span>Voluptatum, ipsum?</span>
<ul class="inner">
<li>Lorem ipsum dolor sit.</li>
<li>Odit, aliquam voluptates alias!</li>
</ul>
</li>
<li><span>Dolorem, quos!</span>
<ul class="inner">
<li>Lorem ipsum dolor sit.</li>
<li>Quae quos quas, fugit?</li>
</ul>
</li>
<li><span>Cum, excepturi.</span>
<ul class="inner">
<li>Lorem ipsum dolor sit.</li>
<li>Libero distinctio, necessitatibus laborum!</li>
</ul>
</li>
<li><span>Blanditiis, harum.</span>
<ul class="inner">
<li>Lorem ipsum dolor sit.</li>
<li>Corporis fuga accusamus, ab?</li>
</ul>
</li>
</ul>
</div>
Is this compatible? See here: http://caniuse.com/#feat=css-grid
As for the sorting: you cannot do this with CSS You have to do it in HTML or with JS

Can I use pure css to adjust it in the hamburger columns according to my rules?
No, CSS cannot perform the required even-distribution arithmetics. You're stuck with pre-formatting in HTML in this case.

You can set the value display:table to your parent div , and then set display:table-cell to your children items.That's not going to break your columns.

I think I can achieve what you want using css column:
ul{
...
column-gap: 2em;
-webkit-column-count: 3;
-moz-column-count: 3;
column-count: 3;
}
Demo: http://jsfiddle.net/pg2xy9h2/3/
I don't understand how it is possible to have Even up the columns as much as possible and a dynamic number of columns. Even up is a division calculation, how can you perform a division if the divisor is unknown?

Related

How to flip the display order of one of the elements individually using flex

I am learning CSS screen layout, and I want to use flex to change the display order of an element. I
have found some tutorials on the Internet and still don't know how to write it, so I can simply change the second , change the display order from left to right?
ul{
display: flex;
flex-direction:column;
width: 300px;
}
<ul>
<li>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Maiores doloribus dolor ipsum odit beatae voluptates culpa. Doloremque veniam labore pariatur!</p>
</li>
<li>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Maiores doloribus dolor ipsum odit beatae voluptates culpa. Doloremque veniam labore pariatur!</p>
</li>
<li>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Maiores doloribus dolor ipsum odit beatae voluptates culpa. Doloremque veniam labore pariatur!</p>
</li>
</ul>
if you looking for something like that
.flexed {
width: 400px;
height: 400px;
border: 1px solid #c3c3c3;
display: flex;
align-items: flex-start;
justify-content: center;
height: 50px;
}
.flexed div {
width: 50px;
height: 50px;
}
.reversed{
flex-direction: row-reverse;
}
<div style="text-align:center"> <h4>Without riversed row</h4> </div>
<div class="flexed" >
<div style="background-color:red;">1</div>
<div style="background-color:pink;">2</div>
<div style="background-color:orange;">3</div>
<div style="background-color:lightblue;">4</div>
</div>
<div style="text-align:center"> <h4>With riversed row</h4> </div>
<div class="flexed reversed" >
<div style="background-color:red;">1</div>
<div style="background-color:pink;">2</div>
<div style="background-color:orange;">3</div>
<div style="background-color:lightblue;">4</div>
</div>
<div style="text-align:center"> <h4>With 2 only riversed row</h4> </div>
<div class="flexed " >
<div style="background-color:red;">1</div>
<div class="flexed reversed">
<div style="background-color:pink;">2</div>
<div style="background-color:orange;">3</div>
</div>
<div style="background-color:lightblue;">4</div>
</div>
The actual letters right to left is easily accomplished with the <bdo> element. Just wrap the text in a <bdo> and add the dir attribute and the value of "rtl".
<bdo dir='rtl'>Text to reverse</bdo>
The text is changed from Latin to English to clearly demonstrate the reversed text.
ul{
display: flex;
flex-direction:column;
width: 300px;
}
<ul>
<li>
<p>Did you know that more frozen bananas are sold right here on this boardwalk than anywhere in the OC? You burn down the storage unit? Oh, most definitely. What a fun, sexy time for you.</p>
</li>
<li>
<p><bdo dir='rtl'>Did you know that more frozen bananas are sold right here on this boardwalk than anywhere in the OC? You burn down the storage unit? Oh, most definitely. What a fun, sexy time for you.</bdo></p>
</li>
<li>
<p>Did you know that more frozen bananas are sold right here on this boardwalk than anywhere in the OC? You burn down the storage unit? Oh, most definitely. What a fun, sexy time for you.</p>
</li>
</ul>

I want to place 3 divs next to each other with a background color

I want to place 3 different divs next to each other with a background color.
I tried floating everything to the left and it works but the background color disappears. If I don't float them, they are lined up under each other but the background color is there.
.wrapper {
width: 1222px;
margin: auto;
}
.footer {
background-color: #6d757c;
}
footer .footercategory {
float:left;
}
.footercategory li {
color: black;
font-family: NewsGothicBTWebCondRegular, "Trebuchet MS", Arial, sans-serif;
font-size: 1.3em;
padding: 0 10px 0 10px;
}
<footer class="footer">
<section class="wrapper">
<div class="footercategory">
<div>
<h1>Payment</h1>
<ul>
<li>
<span>Lastschrift</span>
</li>
<li>
<span>Lastschrift</span>
</li>
<li>
<span>Lastschrift</span>
</li>
</ul>
</div>
</div>
<!-- ROW 2 -->
<div class="footercategory">
<div>
<h1>Unsere Zahlarten</h1>
<ul>
<li>
<span>Lastschrift</span>
</li>
<li>
<span>Lastschrift</span>
</li>
<li>
<span>Lastschrift</span>
</li>
</ul>
</div>
</div>
<!-- ROW 3 -->
<div class="footercategory">
<div>
<h1>Unsere Zahlarten</h1>
<ul>
<li>
<span>Lastschrift</span>
</li>
<li>
<span>Lastschrift</span>
</li>
<li>
<span>Lastschrift</span>
</li>
</ul>
</div>
</div>
</section>
</footer>
If I float all left they are next to eachother but with no background
This can be done easily with the use of flex. Making your .wrapper class use flexbox will align the child elements next to each other. For the background colour, if you're wanting the background to remain consistent across all 3 columns, then set background-color on the footer element. Else, if you wish the background colours to differ, set each one separately on each .footercategory class.
.footer {
background-color:#6d757c;
}
.wrapper {
display:flex;
}
.footercategory {
flex:1;
}
<footer class="footer">
<section class="wrapper">
<div class="footercategory">
<div>
<h1>Payment</h1>
<ul>
<li>
<span>Lastschrift</span>
</li>
<li>
<span>Lastschrift</span>
</li>
<li>
<span>Lastschrift</span>
</li>
</ul>
</div>
</div>
<!-- ROW 2 -->
<div class="footercategory">
<div>
<h1>Unsere Zahlarten</h1>
<ul>
<li>
<span>Lastschrift</span>
</li>
<li>
<span>Lastschrift</span>
</li>
<li>
<span>Lastschrift</span>
</li>
</ul>
</div>
</div>
<!-- ROW 3 -->
<div class="footercategory">
<div>
<h1>Unsere Zahlarten</h1>
<ul>
<li>
<span>Lastschrift</span>
</li>
<li>
<span>Lastschrift</span>
</li>
<li>
<span>Lastschrift</span>
</li>
</ul>
</div>
</div>
</section>
</footer>
This is how I would flex three div's side-by-side, I have also added in some responsiveness just so you get an idea of how you can manipulate the boxes at different size screens.
.section {
width: 100%;
margin: 0 auto;
}
.section .section-inner {
width: 100%;
max-width: 1248px;
margin: 0 auto; /* centers container */
padding: 10px; /* this combined with the margin in the divs will make the margins appear consistent */
box-sizing: border-box;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
flex-direction: row; /* sort into rows */
align-items: center;
justify-content: space-between;
text-align: center;
background-color: rgba(255,100,100,0.25);
}
.section .section-inner div {
width: calc((100% / 3) - 20px); /* calculate width for maximum accuracy | minus margin */
margin: 10px; /* space between boxes */
padding: 20px; /* space inside boxes */
box-sizing: border-box; /* calculates border and padding in width */
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
flex-direction: column; /* sort into columns */
align-items: center;
justify-content: center;
flex-grow: 1; /* forces singular div that falls beneath to be full width */
background-color: rgba(0,0,0,0.25);
}
#media screen and (min-width: 640px) and (max-width: 1023px) {
.section .section-inner div {
width: calc((100% / 2) - 20px); /* calculate width for maximum accuracy | minus margin */
}
}
#media screen and (max-width: 639px) {
.section .section-inner div {
width: 100%; /* calculate width for maximum accuracy | minus margin */
}
}
.section .section-inner div h1 {
margin-bottom: 20px;
}
<section class="section">
<div class="section-inner">
<div>
<h1>Lorem ipsum </h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Omnis nemo quas dolor optio autem! Veniam, dolore neque nam harum quae excepturi distinctio optio explicabo ipsum laudantium nesciunt et autem a.</p>
</div>
<div>
<h1>Lorem ipsum</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Omnis nemo quas dolor optio autem! Veniam, dolore neque nam harum quae excepturi distinctio optio explicabo ipsum laudantium nesciunt et autem a.</p>
</div>
<div>
<h1>Lorem ipsum </h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Omnis nemo quas dolor optio autem! Veniam, dolore neque nam harum quae excepturi distinctio optio explicabo ipsum laudantium nesciunt et autem a.</p>
</div>
</div>
</section>
Modify style as -
.footer {
background-color: #6d757c;
height: auto;
float: left;
}
This will apply same color across the footer.
Add background-color that you want to add to the <section class="wrapper"></section> tag and give a width of 100%.
then If you use bootstrap give class md-col-4 for each divs.
If you don't use bootstrap give the width manually like width: 33% and display: inline-block to each divs

Responsive Block Element in CSS Grid must be position: fixed

I'm trying to build a UI which has the section be display:grid with a grid-template-columns: 1fr 3fr.
Then I have 2 block elements that should be placed in those columns (I used grid-column: 1/2 and grid-column: 2/3), respectively.
Now, my issue is that I wanted the block on the left (in the 1fr cell/area) to have a fixed-position. It's supposed to be a persistent navigation sidebar. However, when I used position: fixed, the block is removed entirely from the grid and so responsiveness doesn't really factor in anymore.
I tried nesting a container inside the main grid-item and giving that one the fixed-position, but when I adjusted my viewport to test, the fixed-container just overflowed/overlapped onto the 3fr block.
Any ideas on who to pull this off?
Thanks!
If you want the element to remain a grid item, then the answer is "you can't".
Once an element has position: absolute or position: fixed (which is a form of absolute positioning, with reference to the viewport), it takes on new characteristics:
the element is removed from the document flow
the element is removed from the grid formatting context
the element is no longer a grid item
So a grid item doesn't work well with fixed positioning.
However, you won't have a problem applying position: fixed to a grid container.
Consider managing your #left and #right elements separately. #left can be a fixed-position grid container. #right can be another grid container and remain in-flow.
Percentage padding / margin on grid item ignored in Firefox
Why doesn't percentage padding / margin work on flex items in Firefox and Edge?
Perhaps position:sticky instead.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
::before,
::after {
box-sizing: inherit;
}
.grid {
display: grid;
grid-template-columns: 1fr 3fr;
grid-gap: .5em;
}
aside {
padding: 0 .5em;
background: lightblue;
}
main {
grid-column: 2;
height: 500vh;
background: lightgreen;
}
aside div {
position: sticky;
top: 0;
}
<div class="grid">
<aside>
<div>
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
<li>item 8</li>
<li>item 9</li>
<li>item 10</li>
</ul>
</div>
</aside>
<main>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Velit provident, voluptatem, dolor eligendi quos harum reiciendis accusantium sapiente optio ad suscipit ullam, quibusdam aut ipsam laboriosam itaque eius officiis. Sapiente molestias vero aut
deleniti vitae cupiditate praesentium necessitatibus delectus, incidunt, cumque porro molestiae ipsa quas eveniet quisquam quod ipsam? Earum.</main>
</div>
The page still scrolls but the div in the sidebar remains "stuck" to the top
Hello i had this problem too, and the solution i came up with and it's working :)
just wrap the div that you want with a grid layout with another div lets call it parent, the parent div will be the grid element and the div inside will be with the position fixed!
.parent{
// This div will be from the grid children
}
.child {
position:fixed;
}

Trying to break up list items dynamically

I'm trying to fill an unordered vertical list that continues on the next line every time the list reaches the length limit. But instead of simply displaying the next list item on the next line I want the list item to break and continue like this:
I don't want to do this with columns, rather that it breaks dynamically.
Maybe something like this to make the list horizontal and to create your own custom list-style-type?
Code:
<style>
ul {
list-style-type: none;
text-align: center;
width: 450px;
}
li {
display: inline;
}
li:before {
content: "\2022";
margin-right: 2px;
}
</style>
<ul>
<li>Lorom Ipsum Dolor Sit Amet Lorem Ipsum</li>
<li>Lorom Ipsum Dolor Sit Amet Lorem Ipsum</li>
<li>Lorom Ipsum Dolor Sit Amet Lorem Ipsum</li>
<li>Lorom Ipsum Dolor Sit Amet Lorem Ipsum</li>
<li>Lorom Ipsum Dolor Sit Amet Lorem Ipsum</li>
<li>Lorom Ipsum Dolor Sit Amet Lorem Ipsum</li>
<li>Lorom Ipsum Dolor Sit Amet Lorem Ipsum</li>
<li>Lorom Ipsum Dolor Sit Amet Lorem Ipsum</li>
</ul>
How about giving your <ul> a set max-width, then give your <li> display: inline; so they aren't block elements anymore and wrap like you want. However list-style-type will not work on the li's anymore because they are inline elements. You can still get your red bullet points working with background images, looks like you might be already doing this.
ul {
max-width: 220px;
list-style-type: disc;
}
ul li {
display: inline;
}
<ul>
<li>Hey there this is a pretty long sentence</li>
<li>Hey there this is a pretty long sentence</li>
<li>Hey there this is a pretty long sentence</li>
<li>Hey there this is a pretty long sentence</li>
</ul>
You can use css to change the way of items are listed.
Ex:
ul {
width: 250px;
display: inline-block;
}
li {
float: left;
margin-left: 20px;
}
<html>
<body>
<ul>
<li>item 1</li>
<li>item 1 item 2</li>
<li>item 1 item 2 item 3</li>
<li>item n</li>
</ul>
</body>
</html>

Different line height for continuing row of list

I have a list and I want line items with long text to flow to the second row which would have a shorter line height than the line height between regular line items. For example:
<ul style="list-style:none">
<li>
Hotel Chain
</li>
<li>
Taxi Service
</li>
<li>
Tourist Trap & Retail Plaza
</li>
<li>
Travel Company
</li>
<li>
Local Olive Oil Company
</li>
</ul>
So hopefully that makes it clear what I'm wanting. Thanks for helping!
{EDIT}
I changed the code above.
The design is responsive, so when the screen shrinks the list width shrinks and some lines that took up one line then takes up two lines. I want those with two lines to have a shorter line height.
It's not clear what effect you are trying to achieve but there is a pseudo-element of ::first-line which might be what you are after
ul {
width: 200px;
}
li {
margin-bottom:1rem;
line-height: 1;
}
li::first-line {
line-height: 2;
}
<ul>
<li>lorem</li>
<li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam soluta ex ipsam dignissimos, provident assumenda!</li>
<li>lorem</li>
<li>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quibusdam, magni!</li>
<li>Lorem ipsum dolor sit.</li>
</ul>
::first-line # MDN
You can do that natively this paragraphs.
<p>First line item</p>
<p>Second line item</p>
<p>This is the third line item that will<br>wrap on a new line but have a<br>smallerline-height than others</p>
<p>Fourth line item</p>
<p>This fifth line item is the same as<br>the third in that its line-height<br>is different because it has multiple lines</p>
<p>And the sixth line is the same with<br>a smaller line-height</p>
No need to css, or you can specify a width to your paragraphs if you don't want do write the BRs.
http://jsfiddle.net/8q6wgw2x/