Image is overlapping content after resizing - javascript

I tried to create JS function that resize image by clicking on it. It works but I have problem with overlapping content. After I click on image it will resize and overlap content above and under my image I tried to set width, height, position(absolute) but nothing works. I want to push the content away from image.
let img = document.getElementById("changeImg");
// Function to increase image size
function scaleupImg() {
// Set image size to 2 times original
img.style.transform = "scale(2)";
// Animation effect
img.style.transition = "transform 0.25s ease";
}
#changeImg {
width: 50%;
height: 50%;
padding: 10px;
margin: 10px;
}
.cool-icon-box {
width: 100%;
height: 1000%;
padding: 10px;
margin: 10px;
}
<section>
<h2>HEADING</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra cursus ex, eget auctor lectus volutpat sed. Maecenas vel ornare arcu.</p>
<div class="cool-icon-box">
<img id="changeImg" src="https://3.bp.blogspot.com/-7x5c_f1yzsQ/XHv9FZKHrEI/AAAAAAAADrE/4iGl9Lm6K2odX4SdWbU_RN6gZesx4IaGACEwYBhgL/s1600/html.jpg" alt="" onclick="scaleupImg()">
</div>
</section>
<section>
<h2>HEADING</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra cursus ex, eget auctor lectus volutpat sed. Maecenas vel ornare arcu.</p>
</section>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>

The css scale() function will always overlay neighboring elements. Try this..
let img = document.getElementById("changeImg");
// Function to increase image size
function scaleupImg() {
// Set image size to 2 times original
img.style = "height:100%;width:100%";
// Animation effect
img.style.transition = "transform 0.25s ease";
}

Set transition on the image element in the CSS with width as the property to transition. In your code, remove the setting of the transition. When clicking on the image, all you need to do is apply img.style.width = "100%".
The problem with using scale is it scales the image in place, thus, it can overlap other elements.
let img = document.getElementById("changeImg");
// Function to increase image size
function scaleupImg() {
// Set image size to 2 times original
img.style.width = "100%";
}
#changeImg {
width: 50%;
height: 50%;
padding: 10px;
margin: 10px;
transition:width 0.25s ease;
}
.cool-icon-box {
width: 100%;
height: 1000%;
padding: 10px;
margin: 10px;
}
<section>
<h2>HEADING</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra cursus ex, eget auctor lectus volutpat sed. Maecenas vel ornare arcu.</p>
<div class="cool-icon-box">
<img id="changeImg" src="https://3.bp.blogspot.com/-7x5c_f1yzsQ/XHv9FZKHrEI/AAAAAAAADrE/4iGl9Lm6K2odX4SdWbU_RN6gZesx4IaGACEwYBhgL/s1600/html.jpg" alt="" onclick="scaleupImg()">
</div>
</section>
<section>
<h2>HEADING</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra cursus ex, eget auctor lectus volutpat sed. Maecenas vel ornare arcu.</p>
</section>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>

That is, because positioning by position: relative and changes to the element by the transform-property are only applied after the element has been inserted into the DOM.
By that I mean that visual changes of the elements achieved by using position: relative in combination with the top-, left-, right- and bottom-property as well as by using the transform-property do not affect the layout of its parent or its siblings. These changes only affect the element itself and its children.

Related

hovering on one element while scrolling

