Arranging divs with the same id in desktop and mobile - javascript

I have a webpage that I am trying to optimize for desktop and mobile but have little experience in how to place divs in separate places on the screen that reference the same id. Any suggestions about best practices would be extremely helpful.
<input id='feature-filter' type='text' placeholder='Filter by name' />
For example, above I have an input named feature-filter that on desktop should be positioned in the menu bar called header on desktop. Note that there is no accompanying CSS to feature-filter.
#header {
display: flex;
position: absolute;
align-items: center;
top: 0px;
width: 100%;
line-height: 50px;
height: 50px;
background: rgba(12, 12, 12, 0.8);
color: #eee;
font: 16px/20px 'Open Sans', sans-serif;
font-weight: 500;
text-align: center;
vertical-align: middle;
}
<div id='header'>
<button title = "ButtonA" id = "A"></button>
<button title = "ButtonB" id = "B"></button>
<button title = "ButtonC" id = "C"></button>
<input id='feature-filter' type='text' placeholder='Filter by name' />
</div>
In the mobile version, however, I would like to place this input in a legend that is at the bottom of the page. In my javascript, there is an event listener that pulls data from feature-filter.
#legend { z-index: 101010; padding: 5px; position: fixed; text-align: center;
color: #fff; bottom: 0px; width: 300px; background: #181818; opacity: 0.92;
font-family: 'Open Sans', sans-serif; left: 0; right: 0; font-weight: 300}
<div id='legend'>
<input id='feature-filter' type='text' placeholder='Filter by name' />
</div>
Is it possible to reference the same DOM id in javascript AND place feature-filter in two separate places in the html - one for the mobile and one for the desktop version ?
What is the best approach to this problem? Using CSS classes would still require having two separate inputs with the same id in the html
Any basic explanation or suggestions would be appreciated.

It would be best to use the same HTML regardless of screen type. I would use a div tag, and not misuse the legend tag. This simplifies the JavaScript and improves accessibility. However, you may style it differently depending on screen size. You may even disable / enable certain elements to adapt to mobile.
I would not try to use two different HTML elements with the same ID. Duplicated elements should use a class name not an ID (which is intended to be unique). Either use the same HTML and style differently, or use two entirely different HTML elements (with different IDs) and use the CSS to disable one and test in JavaScript which one should be used.
To approach styling differently for different devices, the recommended practice is to use a style sheet that applies different rules based on screen size. See this StackOverflow question for how to target different sized screens with your CSS style sheet.
You may also reference existing styling frameworks such as Bootstrap's responsive grid as an example or a solution to see how to style differently for different sized screens.

I'd recommend using CSS to properly position each element depending on the amount of pixels available. If mobile than do this, if desktop than do this. Its a matter of visuals right? Why not use CSS and tell it how you want your page to look. CSS Info
Or download Bootstrap and customize it to your CSS liking.

Related

How to push information (links) into a '...' show more popover based on screen size in React

I have a card that includes 5 hyperlinks in a row, I want all 5 links to show on any screen width above 552px and then below 552px I want only the first two links showing and then a '...' that when clicked displays a popover with the rest of the links. I accomplished this but it has a LOT of repeating code so I'm looking for a more efficient way. Here's an example of what I tried:
const MiniModal = styled.div`
display: flex;
justify-content: center;
position: absolute;
z-index: 1;
text-align: center;
width: 160px;
height: auto;
padding: 12px;
position: relative;
top: 10%;
left: 63%;
margin: -25px;
background-color: #fff;
border: none;
border-radius: 12px;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
border: 1px solid #eceff1;
outline: none;
overflow: hidden;
`
if (window.screen.width > 552) {
return (
<>
Link 1
Link 2
Link 3
Link 4
Link 5
</>
)} else {
return (
<>
Link 1
Link 2
<MiniModal>
Link 3
Link 4
Link 5
</MiniModal>
</>
)}
What you're trying to do is a bit out of ordinary because you're trying to keep some children visible and some hidden. More often than not, you'll have two separate components: one for desktop screens and one for mobile screens. The desktop version will have all children visible (using media selectors to alter their sizes/positions as the screen shrinks), otherwise the mobile version consolidates all the children and conditionally displays them (like a hamburger menu).
That said, I see two options that achieve a desired result...
Option 1
One approach is that you can simply use CSS media selectors which can add/remove class styles when the window changes. These classes will then hide/display the components without having to update React state. This is better for older devices/mobile devices since it's a browser implementation.
The disadvantage of this approach is that both components still reside in the DOM (they're rendered, but just not visible), and so your HTML will be larger in terms of bytes.
Option 2
Another approach involves setting a listener on the window, setting its size to React state and when the window hits a certain size, React can swap out one component for another. Better for more modern devices with larger screens.
The disadvantage of this approach is that you may be updating React state quite/too often to reflect the window change which can be computational heavy. As a result, you may introduce micro-stutters. You could throttle the state updates, but then it's not as responsive.
I'd argue that there really isn't a best solution since taking either approach results in some sort of penalty. On that note, I'd recommend separating your concerns: all children are visible on desktop and all children are hidden on mobile.
Demo:

How to Position "MediaElement" media player

I'm new in web development, I am using MediaElement as my media player in my website. I'm trying to position the audio player but there are too many elements that need to be positioned separately. Is there an easy, singular approach to position the whole thing at once?
There is always a parent element that surrounds just about any component in a web page, especially media players. That's the only thing that needs to be positioned; All child elements will follow.
Below I've created a running example of a fake media player. Notice only the top level .player class has positioning styles. Those are the only ones you need to set. All the child element styles would come from whatever default stylesheet comes with the media player itself.
/* only position the parent container */
.player {
position: absolute;
top: 100px;
left: 100px;
}
/* IGNORE THESE, assume they're from the media player's own stylesheets */
.player .player-video {
width: 250px;
height: 200px;
background: #000;
}
.player .player-controls {
padding: 5px;
background: #CCC;
}
.player .player-play-button,
.player .player-next-button {
display: inline-block;
}
<div class="player">
<video class="player-video"></video>
<div class="player-controls">
<button class="player-play-button">PLAY</button>
<button class="player-next-button">NEXT</button>
</div>
</div>
There are other ways to position elements such as margins, padding and centering, so be sure to explore all options to make sure it'll layout correctly.
One singular (but cheap) approach is to wrap your elements in a <center> tag, but I wouldn't seriously recommend this. If you're new to web development, you should at least be aware of it.
Other options primarily involve CSS. I would check out the flexbox model. It's fantastic for layouts.
.wrapper {
display: flex;
justify-content: center;
width: 100%;
}
Wrapping your items in a <div> with a class of wrapper will horizontally center the items within itself. If you're developing for platforms that support flexbox, then knowing flexbox layouts is helpful to avoid learning arcane, classic CSS hacks of horizontally centering elements.

javascript to detect a browser and use a certain style sheet

There is a a single element of a web page that I absolutely MUST have sit in a precise location on the page, and there seems to be a 14px height differential between Chrome and FF which won't allow me to situate the graphic uniformly between the two. I used a conditional statement for IE9 and IE8, but now the problem exists with Chrome and FF.
I don't have access to the main head section or main global CSS for this site, unfortunately, and there is not a global reset of 0 on the margins. Even if it were possible for me to do so, there have been so many hacks and fixes, that it would be counter-productive to do a global reset.
So after messing around with musical chairs of this object, I think my final solution (although not very elegant to do for just ONE graphic) is to write a style sheet for the margin-top of this image (actually a div with an image background), and have javascript detect the browser and feed the style-sheet accordingly (i.e. - if it is FF then render this CSS, or if it is Chrome then render this CSS).
Unfortunately I cannot show the page, but my CSS for the element is:
#telescope {
background: url("my-image.png") no-repeat scroll 0 0 transparent;
height: 102px;
position: absolute;
right: -48px;
margin-top: 748px;
width: 98px;
z-index: 1;
}
Try putting this at the top of your css:
* {
margin: 0;
padding: 0;
font-family: "Open Sans", 'Consolas', sans-serif;
}
html, body {height: 100%;}

