notas - etiquetas html
Alineado de texto sensible basado en la posiciĆ³n (4)
De hecho, existe una solución solo para CSS que funciona exactamente como lo presentó en las imágenes adjuntas de su pregunta. Sin embargo, puede que no sea una respuesta realmente completa, ya que depende de un factor crucial: que todos los elementos del menú de nivel superior tengan el mismo ancho. Ahora este es el caso que se muestra en sus imágenes adjuntas, pero puede que no sea cierto en su implementación real.
Usando el selector nth-child
CSS3 con la variable n
puede apuntar a cada elemento del menú de nivel superior 3º, 4º, etc. Los elementos dirigidos se pueden diseñar fácilmente para que sus menús desplegables se alineen a la derecha. Por lo tanto, para una solución codificada en una sola pantalla, contaría el número de elementos del menú de nivel superior en una fila y lo configuraría como su multiplicador n
. Por ejemplo, si su menú se ajustara después de 6 elementos, para diseñar el último elemento de cada fila, establecería algo como:
.top-level-item:nth-child(6n) > .dropdown-container > .sub-item {
float: right;
clear: right;
}
o sin embargo, su implementación real necesita diseñar un menú alineado a la derecha.
Por supuesto, esto depende de que todos los elementos del menú tengan el mismo ancho. Si su menú tiene más de 2 filas y los elementos de su menú tienen anchos variables, entonces puede tener un número variable de elementos en cada fila, en cuyo caso el selector nth-child
no necesariamente se dirigirá al elemento secundario final de cada fila.
Ahora para que esto funcione para cualquier tamaño de pantalla, si todos los elementos de nivel superior tienen el mismo ancho fijo, debemos averiguar cuántos elementos habrá por fila independientemente del ancho de la ventana. Lamentablemente, calc()
es demasiado limitado para esta aplicación. Sin embargo, si los elementos superiores tienen un ancho fijo y sabemos cuál es ese ancho, podemos usar una serie de declaraciones @media
para cada caso.
Por ejemplo, digamos que con los márgenes y el ancho juntos, cada elemento de nivel superior tiene un ancho de 230 px. Esto significa que si el ancho de la ventana es menor que 230 * 3 = 690px, habrá 2 elementos en cada fila. Si el ancho de la ventana es menor que 230 * 4 = 920px y mayor que 690px, habrá 3 elementos en cada fila. Y así sucesivamente, al tamaño de ventana más grande que creas que necesitarás. Usando el ejemplo anterior nth-child
, la serie de consultas de medios para apuntar a cada tamaño de fila se vería como:
@media (max-width: 690px) {
/* less than 3 items per row */
.top-level-item:nth-child(2n) > .dropdown-container > .sub-item {
float: right;
clear: right;
}
}
@media (max-width: 920px) and (min-width: 691px) {
/* less than 4 items per row */
.top-level-item:nth-child(3n) > .dropdown-container > .sub-item {
float: right;
clear: right;
}
}
@media (max-width: 1150px) and (min-width: 921px) {
/* less than 5 items per row */
.top-level-item:nth-child(4n) > .dropdown-container > .sub-item {
float: right;
clear: right;
}
}
...
/* and so on */
Una pluma que muestra una implementación de esto está en https://codepen.io/jla-/pen/GYJQMq . Tenga en cuenta que el JavaScript solo está allí para alternar los menús desplegables cuando se hace clic.
Para los elementos de menú de nivel superior que tienen ancho variable, o si tienen el mismo ancho pero no sabes qué valor tiene, no creo que el CSS actual sea lo suficientemente poderoso como para hacer lo que quieres. Lo ideal sería hacer algo como .top-level-item:nth-child(calc((100vw/--itemwidth)-(100vw%--itemwidth))
para obtener el número de elementos en una fila, pero creo que CSS es muy lejos de ese tipo de poder.
Creo que la respuesta a esta pregunta es no, pero antes de realizar cambios más drásticos, quiero asegurarme de que no me haya perdido algo.
¿Existe un medio, solo a través de CSS, para alterar la justificación de un elemento y sus hijos en función de si está orientado más hacia la izquierda o la derecha de la pantalla?
No hay una propiedad directa para esto, pero estoy viendo si me he perdido algún método similar a un hack que involucre pseudo selectores o elementos.
Demostración de la situación actual:
Tengo una barra de navegación <ul>
que proporciona una mezcla de enlaces <a>
y algunos contenedores <ul>
anidados para menús desplegables al pasar el cursor. Bastante estándar y funciona bien en pantallas más anchas:
Si hay menos espacio disponible en la pantalla, la navegación se ajusta a la siguiente línea según lo previsto. Este es un resultado deseable. Sin embargo, a veces los menús desplegables se pueden truncar fuera de la pantalla, lo que no es muy deseable:
En lugar de proporcionar un estilo muy diferente para los dispositivos móviles (mi plan alternativo es presentar los menús desplegables como opciones de diálogo a través de una postion: fixed
en pantallas más pequeñas, en lugar de position: absolute
como son ahora), podría arreglar mi La situación a través de mis elementos es consciente de su aventura fuera de la pantalla y la necesidad text-align: right
ambos text-align: right
y, posiblemente, ajustar su posicionamiento absoluto para anclar a la derecha del elemento <li>
lugar de a la izquierda, como están ahora:
Puedo administrar esto a través de javascript pero ya tengo suficientes eventos de escucha y deseo proporcionar una respuesta más elegante que evite javascript. Si no hay un método solo para CSS, podría usar la alternativa de posición fija como un plan b en su lugar.
Aclaraciones:
Aunque originalmente esperaba usar las consultas de los medios para resolver este problema en los dispositivos móviles, me di cuenta de que, aunque para mí solo es evidente en tamaños de pantalla más pequeños, esto no es algo que pueda dar por sentado.
Por ejemplo, la cantidad de elementos de navegación puede crecer en el futuro y podría presentar esta situación en cualquier tamaño de pantalla. Solo necesita un menú desplegable para estar en la pantalla derecha.
Tampoco puedo garantizar que un dispositivo que aún no he probado no esté replicando el problema en un tamaño que no esperaba.
Mi punto es que no veo una forma en que pueda confiar en las consultas de los medios de tamaño de pantalla. Creo que mi solución, en caso de que exista, debe responder a la posición del elemento en la pantalla, razón por la cual creo que podría no tener suerte con una solución que no sea javascript.
En segundo lugar: supongamos que el contenido es dinámico y, como en cualquier página con capacidad, los elementos que deberían cambiar dinámicamente las propiedades para adaptarse a esto, lo hacen (como el orden de los elementos de navegación, el conteo, los anchos, etc.). Debería referir a cualquier persona que busque advertencias más finas en esta área a la pregunta original: ¿Existe algún medio, solo a través de CSS, para alterar la justificación de un elemento y sus hijos en función de si está orientado más hacia la izquierda o la derecha de la pantalla?
Código de muestra:
Según lo solicitado, aquí está el código de muestra. No creo que sea una buena idea incluirla en este escenario (aunque entiendo que es importante en la mayoría de las preguntas), ya que esto no tiene nada que ver con mi código específico y está mucho más relacionado con cuestionar la capacidad de css para modificar dinámicamente una atributo (s) basado en la posición de la pantalla o conocimiento de los bordes de la pantalla - en cualquier escenario - por lo tanto, mi preferencia para ilustrar la pregunta.
El código es una versión simplificada de mi cuenta, pero la pregunta podría haberse formulado con casi cualquier variación de un menú de navegación estándar y familiar que ofrece menús desplegables a través de :hover
en CSS.
Teniendo eso en cuenta, si está intentando resolver la pregunta trabajando a través de mi código, es posible que haya descrito mal mi situación. Creo que estoy bastante versado en las extensiones a las que se puede empujar CSS actualmente y creo que la respuesta es ''no es posible sin javascript'', pero me estoy asegurando de que no me haya perdido una solución inteligente / pirateo para modificar atributos de elementos dinámicamente a través de CSS basado en la posición de la pantalla (perdón por la repetición de la pregunta, solo quiero asegurarme de que se entienda, siguiendo algunos comentarios). Gracias.
<ul class="nav nav__container">
<li><a class=''nav nav__item'' href="#">Standard Link</a></li>
<li><a class=''nav nav__item'' href="#">Standard Link</a></li>
<li><a class=''nav nav__item'' href="#">Standard Link</a></li>
<li><a class=''nav nav__item'' href="#">Standard Link</a></li>
<li class=''nav nav__item nav__item--dropdown''><li><a href="#">Dropdown Label</a></li>
<ul class=''nav nav__dropdown''>
<li><a class=''nav nav__item nav__item--dditem'' href="#">Dropdown Link</a></li>
<li><a class=''nav nav__item nav__item--dditem'' href="#">Dropdown Link</a></li>
<li><a class=''nav nav__item nav__item--dditem'' href="#">Dropdown Link</a></li>
</ul>
</li>
</ul>
Escriba una consulta de medios para su requerimiento cuando desee ajustar la justificación del texto. Puede cambiar la propiedad justificada de la prueba dentro de la consulta de medios. use diferentes consultas de medios para diferentes tamaños de pantalla de acuerdo a sus requerimientos, vea el ejemplo
@media only screen and (max-width: 600px) {
selector {
property : value;
}
}
Parece la respuesta a la pregunta central:
¿Existe un medio, solo a través de CSS, para alterar la justificación de un elemento y sus hijos en función de si está orientado más hacia la izquierda o la derecha de la pantalla?
no es.
Como una respuesta de seguimiento más exhaustiva, pensé en mencionar que no voy a seguir con mi plan B original de estilos de menús desplegables para ser arreglados en tamaños de pantalla más pequeños. Lo insinué en mi pregunta, pero es más evidente que no puedo confiar en el tamaño de la pantalla para determinar si se truncará un menú desplegable en el futuro. Por lo tanto, dado que las consultas de medios ahora están descartadas, necesito otra solución si quiero asegurarme de no proporcionar una solución descuidada para ningún dispositivo.
Lo que me deja con javascript. Trataba de evitar esto pero, en esta etapa, sería obstinado al hacerlo dado el resultado.
Método
En caso de que sea de utilidad para cualquier otra persona, utilicé jquery para proporcionar un oyente para desplazarse por los menús desplegables. La lógica es que se garantiza que todos los elementos de una determinada clase tienen un menú desplegable, compuesto por un <ul>
de otra clase. Así que puedo apuntar a ambos fácilmente.
Podría verificar si el menú desplegable está a la derecha o izquierda de la pantalla. Esto funcionaría bien. Siendo exigente, prefiero que el menú permanezca justificado a la izquierda a menos que esté a unos 200 píxeles desde la derecha de la pantalla, un umbral seguro para mi contenido dinámico. Podría ir y medir cada ancho desplegable y usarlo como un umbral si alguna vez me encuentro con problemas.
Poniendo todo esto junto. Si me coloco sobre un menú desplegable y se encuentra a menos de 200 píxeles desde la derecha de la pantalla, ambos justificarán su menú a la derecha y colocarán el menú desplegable en el lado derecho de su etiqueta de menú principal. / disparador (como mostré en mis ilustraciones originales). Hay versiones más flexibles y más cortas de hacer esto y tampoco es mucho más trabajo hacer sin jQuery para que nadie evite la biblioteca:
Código JS
$(nav).on(''mouseover'', ''.dropdown'', function() {
var dropdownlist = $(this).children(''ul'');
var screenWidth = $(window).width();
var parentOffsetLeft = $(this).offset().left;
var spaceRight = screenWidth - parentOffsetLeft;
if (spaceRight < 200) {
$(dropdownlist).css(''text-align'', ''right'');
$(dropdownlist).css(''right'', ''0'');
$(dropdownlist).css(''left'', ''initial'');
} else {
$(dropdownlist).css(''text-align'', ''left'');
$(dropdownlist).css(''left'', ''0'');
$(dropdownlist).css(''right'', ''initial'');
}
});
Usando este javascript, puedo recrear la solución ilustrada en la pregunta.
Puede ser que la consulta de medios con flex pueda ayudarlo si lo usa correctamente. Intenté replicar su problema en jsfiddle.
<div id="menu-container">
<div class="menu"></div>
<div class="menu"></div>
<div class="menu">
<div id="sub-menu-container">
<div class="sub-menu" id="sub-menu1"></div>
<div class="sub-menu" id="sub-menu2"></div>
<div class="sub-menu" id="sub-menu3"></div>
<div class="sub-menu" id="sub-menu4"></div>
</div>
</div>
<div class="menu"></div>
</div>
CSS
.menu{
border-radius:15px;
background-color: #00ab9e;
width:120px;
height:50px;
border: 1px solid #01eae9;
display:inline-block;
margin:5px;
position:relative;
vertical-align:top;
}
#sub-menu-container{
margin-top:50px;
display: flex;
flex-flow: column wrap;
align-items: flex-start;
}
.sub-menu{
border-radius:15px;
background-color: #ffb12a;
width:120px;
height:50px;
border: 1px solid #01eae9;
margin-top:5px;
}
#sub-menu2{
width:150px;
}
#sub-menu3{
width:200px;
}
@media only screen and (max-width: 495px) {
#sub-menu-container {
align-items: flex-end;
}
}
@media only screen and (max-width: 420px) {
#sub-menu-container {
align-items: flex-start;
}
}
https://jsfiddle.net/nimittshah/7bsf1r3v/
Gracias