how to hover on one element when scrolling. If you don't know how it's done, please tell me at least what it's called. There is a similar effect here. link
searched on many forums. Because I don't know what it's called, that's why I couldn't find it
If you want to know how it works I leave you my implementation of this feature (not perfect) with some comments
//add event on scroll on the window element and trigger scrollLeftAnimation function
window.addEventListener("scroll", scrollLeftAnimation);
function scrollLeftAnimation() {
//get each element who have scrollLeftAnimation class
let scrollLeftAnimationElements = document.querySelectorAll(".scrollLeftAnimation");
//for each scrollLeftAnimation element, call updateAnimation
scrollLeftAnimationElements.forEach(SectionElement => updateAnimation(SectionElement));
function updateAnimation(SectionElement) {
let ContentElement = SectionElement.querySelector(".animationContent");
//get the top value of element
//for reference see https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
let y = ContentElement.getBoundingClientRect().y;
//get a pourcent of scrolling
let pourcent = Math.abs(SectionElement.getBoundingClientRect().y / (SectionElement.clientHeight - ContentElement.clientHeight));
let ContentOverflowElement = SectionElement.querySelector(".animationContentOverflow");
//get the scroll left available distance
let ContentOverflowElementLeftScrollDistance = ContentOverflowElement.scrollWidth - ContentOverflowElement.clientWidth;
if (y == 0) {
//if element is sticky then scroll left = (max scroll left available distance) * (pourcent of scrolling)
ContentOverflowElement.scrollLeft = ContentOverflowElementLeftScrollDistance * pourcent;
} else if (y > 0) {
//if element is bellow, then scroll left = 0
ContentOverflowElement.scrollLeft = 0;
} else {
//if element is above, then scroll left = max scroll left available distance
ContentOverflowElement.scrollLeft = ContentOverflowElementLeftScrollDistance;
}
}
}
section {
height: 100vh;
}
/*Main CSS*/
section.scrollLeftAnimation {
/*The more the ratio between the height of
.scrollLeftAnimation compared to .animationContent
the more it will be necessary to scroll*/
height: 300vh;
}
section.scrollLeftAnimation .animationContent {
/* using sticky to keep the element inside the window*/
position: sticky;
top: 0;
height: 100vh;
}
.animationContent .animationContentOverflow {
height: 25vh;
overflow: hidden;
}
/*CSS for card element*/
.animationContent ul {
margin: 0;
padding: 0;
height: 100%;
white-space: nowrap;
}
.card {
border: 1px solid black;
height: 100%;
width: 35vw;
background-color: gray;
display: inline-block;
}
.card + .card {
margin-left: 50px;
}
.card:first-child {
margin-left: 25px;
}
.card:last-child {
margin-right: 25px;
}
<section style="background-color: darkorchid;">Regular section 1</section>
<section class="scrollLeftAnimation" style="background-color: deeppink;">
<div class="animationContent">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet consectetur adipiscing elit pellentesque habitant. In fermentum posuere urna nec.</p>
<div class="animationContentOverflow">
<ul>
<li class="card">card 1</li>
<li class="card">card 2</li>
<li class="card">card 3</li>
<li class="card">card 4</li>
</ul>
</div>
</div>
</section>
<section style="background-color: violet;">Regular section 4</section>
<section style="background-color: silver;">Regular section 5</section>
<section class="scrollLeftAnimation" style="background-color: peru;">
<div class="animationContent">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet consectetur adipiscing elit pellentesque habitant. In fermentum posuere urna nec. Posuere ac ut consequat semper viverra nam libero justo laoreet. Tristique risus nec feugiat in fermentum posuere urna nec tincidunt. Rhoncus dolor purus non enim praesent elementum facilisis leo. Turpis tincidunt id aliquet risus feugiat in ante metus.</p>
<div class="animationContentOverflow">
<ul>
<li class="card">card 1</li>
<li class="card">card 2</li>
<li class="card">card 3</li>
<li class="card">card 4</li>
</ul>
</div>
</div>
</section>
<section style="background-color: orange;">Regular section 7</section>

Image max height and max width while preserving aspect ratio