Styling file input with foundation

I'm using foundation and I've not seen anything in the documentation regarding the file input, only general input elements. But styling the file input is not so easy. And more if you want to keep it coherent with the design of the whole form in all the browsers.
I've seen some solutions like Styling an input type="file" button or https://github.com/filamentgroup/jQuery-Custom-File-Input, but I wanted to know if there's something specific in foundation, as the usual wrapping div styles don't work at all (div.large-3.columns etc.).
How do you do it?
Do you need only button? Or field with file's address too? If only button the simpliest solution is demo
<a class="wrapper">
button name
<input type="file"/>
</a>
.wrapper {
width: 100px;
height: 30px;
overflow: hidden;
position: relative;
}
input {
position: absolute;
right: 0;
top: 0;
bottom: 0;
font-size: 50px; /* some huge for cursor pointer hack */
}
also you can use pseudo-classes for some browsers see article
I just applied the .button class to the input tag.
It looks good enough for me.
For any styling more sophisticated than Foundation's default (e.g. changing the look of the browse button) you will need to edit their implementation of the label element technique.
It's fully semantic, accessible and requires no JavaScipt. Basically, you hide the input, ensure the id is set on both the label and file field, then style the label accordingly. Here's a great article that explains the technique along with a CodePen (https://codepen.io/bmarshall511/pen/bjyEgq) that shows how it's done: https://benmarshall.me/styling-file-inputs/
[type="file"] + label {
background: #f15d22;
border-radius: 5px;
color: #fff;
font-family: 'Poppins', sans-serif;
font-weight: 600;
}

How to dynamically change line-height or font size of a link(<a>)?

Here is what my project looks like:
Each red box is a link. Right now I have them as tags with a line-height matching the height of the box, so that the text is vertically centered. The problem i am running into is when the text that needs to go on a tile is too long. How would i be able to make the text wrap if it is too long? Is there a way to find if the string will fit within a certain width?
Would changing the way i have the tiles set up make this easier? I thought about just making the Divs clickable, but then im still not sure how to make the text vertically aligned in the center. I just need a pointing in the right direction. Thanks
EDIT: some of the code
the html of a tile:
<div class="primary col_1 row_1">
<a href="javascript:expand(1, 1)">
<?php echo $tile_data[0][0]; ?>
</a>
</div>
The CSS applicable:
#selection_menu a {
color: #FFFFFF;
width: 162px;
text-decoration: none;
font-weight: bold;
display: block;
border: none;
float: left;
}
#selection_menu .primary_options .primary a { font-size: 23px; height: 108px; }
Consider the following (add proper colors and typography):
#selection_menu div a {
display: table-cell;
height: 108px;
text-align: center;
vertical-align: middle;
width: 162px
}
This will vertically center every a inside a div (inside #selection_menu), no matter how many lines it spans. Works in all modern Web browsers. You can set line-height to a proper value like 1.5 (it will define the way the link looks when it spans across multiple lines).

Categories

Resources