Is it possible to give max-height and max-width to an image while preserving aspect ratio without using js?
For example,
I want an image to be with a height of 38px and the width auto.
If the width is higher than 200px, I want the width to be 200px and the height auto.
If it's not possible without js, does anyone have an idea how to do it with js and without resizing the image after it's already loaded?
You can nest the image in a 200x38 container, then set the max-width and max-height of the image to 100%. Here is a working snippet (I have included JS to make it interactive, but it is not necessary. Try resizing the container using the sliders):
var width = document.getElementById("width");
var height = document.getElementById("height");
var widthInput = document.getElementById("widthInput");
var heightInput = document.getElementById("heightInput");
var imageContainer = document.querySelector("div");
widthInput.addEventListener("input", function() {
width.innerHTML = this.value + "px";
imageContainer.style.width = this.value + "px";
});
heightInput.addEventListener("input", function() {
height.innerHTML = this.value + "px";
imageContainer.style.height = this.value + "px";
});
div {
width: 200px;
height: 200px;
border: 1px dashed #000;
}
.image {
display: block;
max-width: 100%;
max-height: 100%;
background: #333;
}
<div>
<img class="image" src="https://via.placeholder.com/400"/>
</div>
<br/>
<label>Width: <span id="width">200px</span></label>
<br/>
<input id="widthInput" type="range" min="0" max="400"/>
<br/>
<label>Height: <span id="height">200px</span></label>
<br/>
<input id="heightInput" type="range" min="0" max="400"/>
You can notice that however you change the dimensions of the container, the image is still contained within it. By setting the container to 200px wide by 38px tall, you can force the image to stay within the limits 0px ≤ width ≤ 200px and 0px ≤ height ≤ 38px.
There is a built in CSS style called max-width and max-height and I really do not think min-width exists, incase you are wondering. You can refer to the example below to understand better. Also I am using text instead of an image, but you should get the idea.
I have nested the actual div instead another div so you could play around with the resizing.
#con {
resize: both;
overflow: auto;
}
#box {
/*Here you could say auto instead*/
height: 200px;
max-width: 200px;
}
<!DOCTYPE html />
<html>
<head></head>
<body>
<div id="con">
<div id="box">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus dapibus auctor ipsum, in convallis mi lobortis in. Phasellus molestie suscipit rutrum. Duis et convallis lectus. Etiam id urna massa. Nulla sagittis erat nec arcu rutrum elementum. Vestibulum blandit erat vestibulum, ullamcorper augue vitae, accumsan mi. Sed consectetur, quam vel efficitur interdum, ante ligula interdum justo, a dictum ligula tortor sed nunc. Cras eget magna ac urna imperdiet laoreet eget sed ante. Vivamus condimentum tortor sit amet diam elementum malesuada sed sed neque. Vestibulum et magna mollis, consequat nibh ut, facilisis orci. Phasellus fermentum sodales libero, et vehicula enim ornare ut. Donec non bibendum metus. Cras hendrerit, quam a pellentesque varius, tortor nunc maximus lectus, at gravida diam ipsum ut metus. Etiam orci felis, dapibus id cursus eu, dapibus ut augue. Proin a leo viverra, tempus ipsum nec, lacinia lacus. Maecenas id dolor nec neque lobortis interdum quis quis nisi.</div>
</div>
</body>
</html>
Using both width auto and height auto will give to following code. To center horizontal I used the align-items center of the flexbox.
.container,
.container * {
box-sizing: border-box;
}
.container {
display: flex;
width: 800px;
margin: 10px auto;
}
.img {
display: flex;
align-items: center;
width: 25%;
height: 150px;
border: 2px solid silver;
}
.img img {
display: block;
border: 0;
width: auto;
max-width: 100%;
height: auto;
max-height: 100%;
margin: auto;
}
<div class="container">
<div class="img">
<img src="http://placekitten.com/200/300" alt="">
</div>
<div class="img">
<img src="http://placekitten.com/300/200" alt="">
</div>
<div class="img">
<img src="http://placekitten.com/250/350" alt="">
</div>
<div class="img">
<img src="http://placekitten.com/350/200" alt="">
</div>
</div>
You have to use max-width and height and object-fit CSS properties for image.. see example
.img img {
max-width: 200px;
height: 38px;
object-fit: contain;
object-position: left;
}
<div class="img"><img src="https://stackoverflow.design/assets/img/logos/so/logo-stackoverflow.png"></div>
Hope it works... if any question comment pls
Here are 2 examples of the solution I think would work, the first image has less than width: 200px; and the second one has more than width: 200px;
Again, I'm not sure if it would work for you, but I think it would, and if it doesn't I would love to know why.
<style>
img {
max-width: 200px;
height: auto;
}
</style>
<img src="https://dummyimage.com/180x400/666/fff.jpg" alt="test">
<br>
<img src="https://images.pexels.com/photos/5686476/pexels-photo-5686476.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" alt="test 2">
Specifying height or width will keep the aspect ratio. Specifying both the max-height and max-width will keep the aspect ratio. Specifying height and max-height makes no sense. Specifying height and max-width cannot guarantee your aspect ratio.

How to position button depending on what content is on the page

I'm having troubles positioning a button on a page with css. I want the button to be fixed at a certain position but when there is a lot of content on the page I want the button to move down.
Firstly I want the button at the bottom of the page when there isn't much content such as the code below which does this:
#Button
{
position: fixed;
height:90px;
width:220px;
left:16%;
top:70%;
border:none;
background:none;
}
Then when there is lots of content I want the button to move down such as the code below:
#Button
{
position: absolute;
height:90px;
width:220px;
left:16%;
padding-top:10%;
padding-bottom: 13%;
border:none;
background:none;
}
Can anyone help? I've looked online but cant make sense of it.
If you define a wrapper block element (a <div> for example) around all your content and put the <button> directly under that element, it is possible to reach the desired result with CSS only.
HTML:
<div id="wrapper">
<!-- other content goes here -->
<button id="button">Sample</button>
</div>
CSS:
#wrapper {
position: relative;
min-height: 100vh;
}
#button {
position: absolute;
bottom: 0;
}
However, I have to warn you about the fact that legacy browsers do not support the vh unit and some others show buggy behavior. Take a look at here before you implement it in your project.
I don't know your structure, but I'll try to help you.
Let's use the following markup:
<div class="parent">
<p class="texto">Your text goes here!</p>
<input type="button" value="OK" />
</div>
To solve your problem, I'd simply use a min-height in the content.
.parent .texto {
min-height: 100px;
}
In this way, the button will always be in the same position if there isn't much content. And it'll follow the height if there are lots of content.
Snippet:
.parent {
width: 200px;
padding: 5px;
border: 1px solid black;
float: left;
margin: 5px;
}
.parent .texto {
min-height: 100px;
}
<div class="parent">
<p class="texto">
Small text!
</p>
<input type="button" value="OK" />
</div>
<div class="parent">
<p class="texto">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi mi urna, rhoncus vitae hendrerit ut, hendrerit a turpis. Phasellus sed rhoncus augue, eget vehicula neque. Vivamus lobortis, velit vitae maximus porttitor, erat nulla scelerisque est, nec
sagittis diam diam id nisl. Maecenas dictum lacinia dignissim. Duis eget ligula fermentum, vulputate dui sed, vestibulum ipsum. Duis non consectetur dolor. Nunc urna eros, tincidunt id nisl id, dapibus imperdiet orci. Mauris posuere convallis ullamcorper.
</p>
<input type="button" value="OK" />
</div>
Hope it helps!
use position:relative for the element which you have defined before this button.

Prevent element width from shrinking

I have a tooltip with some text, and in order to control the tooltip's position relative to the cursor with CSS, I placed it inside a zero-sized div. Javascript moves the outer div, and the tooltip can be aligned via any of the top/right/left/bottom attributes, depending on which side it should be placed on.
However, this creates a new problem - the tooltip contents now tries to use as little width as possible. I can't disable wordwrap because it needs to fit on mobile screens. Without the outer container, it works perfectly, stretching up to the window edge. Is there a way to ignore the outer container while calculating the line breaks?
From what I can tell, the tooltip no longer 'sees' the body element so it can't know how much it can stretch. However, controlling the tooltip position directly via Javascript is more complicated if I need to align the bottom or right sides - I have to either consider tooltip size (which can change depending on its position), or set bottom/right properties and consider window size.
Here's an example: http://jsfiddle.net/03gdomLt/1/
The first tooltip works correctly, while the second one tries to shrink to zero width.
.tip-outer {
position: absolute;
top: 200px;
left: 100px;
}
.tooltip {
position: absolute;
left: 10px;
top: 10px;
border: 1px solid black;
}
<div class="tip-outer">
<div class="tooltip">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis pharetra feugiat augue, non pretium massa ultricies vel. In hendrerit tellus.
</div>
</div>
<div class="tooltip">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis pharetra feugiat augue, non pretium massa ultricies vel. In hendrerit tellus.
</div>
Looks only parent width shrinks to 0, the tooltip text are still there but are not able to fit on screen. That is because the parent div (tip-outer) is having left:100px which is forcing tooltip to shift towards right, hence not visible.
Try below css to fix it for small screen. Updated fiddle
#media only screen
and (max-width : 400px) {
.tip-outer .tooltip{
left: -90px;
}
}
I don't know if this can or can not work for your case, but positioning the element relative does enable the text to wrap correctly even if it is positioned left top bottom right.
http://jsfiddle.net/03gdomLt/3/
.tip-outer {
position: absolute;
top: 200px;
left: 100px;
}
.tooltip {
position: relative;
left: 10px;
top: 10px;
border: 1px solid black;
//white-space: pre-wrap;
}
<div class="tip-outer">
<div class="tooltip">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Suspendisse accumsan lectus eget egestas fringilla.</div>
</div>
<div class="tooltip">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Suspendisse accumsan lectus eget egestas fringilla.</div>

Add CSS3 transition expand/collapse

How do I add an expand/collapse transition?
function showHide(shID) {
if (document.getElementById(shID)) {
if (document.getElementById(shID + '-show').style.display != 'none') {
document.getElementById(shID + '-show').style.display = 'none';
document.getElementById(shID).style.display = 'block';
} else {
document.getElementById(shID + '-show').style.display = 'inline';
document.getElementById(shID).style.display = 'none';
}
}
}
.more {
display: none;
padding-top: 10px;
}
a.showLink,
a.hideLink {
text-decoration: none;
-webkit-transition: 0.5s ease-out;
background: transparent url('down.gif') no-repeat left;
}
a.hideLink {
background: transparent url('up.gif') no-repeat left;
}
Here is some text.
<div class="readmore">
Read more
<div id="example" class="more">
<div class="text">Here is some more text: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae urna nulla. Vivamus a purus mi. In hac habitasse platea dictumst. In ac tempor quam. Vestibulum eleifend vehicula ligula, et cursus nisl gravida sit amet. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</div>
<p>Hide</p>
</div>
</div>
http://jsfiddle.net/Bq6eK/1
This is my solution that adjusts the height automatically:
function growDiv() {
var growDiv = document.getElementById('grow');
if (growDiv.clientHeight) {
growDiv.style.height = 0;
} else {
var wrapper = document.querySelector('.measuringWrapper');
growDiv.style.height = wrapper.clientHeight + "px";
}
document.getElementById("more-button").value = document.getElementById("more-button").value == 'Read more' ? 'Read less' : 'Read more';
}
#more-button {
border-style: none;
background: none;
font: 16px Serif;
color: blue;
margin: 0 0 10px 0;
}
#grow input:checked {
color: red;
}
#more-button:hover {
color: black;
}
#grow {
-moz-transition: height .5s;
-ms-transition: height .5s;
-o-transition: height .5s;
-webkit-transition: height .5s;
transition: height .5s;
height: 0;
overflow: hidden;
}
<input type="button" onclick="growDiv()" value="Read more" id="more-button">
<div id='grow'>
<div class='measuringWrapper'>
<div class="text">Here is some more text: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae urna nulla. Vivamus a purus mi. In hac habitasse platea dictumst. In ac tempor quam. Vestibulum eleifend vehicula ligula, et cursus nisl gravida sit
amet. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</div>
</div>
</div>
I used the workaround that r3bel posted: Can you use CSS3 to transition from height:0 to the variable height of content?
this should work, had to try a while too.. :D
function showHide(shID) {
if (document.getElementById(shID)) {
if (document.getElementById(shID + '-show').style.display != 'none') {
document.getElementById(shID + '-show').style.display = 'none';
document.getElementById(shID + '-hide').style.display = 'inline';
document.getElementById(shID).style.height = '100px';
} else {
document.getElementById(shID + '-show').style.display = 'inline';
document.getElementById(shID + '-hide').style.display = 'none';
document.getElementById(shID).style.height = '0px';
}
}
}
#example {
background: red;
height: 0px;
overflow: hidden;
transition: height 2s;
-moz-transition: height 2s;
/* Firefox 4 */
-webkit-transition: height 2s;
/* Safari and Chrome */
-o-transition: height 2s;
/* Opera */
}
a.showLink,
a.hideLink {
text-decoration: none;
background: transparent url('down.gif') no-repeat left;
}
a.hideLink {
background: transparent url('up.gif') no-repeat left;
}
Here is some text.
<div class="readmore">
Read more
<div id="example" class="more">
<div class="text">
Here is some more text: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae urna nulla. Vivamus a purus mi. In hac habitasse platea dictumst. In ac tempor quam. Vestibulum eleifend vehicula ligula, et cursus nisl gravida sit amet.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
</div>
<p>
Hide
</p>
</div>
</div>
OMG, I tried to find a simple solution to this for hours. I knew the code was simple but no one provided me what I wanted. So finally got to work on some example code and made something simple that anyone can use no JQuery required. Simple javascript and css and html. In order for the animation to work you have to set the height and width or the animation wont work. Found that out the hard way.
<script>
function dostuff() {
if (document.getElementById('MyBox').style.height == "0px") {
document.getElementById('MyBox').setAttribute("style", "background-color: #45CEE0; height: 200px; width: 200px; transition: all 2s ease;");
}
else {
document.getElementById('MyBox').setAttribute("style", "background-color: #45CEE0; height: 0px; width: 0px; transition: all 2s ease;");
}
}
</script>
<div id="MyBox" style="height: 0px; width: 0px;">
</div>
<input type="button" id="buttontest" onclick="dostuff()" value="Click Me">
http://jsfiddle.net/Bq6eK/215/
I did not modify your code for this solution, I wrote my own instead. My solution isn't quite what you asked for, but maybe you could build on it with existing knowledge. I commented the code as well so you know what exactly I'm doing with the changes.
As a solution to "avoid setting the height in JavaScript", I just made 'maxHeight' a parameter in the JS function called toggleHeight. Now it can be set in the HTML for each div of class expandable.
I'll say this up front, I'm not super experienced with front-end languages, and there's an issue where I need to click the 'Show/hide' button twice initially before the animation starts. I suspect it's an issue with focus.
The other issue with my solution is that you can actually figure out what the hidden text is without pressing the show/hide button just by clicking in the div and dragging down, you can highlight the text that's not visible and paste it to a visible space.
My suggestion for a next step on top of what I've done is to make it so that the show/hide button changes dynamically. I think you can figure out how to do that with what you already seem to know about showing and hiding text with JS.
Here's a solution that doesn't use JS at all. It uses checkboxes instead.
You can hide the checkbox by adding this to your CSS:
.container input{
display: none;
}
And then add some styling to make it look like a button.
Here's the source code that I modded.

Categories